Arrange a Masterclass

Quasi-qualified CSS selectors

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. Risk?

This is a bit of an odd post in that the first half deals with qualified selectors, what they are and how they’re bad; the second half is more of a thinking-out-loud tip/trick than anything really substantial or interesting. Let’s see what you make of it…

One really basic way to make your CSS much nicer to work with is to avoid (over) qualified selectors. That is to say, it’s better to write .nav{} than ul.nav{}. This is for a variety of reasons, chiefly in that—with the former syntax—you can use .nav on anything at all, be that a ul or an ol and, secondly, it also keeps your specificity nice and low. Having an element prefixing the class selector bumps up its specificity unnecessarily and specificity is one of the easiest ways to get your project into a mess; keeping it as low as possible at all times is a very good idea.

For a decent (and very timid) example of how qualifying selectors impacts specificity, take a look at this fiddle. Here we can see that the qualified div.promo{} selector trumps the .special-promo{} selector. A sub-optimal fix would be to qualify the second selector. This is no good, because this will just go on and on and on… What we need to do is avoid qualifying selectors altogether.

So in short…

  • You should never (over) qualify selectors because…
  • …qualified selectors, by their very definition, can’t be used on other elements…
  • …and qualified selectors increase overall specificity. Bad!
  • But sometimes selectors are only ever meant for use on only one type of element…
  • …but you still shouldn’t qualify that selector for specificity reasons.
  • How do you denote that a selector is to be used on a particular element without actually qualifying it?

To start, a simple enough rule to follow; don’t qualify your selectors. This keeps classes element agnostic and keeps specificity low. Awesome!

Sometimes though, you can only really use a class on one element. A well abstracted class should be usable on a variety of elements, but oftentimes you have a class that can only ever really be used on one thing. How can you communicate this in your stylesheet without qualifying your selector? Let’s take an example…

Let’s say I have the media object in my project. The media object is element agnostic, as all good CSS should be. I know I can apply this to any element(s) that need to adopt that visual construct. This means my CSS only ever needs to read (actual styles omitted for brevity):

.media{
    [styles]
}
    .img{
        [styles]
    }
    .body{
        [styles]
    }

Here I don’t need to mark the classes for use on any specific elements because they can be used on (almost) anything. My CSS doesn’t care about my HTML and this is a very good thing.

However, what happens when I have a class like this:

.product-page{
    [styles]
}

Now, to look at, you can guess that this class probably belongs on a high-level container on a product page, but which one? The html element? The body? A wrapper div? The main content area? Well there are several ways I could communicate this to another developer (or myself, in six months time). Let’s, for this example, assume this class should be applied to my html element.

The first and most obvious solution to our problem might be do simply have this CSS:

html.product-page{
    [styles]
}

Now I can immediately see that this class belongs on our html element. But here I have unnecessarily increased my specificity. Not by much, but by more than I need to, and more than I ever should. How can I tell the next developer that this class should only go on the html element?

Perhaps like this?

/* Apply this class to the HTML element on a product page. */
.product-page{
    [styles]
}

Which definitely works, but it’s a lot to write. A lot more than we need to, and you can’t glean that information at a glance.

A thing I’m considering starting doing is this:

/*html*/.product-page{
    [styles]
}

I write the element in a comment so that it reads properly (a html element with a class of .product-page) but without altering the specificity at all.

Risk?

The obvious problem with this is that, if you work in a team, you will have to make sure all devs understand and follow this convention. You need team buy-in before being able to start using this kind of notation so that any devs encountering it understand that this has meaning and isn’t simply some commented out/redundant code.

So yeah, just an idea I’m toying with in order to quasi-qualify some selectors that are intended for use on a specific element but without altering that selector’s specificity.

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.