Eliminating Multiple-Style Classes with @extend and SCSS

SCSS has numerous beneficial features, include one that I really came to love during my last project. The @extend feature really took the cake, and I think will help me along my path as a maker! It has a couple downfalls in practice, but it is such a great feature that I want to convince you to give it a try on your next project.

What is @extend?

Extend is a lot like inheritance in programming. It lets you import css styles from a previously defined css rule into another rule.

Let’s say you have three elements on the DOM that you want to style. Each element will look the same except each element’s border color will be different. Using the @extend feature, one approach to solving the styling of the elements is to define one class for the structure of the element. We will call the class .element, and define the height, width, background color, border thickness, etc.

.element{
   width:300px;
   height:150px;
   margin:2%;
   background:#cccccc;
   text-align:center;
   border:4px solid;
}

Screen Shot 2014-07-07 at 3.07.03 PM

Here is an example of how I might have solved this problem before.

Now that we have the main structure of the elements defined, we would create three new classes unique to each element. We will name those classes .element-a, .element-b and .element-c and apply the border color for each element.

.element-a{
   border-color:blue;
}

.element-b{
   border-color:yellow;
}

.element-c{
   border-color:orange;
}

Here is where you would normally add the .element-a, .element-b and .element-c to the html, but there is another way…

How do you call @extend?

Instead of calling those classes in the html, we will tell the class to inherit the rules into its styling. In order to @extend the styling rules of a css class into another, you use the syntax @extend .classname;.

In our case, the first element’s css rule would look like:

.element-a{
   @extend .element;
   border-color:red; 
}

This should be added to .element-b and .element-c. You can also import multiple class rules by a comma space separation, for example: @extend .class-name1, .class-name2;.

Now that you have the @extend added to your class rule, when the SCSS is compiled, the correct rules will be inserted for you. How awesome!

Screen Shot 2014-07-07 at 3.26.31 PM
Here is how the example should look with the @extend feature.

What I loved about @extend

There are two great benefits of using the extend feature. First, it can reduce the amount of duplicate style rules needed in a stylesheet. As per the example above, instead of having the structure css rules defined in each class we can combine these rules then import them into the individual classes. This can reduce mistakes when modifying the styles later into development.

Second, this also reduces the amount of classes applied to an element in the html keeping all the styling on the stylesheet. @extend can allow us the ability to use a styling framework like bootstrap while separating your style markup from your content.

What I didn’t care for about @extend

One of the down sides to SCSS and the @extend feature is that it creates a lot of rules when it compiles. On most modern browsers, this really isn’t an issue. But in the project I was working on, we had support ie.8, which only supports 4,096 css rules limit per stylesheet.

Secondly, @extend made designing via Firebug/developer tools more challenging, as the class names are not in the html markup like I had been use to when developing with Bootstrap. To solve this, I would develop and design the page with the multiple classes per element in the html. Once the design was accepted and complete, I would move the classes to stylesheet using the @extend feature.

Before using the @extend feature, I would have handled the styling through multiple classes. Now I prefer to keep the styling apart from the html as much as possible. How do you feel about having numerous classes added to an html element? Do you like the framework approach or like to keep your code clear of styling?
 

 
Conversation
  • Alex Bondarev says:

    instead of working fine … i would like to combine classes and call it as …
    but if if i put in scss
    btn-bar-xxx { @extend btn; @extend btn-primary; @extend btn-bar; width: 280px; }
    it cannot find btn class

    Module build failed:
    btn-bar-xxx { @extend btn; @extend btn-primary; @extend btn-bar; width: 280px; }
    ^
    “btn-bar-xxx” failed to @extend “btn”.

  • Alex Bondarev says:

    html tags were not handled in previous post, i meant to use
    <button class=”btn btn-primary btn-bar xxx>… – works fine

  • Comments are closed.