Sass: The @extend Directive - Vanseo Design |
Posted: 09 Feb 2016 05:30 AM PST Have you ever wanted one selector to inherit the styles of another? Maybe you have a .button class for standard buttons across the site and now you want to create a larger button that should be styled the same as the rest of your buttons, except it should be larger.
Wouldn't it be nice if you could tell the new class to style itself like standard buttons, but bigger. The @extend directive allows you do just that. It lets one selector inherit the styles of another selector, which you can then build on. For the last few weeks I've been looking at @-rules and directives in Sass. I talked about @-rules in general and then more specifically about @media and @import. Last week I offered some ideas for structuring your Sass directories. Today and next week I want to talk about the @extend directive, which as I mentioned allows one selector to inherit the styles of another and allowing you write DRYer code. The @extend DirectiveLet's think for a moment how you might style a standard .button class and then a .button-large class for a larger version of the standard button. A common approach is to create a .button class with the styles you want for your buttons and then add a new .button-large class that overrides the size.
You would add both classes to any elements that should become a large button.
The downside is you now have an additional class to maintain in your stylesheet and to remember to include in your HTML. The @extend directive provides another option that doesn't require a second class on your HTML. The directive allows you to extend one selector and tell Sass that the second selector should inherit the styles of the first. Here's how you might style a standard button and then a large button using @extend. The size of the button is controlled by its font-size. If the font-size increases, the padding will also increase and both will lead to a larger button.
The .button class sets some general styles for how buttons across the site should look. The .button-large class extends the .button class through the @extend directive. It then overrides the font-size and makes it 50% larger. The Sass compiles to the following CSS.
Notice that the styles aren't repeated in the .button-large class, but rather the selector has been added to the .button selector styles keeping the CSS DRY. Creating a large button now requires a single class instead of two. Here the first line of HTML creates a standard button and the second line creates a large button. Each link requires a single class.
The selector that @extends and inherits styles will be inserted in DRY fashion wherever the extended selector exists in the stylesheet. For example imagine your buttons come in different colors and you defined those colors on a selector that requires the element to have both classes.
Your CSS only adds the background color when both classes are present.
You then extend the .button class inside a .button-large class as before.
A .button-large selector will be inserted wherever a .button selector exists so you'll find something like this in your compiled CSS file.
When selectors are merged this way, the @extend directive can avoid unnecessary duplication. For example if your compiled code would become:
The duplicate would be removed.
Extending Complex SelectorsYou can extend more than classes. Any selector representing a single element can be extended. Imagine your links change background color and you want to do the same when hovering over a button.
Here I created a class called .button-hover that extends the :hover pseudo class and compiles to:
As a selector, a:hover is still relatively simple. You can extend more complex selectors such as Multiple @extend DirectivesA selector isn't limited to extending one other selector. Selectors can use multiple @extend directives and inherit the styles of several different selectors. For example imagine you created classes for different background colors and all your large buttons will have a green background. Not exactly something you'd do in practice, but go with it for the example.
The .button-large class extends both .button and .green and then bumps up the font-size. The code compiles to:
Another way to write multiple extends is by using a comma-separated list of selectors. In the previous example both extends could have been written as one.
Either works. I prefer new lines because it's easier for me to read, though may find the single line easier to read. Chaining @extend DirectivesYou can chain selectors so that one selector is extended by another selector, which is then extended by a third selector.
Here .button extends a link and is then extended by .button-large. The Sass compiles to:
Selector SequencesAt the moment you can't extend a sequence of selectors. For example the following doesn't work.
However a selector sequence can extend a single selector.
This is perfectly valid and compiles to:
Similarly you can extend one part of a selector sequence. Here .button-large extends only the .button class part of the sequence.
When the Sass is compiled every instance where you would find .button, you'll now also find a duplicate using .button-large instead.
Merging Selector SequencesExtending sequences of selectors can get complex in a hurry. Consider the following example.
The second selector is extending .button. There are more ways the selectors above can be merged than you might think at first. The obvious way is to substitute the entire second selector for .button in the first selector.
However, the following selector is also valid.
As long as .button-large comes before .page .sidebar the selector will be valid. It turns out there are 10 possible ways to merge these selectors, though not all of them are likely to be used. Instead of adding all 10 on compile, Sass generates only those likely to be useful according to the following two rules.
Following this rule the previous example compiles to:
Here I changed the previous example and replaced .container in the second selector to .page so the two will share a selector.
The Sass compiles to the following.
The only difference in the sequence (besides the change from .button to .button-large) is that one selector contains .sidebar and the other contains .footer. These will alternate positions as you can see in the compiled code. Closing ThoughtsInheriting the styles of one selector into another helps make maintenance easier by having a single source for those styles. Inheritance in general reduces duplicate code and helps make your code reusable. Sass maintains the lack of duplication by compiling to DRY CSS. If you've ever styled one selector to look similar, though not quite the same as another, you'll appreciate being able to inherit the styles using @extend. There's more I want to cover about the @extend directive and I'll finish next week, including what to do when you want to inherit the styles of one class, but you don't actually want to compile the code of that class. Download a free sample from my book Design Fundamentals. Join me as I share my creative process and journey as a writer. This posting includes an audio/video/photo media file: Download Now |
You are subscribed to email updates from Vanseo Design. To stop receiving these emails, you may unsubscribe now. | Email delivery powered by Google |
Google Inc., 1600 Amphitheatre Parkway, Mountain View, CA 94043, United States |