1383Days

1383 days since this post was last revised. Specific details are likely out of date.

How do you name your HTML classes and CSS selectors?

I don’t subscribe wholesale to any of the BEM/OOCSS methodologies. Rather I do some fusion of what I find useful in everything I’m exposed to. I suspect many (most?) others do the same. Therefore, when I talk about naming things here it’s not in direct relation to one of the aforementioned systems. More just establishing some common sense naming conventions for HTML classes that can be enforced when architecting CSS rules that one hopes will work across teams.

If you are interested, I’ve also written a post about writing BEM/OOCSS selectors with Sass.

Over some time, I’ve tried a few naming conventions but I’m only just settling on something that, for the time being at least, I’m relatively happy with.

Unless you can convince me otherwise?

Before we proceed into naming and syntax pedantry, first, let’s agree on some case style definitions:

  • train-case : all lowercase, words separated by a hyphen (this text style is arguably more legible but using hyphens requires more characters)
  • UpperCamelCase : no hyphens, an Upper case letter defines each new word (less characters are needed with this style but arguably it is not as legible as train-case)
  • lowerCamelCase : no hyphens, an Upper case letter defines all but the first word (less characters are needed with this style but arguably it is not as legible as train-case)

As noted above, generally speaking, it’s easier to read the hyphen separated train case (some will argue otherwise). However, both camel-case variants have their upsides. Besides less characters being needed, with no hyphens, it’s simple in Developer Tools/Text editor to double click an HTML class and grab the whole name. With a hyphen separated class, it doesn’t select the whole lot. A minor thing but the very nature of what we are talking about is arguably nit-picky (sp?).

Why is any of this even important?

Well, if you’re a lone gun, it probably isn’t. If you have all the control over markup and the CSS selectors used in a project, name your HTML classes however you like.

However, if you’re trying to build some sort of system, whereby other developers (hopefully any other developers) can glean some sense from the classes you have used, it’s beneficial to define some consistent convention that can be enforced and referenced by all involved parties. I heard a great line on the JavaScript Jabber Show in relation to CSS:

Discipline is your only defence in terms of maintainability Brian Turley, on the JSJ Podcast

So true. Without some kind of naming and syntax discipline in CSS, the resultant code will look like it was built by a multitude of different people. That’s bad, M’kay?

For some time I had been using this kind of convention:

<div class="namespace-component-name--modifier-name-variant-label"></div>

First the namespace (optional), then a hyphen, then the component-name, then a double hyphen for the modifier-name (optional) and finally a hyphen to separate the variant-label. All in lowercase. The above example is the edge case. It would be unusual for both component name and modifier name to both need two words plus a variant label as well. The verbosity of this class is certainly undesirable.

Generally though, this convention has served me well. However, I’m primarily the one creating the classes and selectors so it’s easier for me to understand their intended meaning. My growing concern wasn’t just that other developers couldn’t figure out the intended use but also that the syntax wasn’t easily enforceable due to a fuzzy separation of sections within the class name. I needed some rules in place that had some clear logic to them.

So, whenever I hit these issues I see what people far smarter than me (that have already figured this stuff out) are doing:

I’m a big fan of Nicolas Gallagher’s naming convention for classes used in his Suit framework.

<div class="namespace-ComponentName--modifierName-descendantName"></div>

This ticks most of my boxes. The namespace is easily distinguishable from the component name and then the modifierName is easily distinguishable from the ComponentName. The descendantName is then easy to distinguish as it always comes after a modifierName (or not at all).

However, whilst it’s not a big deal, using a double dash to separate the modifierName from the ComponentName can occasionally mess-up syntax highlighting in IDEs (something that had long irritated me in my existing naming convention). For example, where comments are used in the HTML around code that has a class containing a double dash:

<!--<div class="wrap-class--all">-->

The HTML5 Validator also pisses and moans about the double-dashes meaning it’s not possible to map to XML. That isn’t a big deal either but… Oh who am I kidding – of course that bothers me. I know it shouldn’t but I DO hate it when the Validator tells me I’m doing something wrong.

So, if opting to not use a double-hyphen, there’s a challenge of how to actually clearly demarcate modifierName from ComponentName.

The allowable characters for naming selectors in CSS is actually fairly limiting. The Character and Case section of the W3C CSS2.1 spec (which the CSS3 modules also reference) describes the allowable characters for class names thus:

In CSS, identifiers (including element names, classes, and IDs in selectors) can contain only the characters [a-zA-Z0–9] and ISO 10646 characters U+00A0 and higher, plus the hyphen (-) and the underscore (_); they cannot start with a digit, two hyphens, or a hyphen followed by a digit. Identifiers can also contain escaped characters and any ISO 10646 character as a numeric code (see next item). For instance, the identifier “B&W?” may be written as “B\&W\?” or “B\26 W\3F”.

In the past, the ability to use unicode characters has led me to experiment with all kinds of crazy. If you are easily offended, skip this code example:

.♣ {
    width: 100%;
}


.◴ {
    width: 75%;
}


.★ {
    width: 50%;
}

I know, I know. As compact as they are, they lead to an even greater obfuscation of the intended use. Plus character encoding can also become screwed up across systems.

Where I’m at

Coming back to the far saner Suit naming convention, I’ve decided the lion share of work has been done for me (thanks Nicolas)! The only amendments I am making are to separate the ComponentName from the ModifierName with an underscore and write both as ‘UpperCamelCase’.

Some would argue that writing an underscore as a separator is more effort (as it requires use of the shift key to type) and that they are sometimes hard to see when looking within markup. I’ll concede the second point, but on the former, you need to press shift to get capitalisation of the ModifierName (which comes directly after) anyway so I’m prepared to suffer that minor inconvenience. I also tend to think of the descendant name in Nicolas’s example as a ‘variant label’ so I refer to it as such when I document it.

Now, I’m in no way suggesting this is a wholesale improvement, just something that works better for me. Here’s an example of the way I am currently naming HTML classes:

.namespace-ComponentName_ModifierName-variant-label
  • name-space : all lowercase/train-case (optional).
  • ComponentName : upper camel case (non-optional)
  • _ModifierName : upper camel case preceded by an underscore (optional)
  • -variant-label : all lowercase/train-case (optional)

Now my intention (and hope) is that each potential part of a class name can be logically discerned from another:

  • If the first part of a class is all lowercase/train-case it is a namespace (I typically use this for very specific features or special interests e.g. js-Thing for a JavaScript hook)
  • If the first part of a class is CamelCase it is a component
  • If something UpperCamelCase is preceded by an underscore it is a ModifierName (if not it is a ComponentName)
  • If something is all lowercase/train-case and not the first part of a class name it is a variant label
  • Finally, if a class is lowercase, all by itself then it is a utility class e.g. w50, blk.

Also, as a tiny advantage (and admittedly this is a minuscule thing – I really am clutching at straws) using an underscore to delineate the ModifierName from the ComponentName I am saving a character (1 byte win with each class name Woo Hoo!).

So, I’m keen to hear how everyone else is naming their HTML classes and why? Or, even more useful if there is something blindly obvious I’m missing in my suggested approach?

Ben Frain Developer, Author: 'Enduring CSS', 'Responsive Web Design with HTML5 & CSS3'.