Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Sass, what's the difference between the @mixin and @extend directives?

Tags:

css

sass

I just finished with the Sass guide. The guide explains mixins:

..A mixin lets you make groups of CSS declarations that you want to reuse throughout your site. You can even pass in values to make your mixin more flexible.

and extend:

.. This is one of the most useful features of Sass. Using @extend lets you share a set of CSS properties from one selector to another ..

It looks like 'extend' may be implemented in 'mixin' (it seems 'mixin' is extend of 'extend' :-) ).

// @extend
.message {
  border: 1px solid #ccc;
  padding: 10px;
  color: #333;
}

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

.error {
  @extend .message;
  border-color: red;
}

.warning {
  @extend .message;
  border-color: yellow;
}

// @mixin
@mixin message($color) {
  border: 1px solid #ccc;
  padding: 10px;
  color: #333;
  border-color: $color;
}

.success { @include message(green); }

.error { @include message(red); }

.warning { @include message(yellow); }

and even more because mixins have params. But on the other hand the processed CSS is not exactly the same. But it will be same style effect on the DOM.

/* extend processed */
.message, .success, .error, .warning {
  border: 1px solid #ccc;
  padding: 10px;
  color: #333; }

.success {
  border-color: green; }

.error {
  border-color: red; }

.warning {
  border-color: yellow; }

/* mixin processed */

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

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

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

My question is how do these features differ? When should I use one over the other?

like image 284
Ilan Avatar asked Jun 12 '17 11:06

Ilan


People also ask

What is @mixin in Sass?

Sass Mixins The @mixin directive lets you create CSS code that is to be reused throughout the website. The @include directive is created to let you use (include) the mixin.

What is the difference between a mixin and inheritance?

Mixins are sometimes described as being "included" rather than "inherited". In short, the key difference from an inheritance is that mix-ins does NOT need to have a "is-a" relationship like in inheritance. From the implementation point of view, you can think it as an interface with implementations.

What is the purpose of @include directive in SCSS?

Used to include the mixins in the document. Explanation: In Sass, the @include directive is used to include the mixins in the document. The styles defined by the mixin can be included into the current rule.

What does @content do in Sass?

Sass 3.2 added the @content directive, which allows us to pass a content block into a mixin. We can use it anywhere that declarations need to be wrapped in outer-scoped selectors, and many places where declarations are duplicated.


2 Answers

From http://blog.nakulrajput.com/mixins-extends-and-placeholders/:

@mixin

Here is how mixins work. Definition and usage:

@mixin awesome {
    width: 100%;
    height: 100%;
}

body {
    @include awesome;
}

p {
    @include awesome;
}

The snippets above produce the following CSS:

body {
    width: 100%;
    height: 100%;
}

p {
    width: 100%;
    height: 100%;
}

To make things a little bit more interesting, we could make our mixin accept parameters. Even better, we are able to define default values if the mixin is called without arguments.

@mixin awesome($w: 100%, $h: 100%) {
    width: $w;
    height: $h;
}

body {
    @include awesome(960px);
}

p {
    @include awesome;
}

The result will be similar, but the width of the body is different.

body {
    width: 960px;
    height: 100%;
}

p {
    width: 100%;
    height: 100%;
}

If you use mixins, the styles in them are duplicated for each selector.

Mixins are very helpful if you need to change or calculate something in the final output, for example if you need to apply border-radius to several elements.

However, in some other cases there is a lot of duplicative code, which could be avoided if you use @extend.

**@extend**

.awesome {
    width: 100%;
    height: 100%;
}

body {
    @extend .awesome;
}

p {
    @extend .awesome;
}

It's similar, isn't it. In Sass it looks almost identical, but the CSS the result is:

.awesome, body, p {
    width: 100%;
    height: 100%;
}

Shorter than the version using a mixin. You can't pass parameters during the extending, but that's not the idea actually.

@extend should be used in those places where you want to share properties between the elements.

like image 61
geo Avatar answered Oct 24 '22 11:10

geo


Well, Mixin is like function that can do some work and output processed result while extend is like pre-defined cop-paste code

like image 22
Justinas Avatar answered Oct 24 '22 10:10

Justinas