Photograph of a man in red-tinted glasses and a shoulder-width moustache

As sites become complex information systems, the technologies we use to build them must grow and adapt. One of the more recent approaches to CSS development is object-oriented CSS (OOCSS), a methodology that is helped immensely by the power of @extend in Sass. To understand one is to understand the purpose of the other, so we’ll start with a very brief explanation of the various development methodologies:

OOCSS, first introduced by Nicole Sullivan, is one of a cluster of approaches that seek to impose modular control over site presentation; similar methods include SmaCSS, Atomic CSS and BEM. All of them reply on the fact that any HTML element can take multiple CSS classes. As a simple example, let’s use a typical class for article promos on a website:

article.promo {
	border: 1px solid #333;
	border-radius: 2px;
	overflow: hidden;
}

This defines the root appearance of basic article promotional blocks on a web page. Let’s also assume that we’d like to have at least one article with a special appearance to make it stand out: something for breaking news, perhaps. Traditional CSS approaches would require us to duplicate the base styles of the .promo class in the new class of .breaking before adding anything new:

article.breaking {
	border: 1px solid #333;
	border-radius: 2px;
	overflow: hidden;
	background: hsl(20,80%,80%);
}

There’s a very real problem with this approach: if we decide to change the presentational rules for the .promo class, we’d have to remember to also change the .breaking class, as well as any other that duplicated the base rules of .promo.

Alternatively, we could break up the classes and write them this way instead:

.blockborder {
	border: 1px solid #333;
	border-radius: 2px;
	overflow: hidden;
}
.blockhighlight {
	background: hsl(20,80%,80%);
}

Using these styles, an article we want to be “normal” would have the .blockborder class applied:

<article class="blockborder">…

For a breaking news article, we’d apply both the .blockborder and .blockhighlight classes:.

<article class="blockborder blockhighlight">…

The result for the second article is that the two classes would combine, producing something like the appearance of the center block below:

Gentleman of Four Outs

When a vulgar, blustering fellow asserts that he is a gentleman, the retort generally is, “Yes, a Gentleman Of Four Outs”—that is, without wit, without money, without credit, and without manners.

Draw The Long Bow

To tell extravagant stories, to exaggerate overmuch; same as “throw the hatchet.” From the extremely wonderful stories which used to be told of the Norman archers, and more subsequently of Indians’ skill with the tomahawk.

This allows us to “mix and match” CSS classes to create appearance rules that are visually consistent. But as you can imagine, taking a strongly modular approach to site stylesheet development creates long lists of classes that need to be applied in order to correctly style page elements:

<article class="blockborder blockhighlight twoeighthcolumn mediumgutter">…

… which are difficult for developers to remember or apply correctly.

Simplifying Modular Development with @extend

Rather than long lists of classes that only become interrelated when they are applied to HTML, we can create strong interdependence of classes in Sass using @extend.

Returning to our earlier example, write .blockborder as normal in CodePen (after setting it up for Sass, as shown in the first article):

.blockborder {
	border: 1px solid #333;
	border-radius: 2px;
	overflow: hidden;
}

We want the .blockhighlight class to inherit everything in .blockborder and then extend it, so we’ll write the second class as follows:

.blockhighlight {
	@extend .blockborder;
	background: hsl(20,80%,80%);
}

The CSS generated by Sass returns to the first example, meaning that we can style a breaking news article with just one class:

<article class="blockhighlight">…

But because Sass writes the CSS interdependently using @extend, changing the “base” CSS of .blockborder immediately changes the appearance of .blockhighlight, making maintenance of your CSS far easier. Try doing so yourself on the CodePen example.

A Few Tricks & Gotchas

@extend is very powerful; it can even create new classes that inherit from nested selectors. However, you cannot extend from a declaration outside a media query to one inside one:

.featured {
	…
}
@media all and (max-width: 750px) {
	.smallstuff { 
		@extend .featured;
		// this won’t work
	}
}

Be sure to double-check the CSS created by Sass: “chaining” selectors with @extend is very useful, but if used poorly it can inflate the size of stylesheets dramatically. Employed in excess, extending selectors can cause maintenance problems, due to the fact you can can @extend an @extend, creating long interdependent chains that are difficult to track down or understand.

The styles generated by Sass @extend will always work, but we also want them to perform well.

Native @extend In CSS?

CSS continues to take proven features from preprocessors and fold them into itself: variables, and now a proposal for @extend.

Right now, native @extend in CSS is only an “interesting idea”: even if it is adopted in the official specification, it will be years before it could be used in production. In the meantime, preprocessors like Sass are an excellent way of using this powerful feature in your code.

Photographs of contestants in the 2014 World Beard & Moustache Championships by Greg Anderson, used with permission.

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.
Check out the CodePen demo for this article at https://codepen.io/dudleystorey/pen/zxzQXa