新宿(近々代々木に移転)で働く18歳エンジニアのブログ

思ったこととか、技術的なこと書きます。

Difference between mixins, extend and %placeholder

Mixins

A mixin lets you make groups of CSS declarations that you want to reuse throughout your site.
@mixin message($color) {
  border: 1px solid #ccc;
  padding: 10px;
  color: $color;
}

.success { 
  @include message(#333); 
  border-color: green;
}

.error {
  @include message(#333);
  border-color: red;
}
.success {
  border: 1px solid #ccc;
  padding: 10px;
  color: #333;
  border-color: green;
}

.error {
  border: 1px solid #ccc;
  padding: 10px;
  color: #333;  
  border-color: red;
}

Extend/Inheritance

Using @extend lets you share a set of CSS properties from one selector to another. It helps keep your Sass very DRY.
.message {
  border: 1px solid #ccc;
  padding: 10px;
  color: #333;
}

.success {
  @extend .message;
  border-color: green;
}

.error {
  @extend .message;
  border-color: red;
}
.message, .success, .error, .warning {
  border: 1px solid #cccccc;
  padding: 10px;
  color: #333;
}

.success {
  border-color: green;
}

.error {
  border-color: red;
}

%placeholder

Placeholder selectors have the additional property that they will not show up in the generated CSS, only the selectors that extend them will be included in the output.
%message {
  border: 1px solid #ccc;
  padding: 10px;
  color: #333;
}

.success {
  @extend %message;
  border-color: green;
}

.error {
  @extend %message;
  border-color: red;
}
.success, .error{
  border: 1px solid #cccccc;
  padding: 10px;
  color: #333;
}

.success {
  border-color: green;
}

.error {
  border-color: red;
}

Difference between mixins, extend and %placeholder

  • difference between mixins and extend
# mixin
+.success {
+  border: 1px solid #ccc;
+  padding: 10px;
+  color: #333;
+  border-color: green;
+}

+.error {
+  border: 1px solid #ccc;
+  padding: 10px;
+  color: #333;  
+  border-color: red;
+}

# extend
-.message, .success, .error{
-  border: 1px solid #cccccc;
-  padding: 10px;
-  color: #333;
-}

-.success {
-  border-color: green;
-}
  • difference between A and B
# extend .message
+ .message, .success, .error, .warning { 
# extend %message
- .success, .error{ 

Limitations

Since @extend works by adding a selector to another selector without duplicating any of the properties it's actually impossible to join selectors in different @media blocks.
%icon {
  transition: background-color ease .2s;
  margin: 0 .5em;
}

@media screen {
  .error-icon {
    @extend %icon;
  }
  
  .info-icon {
    @extend %icon;
  }
}
You may not @extend an outer selector from within @media.
You may only @extend selectors within the same directive.
From "@extend %icon" on line 8 of icons.scss
@media screen {
  %icon {
    transition: background-color ease .2s;
    margin: 0 .5em;
  }
}

.error-icon {
  @extend %icon;
}

.info-icon {
  @extend %icon;
}
@media screen {
  .error-icon, .info-icon {
    transition: background-color ease .2s;
    margin: 0 .5em;
  }
}
@extend doesn't work between rules in different @media blocks.

Conclusion

  • コンパイル後のcssでより簡潔(冗長ではない)になるのが、mixinより、extend
  • CSSには書き出されない別のセレクタから継承(@extend)されるためだけの専用セレクタが%placeholdar

Reference from

http://sass-lang.com/guide https://sass-guidelin.es/#extend https://sass-guidelin.es/#mixins https://www.sitepoint.com/sass-mixin-placeholder/ http://thesassway.com/intermediate/understanding-placeholder-selectors