Naming Convention in CSS

My mind is on CSS quite a bit these days. At Shopify, I'm jumping into projects that already well under way. As a result, it's been a great way to look at what I wrote in SMACSS and see how applicable it is to yet another project. (As if Yahoo! wasn't already enough of a testing ground.)

With Yahoo!, I (and a team of people) were writing the CSS from scratch and creating our mental map of the project as we went along. Jumping into the middle of a project as I am at Shopify, I have to try and figure out why things are done the way they are.

Here's an example of something that I ran into in the CSS:

#loading-header .loading { background: url(spinner.gif) no-repeat 0 0; }
[...separated by a few pages of code...]
#content {
[...separated by more code...]
  #loading-header { display:none; }
  .row { display:block; }
  &.loading {
    #loading-header { display:block; }
    .row { display:none; }
  }
}

The loading class has a spinner. Got it. But wait, there's a loading class inside an element with an ID of loading-header and another loading class that gets added to the element with an ID of content. Are they the same somehow? Is there some inheritence that is taking place?

As it turns out, no. These two loading classes were named exactly the same thing but applied in two different contexts. They really had no relation at all except that the #loading-header (and thus, #loading-header .loading) is only visible with #content.loading. (The &.loading is part of SASS and adds #content in place of the ampersand.)

One class is a state. Because it's a state, I prefer to prepend all my states with "is-". In this case, it would be "is-loading". The question asked when I first mentioned this is, "isn't the 'is-' redundant?" But as you can see from the example, it isn't. The naming convention clarifies its intent.

In this case, I had to determine intent based on the CSS. Other times, you're looking at the HTML first.

<div id="content" class="loading">
<div id="loading-header">
    <div class="loading">

Where do you begin to look in the CSS to find what you're looking for? You'd probably start with a search for ".loading". Now you're left trying to figure out which loading class applies to what element. The swaths of CSS that separated the relevant parts made it harder to see what was going on.

The simple answer to this, of course, is not to naming two different things with the same name. However, I believe a solid naming convention clarifies intent and makes the project easier to understand. We've long applied naming conventions to programmery things like JavaScript and PHP. The same should go for CSS.

Published January 24, 2012
Categorized as HTML and CSS
Short URL: http://snook.ca/s/1011

Conversation

15 Comments · RSS feed
Richard Livsey said on January 24, 2012

In this case would it not only be good to change #content.loading to #content.is-loading, but maybe also change #loading-header .loading to #loading-header .contents or even #loading-header #loading-contents if it is unique?

Brandon Richards said on January 24, 2012

I agree. The issue I run into most often is when a project has hit the launch milestone for a time and then a revision will be requested from client that requires additional styles that the developer doesn't or isn't familiar with the entirety of the project so they inject their own 'schema' and then that's perpetuated for each revision. Is there a better way to manage the naming conventions used?

Moritz Gießmann said on January 24, 2012

Fullack. Had the same thing in a current project with the same classes nested in each other doing different things. Naming guidelines help internally but not if you have to work with foreign code...

Dan M said on January 24, 2012

I've started namespacing all my CSS rules with the id of the page they are a part of. So if I have a #loading-header on the splash screen, it will be listed as #splash #loading-header. (Actually, I should probably use a naming convention as you've described to identify what is actually a page. #pg-splash?)

This reduces naming conflicts to the page-level, which is good enough for my needs. (These days most of my web development is for mobile devices, and those designs tend to favour many small pages over few large ones.)

Ramon Lapenta said on January 25, 2012

I've been thinking about this for a while now.

This is a good example of a case where some kind of context-driven CSS can be useful. I'd like to write less CSS and avoid using tons of non-semantic classes in the HTML. Naming conventions sound like a good start :)

Tobias Buschor said on January 25, 2012

All my css-classes that have a specific context have the prefix "-".


<div id="content" class="-loading">
<div id="loading-header">
    <div class="-loading">

In my css I never write:


.-loading {...}

I write:


content.-loading {...}
loading-header > .-loading {...}

If everyone writes css this way, we should get no conflict with third part code.

Ryan Cannon said on January 25, 2012

YUI's Widget framework has an interesting take on this. Widget instances have a method getClassName() that outputs value for the class attribute based on a configurable prefix, the widget's name and any values to supply to the method:

var w = new Y.Widget();
w.getClassName();                   // yui3-widget
w.getClassName("content");          // yui3-widget-content
w.getClassName("state", "loading"); // yui3-widget-state-loading

It's not perfect. it's not smart with regards to inheritance, for one thing, but I find that this type of prefixing works really well. Although the class names are long, your selectors are relatively short; poorly-performing selectors like .container > ul > li > a are shortened to a snappier .container-list-link. Also, since it relies on class selectors and not ID selectors, it's incredibly portable.

Nate Klaiber said on January 30, 2012

As Phil Karlton said:

There are only two hard things in Computer Science: cache invalidation and naming things.

This applies to CSS, too.

I think the comments here highlight this, too. Everyone has their own way, that seems right to them - but may conflict with how someone on another team writes their CSS. Seems like this is a dilemma that will continue. Thoughts?

Jonathan Snook said on January 30, 2012

@Richard: yes, changing the naming on the other loading element would be good as well. I would have likely named it ".loading-header" and ".loading-label".

@Brandon: Documentation is best. An organization should have guidelines on how and why things are the way they are. SMACSS also helps.

@Dan M: if all your CSS is namespaced to the page then don't bother putting it in an external CSS file. Keep it on the page. The only benefit of having it in a separate file is that you're pre-caching for pages the user hasn't visited yet. Although, personally, I would try to make things more generic.

@Tobias: that's essentially the problem I describe in this post. The problem is that when I stumble across "-loading", I have to find which parent element it pertains to. And it didn't help that loading-header was inside of content.

@Nate Klaiber: Indeed. Naming things is hard! Much of the SMACSS methodology really comes down to naming things. (Where, how and why are things named the way they are.)

Chris Blown said on January 31, 2012

I'm not sure about the best policy for CSS naming conventions. I always seem to find unique situations that either break or force a rethink of my own system on most projects.

I will say that adding comments to the CSS goes a long way to establishing how its being done. As Nate says everyone has their own way. If I can understand what that is by reading a small description and the odd comment in the CSS, its worth its weight in gold.

Lillan said on February 13, 2012

Unfortunately I have seen this problem too often to believe it's a pure coincidence. BTW is it so good to precede a CSS selector/class with a hyphen?

Jonathan Snook said on February 13, 2012

@Lillan: You can precede a class name with a hyphen, although I'm not personally a big fan of it.

John Milmine said on February 16, 2012

I agree that the Hyphen feels odd.

I generally go by the rule that the name should describe what it does not where it is.

Stan Duncan said on February 20, 2012

Some of the issues I run into are when working with multiple platforms or frameworks on one project and they all use different naming conventions. In this case, I try to follow that specific platform's convention when I am modifying/adding any CSS for that part of the project.

Luci said on March 08, 2012

I've got to say, I never thought of applying a prefix-naming convention before reading your article! And yet.. now I've read it I find myself thinking that that is bloody genius! At the moment like to think that the CSS i write is fairly helpful to any new developers hooking in to a project - I'm a big fan of comments in CSS (and everything else!)

I agree with Moritz as well though - it's all well and good taking on these standards on a personal level, or even a studio level - but unless it's taken on across the board there's always going to be that instant of 'what on earth is going on here' when coming face to face with css that doesn't have these naming conventions.

Sorry, comments are closed for this post. If you have any further questions or comments, feel free to send them to me directly.