Sass Tutorial

Sass HOME Sass Intro Sass Installation Sass Variables Sass Nesting Sass @import Sass @mixin Sass @extend

Sass Functions

Sass String Sass Numeric Sass List Sass Map Sass Selector Sass Introspection Sass Color

Sass Exercises

Sass Quiz

Sass @extend and Inheritance

The @extend Directive

The @extend directive lets you share a set of CSS properties from one selector to another.

The @extend directive is useful if you have almost identically styled elements that only differ in some small details.

The following Sass example first creates a basic style for buttons (this style will be used for most buttons). Then, we create one style for a "Report" button and one style for a "Submit" button. Both "Report" and "Submit" button inherit all the CSS properties from the .button-basic class, through the @extend directive. In addition, they have their own colors defined

SCSS: @extend

.button-basic  {
  border: none;
  padding: 15px 30px;
  text-align: center;
  font-size: 16px;
  cursor: pointer;
}

.button-report  {
  @extend .button-basic;
  background-color: red;
}

.button-submit  {
  @extend .button-basic;
  background-color: green;
  color: white;
}

which will be compiled as

CSS Output

.button-basic, .button-report, .button-submit {
  border: none;
  padding: 15px 30px;
  text-align: center;
  font-size: 16px;
  cursor: pointer;
}

.button-report  {
  background-color: red;
}

.button-submit  {
  background-color: green;
  color: white;
}

By using the @extend directive, you do not need to specify several classes for an element in your HTML code, like this: <button class="button-basic button-report">Report this</button>. You just need to specify .button-report to get both sets of styles.

The @extend directive helps keep your Sass code very DRY.

Inheritance Chains

Any object-oriented programming language, the @extend directive can be chained. That is, you can extend a class that extends another class:

SCSS: Inheritance

.button-base {
margin: 2px;
radius: 2px;
}

.error-button {
@extend .button-base;
background-color: red;
}

.menu-button-error {
@extend .error-button;
}

which is transpiled to

CSS Output

.button-base, .error-button, .menu-button-error {
margin: 2px;
radius: 2px;
}

.error-button, .menu-button-error {
background-color: red;
}

Multiple Inheritance

Unlike most object-oriented programming languages, which only allow inheritance from a single base class, you can use @extend as many different classes as you need to:

SCSS

.button-base {
margin: 2px;
radius: 2px;
}

.error-base {
background-color: red;
}

.error-button {
@extend .button-base;
@extend .error-base;
}

Notice that it isn't necessary for the child class to contain any properties of its own. The example above results in the following CSS:

CSS

.button-base, .error-button {
margin: 2px;
radius: 2px;
}

.error-base, .error-button {
background-color: red;
}

Extending Other Selectors

Only single selectors can be extended. You can't, for example, extend p.test. But you can use the @extend directive can be used to inherit styles from any single selector, no matter how complex. Selectors like p.error and pseudo-classes like :first-child work just fine. The syntax is the same:

SCSS

li:first-child {
color: red;
}

.link-list {
@extend li:first-child;
}

which transpiles to

CSS

li:first-child, .link-list {
color: red;
}

Placeholder Selectors

Did you notice that in all the examples above, the base class, the one that's called by the @extend directive, is included in the resulting CSS? This is different than the behavior or mixins, which are only output when they're called with the @include directive.

Sass provides a mechanism for excluding the base class from the output via the placeholder selector, %. Simply add a % symbol before the name of the elector and it won't be included in the output:

SCSS

%button-base {
margin: 2px;
radius: 2px;
}

.error-button {
@extend %button-base;
background-color: red;
}

This results in the following CSS output

CSS

.error-button {
margin: 2px;
radius: 2px;
}

.error-button {
background-color: red;
}

Of course, this isn't the most efficient CSS since the .error-button selector is used twice. But the example is just that, an example. In a real project, it probably wouldn't make sense to declare the placeholder unless you were going to use it more than once.

Using @extend inside directives

The current version of the Sass compiler can't efficiently extend classes inside directives such as @media unless the base class is also inside the directive, so at least for the time being-referencing a base class outside the directive will fail. You can reference classes within the context of the directive, however, so this works fine:

SCSS:

@media print {
.text {
font-family: Sans Serif;
}

p {
@extend .text;
color: black;
}
}

and results in the following CSS

CSS

@media print {
.text, p {
font-family: Sans Serif;
}

p {
color: black;
}
}