1. What is SASS @extend Rule?
Sometimes, while working on a project, we design an HTML element with different variations. But all the variants should have some core similarity to follow along with some separate styles. The SASS @extend rule or directive allows the developer to solve this problem by letting the variants inherit some basic style rules. Further, this SCSS @extend rule also extends these variants with some additional styles along with the inherited rules. This is also called inheritance in SASS programming.
In this tutorial, we will learn about the SASS @extend rule and how to use this directive efficiently in our programs. Also, we will be discussing the types and usage phenomena of SASS @extend rule. Further, we will talk about SCSS placeholder selectors, the extension scope, and finally some limitations of the @extend rule or directive.
1.1. Syntax of SCSS @extend Rule
The syntax of the SCSS @extend rule is simple and very similar to other at-rules or directives. The below box reads the basic syntax of this directive.
@extend some-selector
2. Usage of SASS @extend Directive
Usage of this @extend rule or directive can be grasped by the underneath SASS example.
Example 1
.btn{ padding: 5px 10px; border-radius: 5px; font-size: 14px; &-red{ @extend .btn; background: #ffcccc; color: #ff0000; } &-green{ @extend .btn; background: #ccffcc; color: #00ff00; } &-blue{ @extend .btn; background: #ccccff; color: #0000ff; } }
.btn, .btn-blue, .btn-green, .btn-red { padding: 5px 10px; border-radius: 5px; font-size: 14px; } .btn-red { background: #ffcccc; color: #ff0000; } .btn-green { background: #ccffcc; color: #00ff00; } .btn-blue { background: #ccccff; color: #0000ff; }
2.1. SCSS @extend Rule Usage Explanation
- The above instance contains style rules generated for HTML .btn selector. Firstly, some general style declarations are set for the .btn. Further, the variants get the extension of the .btn using the SCSS @extend rule.
- Further, the SCSS @extend rule tells the parser to use the parent style declarations for the current selector also.
- Also, we used the parent selector & to apply the rules of the parent .btn to the child element. This is done by the method of Style rules nesting as depicted in the above SASS example.
- Lastly, after the nesting and @extend rules get applied, the CSS styles are generated. We got .btn, .btn-red, .btn-green, and .btn-blue classes as a result of nesting and applying the @extend directive to our SCSS style rules.
- The adjacent CSS code tab displays the generated CSS for this SCSS @exted directive example.
2.2. Another Approach of SCSS @extend Directive
In the above two examples, we have seen that the nesting approach is utilized to extend the style rules. However, there is a possibility of another approach to using the @extend directive in SCSS style rules without nesting. Quickly look over the following example to perceive this method.
Example 2
.heading{ color: #0000ff; background: #ffffff; } h2{ @extend .heading; font-size: 30px; } h3{ @extend .heading; font-size: 26px; }
.heading, h3, h2 { color: #0000ff; background: #ffffff; } h2 { font-size: 30px; } h3 { font-size: 26px; }
As you can see in the above example that we have not used the nesting principle of SASS. Instead, the .heading style rule is written above and then extended later by h2 and h3 selectors. This approach also works perfectly fine and the SASS @extend directive produces the CSS styles as desired.
2.3. Types of SCSS @extend Rule
There are two usage types of SCSS @extend rule as listed below.
2.3.1. Mandatory Type Extend
The normal approach of this directive is termed as mandatory type. In the above example, we used this rule as a mandatory type in our SCSS style rules. If the extend SASS style rule is not present in the stylesheet, there will be an error and transpilation will stop.
2.3.2. Optional Type Extend
The other type of SCSS directive is the approach of using the SASS @extend rule as optional in our styles. In other words, we can add an !optional flag with the extended declaration to make it an optional directive. If the class or selector is not available which is extended, then this !optional flag will not produce an error. Hence, the absence of the extended style rule will not stop the parsing of our stylesheet.
Check the following example for the usage of the !optional flag.
!optional Flag
.new-btn{ @extend .my-btn !optional background: #2a73cc; color: #fff; }
3. SASS Placeholder % Selectors
In the previous examples, we used simple CSS selectors to extend the style rules. We saw that the rule which extends also takes part in the CSS stylesheet. However, SASS provides us with a special selector known as a placeholder % selector. As the name speaks for itself, the placeholder selectors just work as a reference. It means that the placeholder selectors will not be appended in the final CSS output.
Consider the following instance to discern this SCSS placeholder selector.
Example
%shadow{ -webkit-box-shadow: 0px 0px 2px 2px rgba(0,0,0,0.1); -moz-box-shadow: 0px 0px 2px 2px rgba(0,0,0,0.1); box-shadow: 0px 0px 2px 2px rgba(0,0,0,0.1); } .alert, .code{ @extend %shadow; }
.alert, .code { -webkit-box-shadow: 0px 0px 2px 2px rgba(0, 0, 0, 0.1); -moz-box-shadow: 0px 0px 2px 2px rgba(0, 0, 0, 0.1); box-shadow: 0px 0px 2px 2px rgba(0, 0, 0, 0.1); }
As it is vividly revealed in the former example that the placeholder selector class %shadow is declared initially. After that, this class is extended for .alert and .code selectors. Moreover, the results show that the placeholder %shadow just imparted its styles to the .alert and .code classes as shown in the CSS tab. The %shadow itself doesn't appear in the final CSS output.
3.1. SASS Private Placeholder Selector
In the earlier example, we used the SASS placeholder to extend the SCSS style rules. But there is a possibility that we are designing many stylesheets and for each file, we need different declarations for the %shadow selector. Whenever we call the %shadow selector by SASS the @extend directive, this particular placeholder selector will be called. However, SASS provides us with the functionality to limit the scope of the placeholder selectors by making them private.
3.1.1. How to Make Private Placeholder Selector in SASS?
The private placeholder selectors are only available in that specific stylesheet in which they are defined. Hence, we can define different declarations for this selector for each stylesheet. To make a placeholder selector private, we use a dash - or an underscore _ before its name. Now that placeholder selector is private and solely available for the only stylesheet in which it is declared.
Extension Scope
4. Limitations of @extend Rule
In the above examples, we have seen the usage of the @extend directive in our SCSS style rules. But there are certain limitations to using the SASS @extend directive. Further, we can only extend certain types of selectors. See the subsequent example to understand the myth.
Example
p.alert{ margin: 10px; } .red, .green{ @extend h2.alert; }
// Error: Compound selectors are not extended.
The above extension tells the parser about the wrong implementation of the SCSS @extend directive. Thus, it will produce the error message. However, we can extend multiple selectors by the following method. A comma separated selectors servers the purpose.
%one{ // style rule one } %two{ // style rule two } .three{ @extend %one, %two} // Both %one and %two are extended at the same time.
4.1. Effects of @extend Directive on the Child Rules
Importantly, the SCSS @extend directive takes effect from the parent selectors only. It means that all the parent selectors in the nested SCSS style rule will affect the current rule which uses this directive. However, any child rules of the current rule will have no effect of this directive and will parse as normal SCSS rules. Consider a short example below to crack this mystry.
Example
.header{ font-size: 28px; background: #fff; &-post{ @extend .header; border-left: 10px solid #000; h3{ font-size: 24px; } } }
.header, .header-post { font-size: 28px; background: #fff; } .header-post { border-left: 10px solid #000; } .header-post h3 { font-size: 24px; }
The above example distinctly portrays that the h3 selector in the inner-most rule of the nesting has no effect on the SCSS @extend rule. However, the &-post selector has the directive and hence has the effect of the parent styles. Navigate the CSS tab to witness the limits of this directive.