Arrange a Masterclass

Extending silent classes in Sass

Written by on CSS Wizardry.

N.B. All code can now be licensed under the permissive MIT license. Read more about licensing CSS Wizardry code samples

Table of Contents
  1. Featured case study: NHS

This is a shorter, tip-style post that covers a little thing I like to do when writing Sass. It’s something that I’ve been asked about in workshops, and something I hope to bring to the new version of inuitcss.

When writing Sass, specifically any objects or abstractions, I write it like this:

.foo,
%foo {
    color: red;
}

The reason for the solid and the silent class is simple: I only use the silent class as the subject of an @extend.

Oliver J Ash wrote a great post that I would really recommend you read; it will give this post a lot more context.

In short, a common problem with @extend is that it will indiscriminately extend every instance of a matching selector that it finds. For example, if you author this:

.foo {
    color: red;
}

.footer .foo {
    font-weight: bold;
}

.bar {
    @extend .foo;
}

You might expect, or want, to see some output like this:

.foo, .bar {
    color: red;
}

.footer .foo {
    font-weight: bold;
}

However, anyone who’s used Sass’ @extend directive before will know that what you actually get is this:

.foo, .bar {
    color: red;
}

.footer .foo, .footer .bar {
    font-weight: bold;
}

What Sass has done is it’s extended every instance of .foo that it could find. This is a very timid example, but Oliver’s article will paint a more detailed picture of what’s going on.

In order to circumvent this correct-but-unexpected (but really should be totally expected) behaviour, I came up with a very simple way of managing my @extend directives: make sure that the subject of an @extend only exists once in a project.

There are a number of ways you could achieve this, perhaps a simple naming convention or a namespace, something like:

.foo,
.x-foo {
}

Remembering to only ever @extend the x- prepended version—and avoid writing the prepended version elsewhere—means that there’s no chance of an overzealous @extend directive yielding far more CSS than we were expecting.

Featured case study: NHS

How I helped the NHS rapidly build a brand new product.

Read case study…

The only issue with this, really, is the fact that the x- classes will still appear in my CSS. Not such a big deal, but considering the whole point of this exercise is to reduce the amount of classes in our CSS, it seems a little counter-productive.

The obvious solution to this particular problem is silent classes. Instead of:

.foo,
.x-foo {
}

We’d write:

.foo,
%foo {
}

Now the %foo silent class—which should only ever exist once in any project—is the subject of our @extend. This means that we can limit the reach of our @extends, and not have that placeholder class appear in our compiled stylesheet(s).

Our Sass now looks like this:

.foo,
%foo {
    color: red;
}

.footer .foo {
    font-weight: bold;
}

.bar {
    @extend %foo;
}

And our compiled CSS now looks exactly how we want it:

.foo,
.bar {
    color: red;
}

.footer .foo {
    font-weight: bold;
}

The rules to follow:

  1. Only write a given silent class once in your Sass.
  2. Only ever @extend silent classes.
  3. Use solid classes in markup, and as many times as you need in your Sass.

All we’re really doing is making sure the selectors we @extend exist as few times as possible.

Of course, this solution isn’t bulletproof, failsafe, or ideal; it’s only as good as your ability to stick to it, and your ability to stick to it isn’t always entirely in your own hands. It’s simply a little hack I came up with in order to make use of @extend (which, incidentally, I don’t really use much anyway) whilst attempting to mitigate the effects of its ‘greedy’ nature.

There may well be better ways—and I’d love to hear them—but this, for now, is how I’m handling it. I actually created a mixin (which hasn’t been stress tested at all) to generate this in one, DRYer go: jsfiddle.net/csswizardry/ECntr

N.B. All code can now be licensed under the permissive MIT license. Read more about licensing CSS Wizardry code samples




By Harry Roberts

Harry Roberts is an independent consultant web performance engineer. He helps companies of all shapes and sizes find and fix site speed issues.


Hi there, I’m Harry Roberts. I am an award-winning Consultant Web Performance Engineer, designer, developer, writer, and speaker from the UK. I write, Tweet, speak, and share code about measuring and improving site-speed. You should hire me.

You can now find me on Mastodon.


Suffering? Fix It Fast!

Projects

  • inuitcss
  • ITCSS – coming soon…
  • CSS Guidelines

Next Appearance

Learn:

I help teams achieve class-leading web performance, providing consultancy, guidance, and hands-on expertise.

I specialise in tackling complex, large-scale projects where speed, scalability, and reliability are critical to success.