Using @include vs @extend in Sass?

temporary_user_name picture temporary_user_name · Aug 2, 2013 · Viewed 84.3k times · Source

In Sass, I can't quite discern the difference between using @include with a mixin and using @extend with a placeholder class. Don't they amount to the same thing?

Answer

Extends do not allow customization, but they produce very efficient CSS.

%button
  background-color: lightgrey
  &:hover, &:active
    background-color: white

a
  @extend %button

button
  @extend %button

Result:

a, button {
  background-color: lightgrey;
}
a:hover, button:hover, a:active, button:active {
  background-color: white;
}

With mixins, you get duplicated CSS, but you can use arguments to modify the result for each usage.

=button($main-color: lightgrey, $active-color: white)
  background-color: $main-color
  border: 1px solid black
  border-radius: 0.2em

  &:hover, &:active
    background-color: $active-color

a
  +button

button
  +button(pink, red)

Results in:

a {
  background-color: lightgrey;
  border: 1px solid black;
  border-radius: 0.2em;
}
a:hover, a:active {
  background-color: white;
}

button {
  background-color: pink;
  border: 1px solid black;
  border-radius: 0.2em;
}
button:hover, button:active {
  background-color: red;
}

Please follow this consecutive set of code examples to see how you can make your code cleaner and more maintainable by using extends and mixins effectively: http://thecodingdesigner.com/posts/balancing

Note that SASS unfortunately does not allow using extends inside media queries (and corresponding example from the above link is wrong). In the situation where you need to extend based on media queries, use a mixin:

=active
  display: block
  background-color: pink

%active
  +active

#main-menu
  @extend %active // Active by default

#secondary-menu
  @media (min-width: 20em)
    +active // Active only on wide screens

Result:

#main-menu {
  display: block;
  background-color: pink;
}

@media (min-width: 20em) {
  #secondary-menu {
    display: block;
    background-color: pink;
  }
}

Duplication is inevitable in this case, but you shouldn't care too much about it because web server's gzip compression will take care of it.

PS Note that you can declare placeholder classes within media queries.

Update 2014-12-28: Extends produce more compact CSS than mixins do, but this benefit is diminished when CSS is gzipped. If your server serves gzipped CSS (it really should!), then extends give you almost no benefit. So you can always use mixins! More on this here: http://www.sitepoint.com/sass-extend-nobody-told-you/