Using IDs with Low Specificity (CSS)

I like to stress that no rules are unbreakable. There will always be exceptions, there will always be a situation which requires a rule to be bent, there will always be anomalies. Whenever someone says always do x, apply some critical thinking to work out the principles behind that rule, and take and break the bits you need to.

One exception to this exception, however, is the use of IDs. There is never a time when using an ID in CSS makes sense; there is never a good reason to use one; this rule is not breakable. Even if you were working with third-party markup that you can’t edit, and all that is in that markup is an ID, you can still avoid using that ID in your CSS.

N.B. Using IDs in your HTML, as fragment identifiers, or in your JS, as hooks, is totally fine—it’s in CSS that IDs are troublesome.

Let’s imagine you have this third-party widget embedded on your page, and you want to style it:

<div id="widget">
    ...
</div>

Naturally, given that we can’t edit this HTML to use a class instead of (or alongside) the ID, we’d opt for something like this:

#widget {
    ...
}

Now we have an ID in our CSS, and that is not a good precedent to set. Instead, we should do something like this:

[id="widget"] {
    ...
}

This is an attribute selector. This is not selecting on an ID per se, but on an element with an attribute of id which also has a certain value. This particular selector is basically saying Hey, find me an element with an attribute called id which has a value ofwidget.

The beauty of this selector is that it has the exact same specificity as a class, so we’re selecting a chunk of the DOM based on an ID, but never actually increasing our specificity beyond that of our classes that we’re making liberal use of elsewhere.

But this is a hack.

Just because we know a way of using IDs without introducing their heightened specificity, it does not mean we should go back to using IDs in our CSS; they still have the problem of not being reusable. Only use this technique when you have no other option, and you cannot replace an ID in some markup with a class.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top