By Meitar Moscovitz

How To Compose HTML ID and Class Names like a Rockstar

By Meitar Moscovitz

As you know, both id and class values can be used to provide implementation hooks for presentational (CSS) and behavioral (JavaScript) effects in front-end code. Of course, they can also affect semantics; microformats are a design pattern that makes heavy use of the class attribute in a specific way. But do you know what else these two core attributes can, and I argue should, be used to do?

I think, when crafted thoughtfully, id and class attributes can also improve our code’s organization, readability, and can directly improve many aspects of developer-to-developer communication, which can be particularly important on large teams. Indeed, part of the success of microformats came from creating thoughtful conventions about which class names to use when, and why.

ID and Class Name Considerations

When composing values for id and class attributes, I ask myself the following questions, in order, to help guide me towards a good (and reproducible) name:

  1. What function does the element serve? (Why’s it there? What’s its purpose?)
  2. Are there other elements that serve similar functions? (How similar? What are the differences between them?)
  3. Are there other websites that use elements for the same purposes? (What are those named?)

Answering the first question helps me produce self-documenting code by coming up with a name that matches the code’s function and purpose. For instance, one glance at code like this immediately suggests that it’s a navigation list, so having a reference to “navigation” in its name makes obvious sense.

    <li><a href="/">Home</a></li>
    <li><a href="/about/">About</a></li>

Answering the second question helps illuminate opportunities for reuse. For example, unless there is only one navigation element in the entire codebase, identifying the above code merely by function (“navigation”) is unlikely to be sufficiently distinguished. It might therefore get named “main navigation,” “site navigation,” “navigation bar,” “global navigation,” or some combination of these, while another navigation element gets one of the other names. Let’s go with the “site” name for the sake of this example:

<ul id="sitenavigation">
    <li><a href="/">Home</a></li>
    <li><a href="/about/">About</a></li>

Answering the third question can help code interoperate technically (as in the case of using Microformats), but it can also help keep naming schemes themselves clear and simple. “Nav” is a common abbreviation, and is even a first-class HTML5 element in its own right you can use today. By taking inspiration from existing work, you lessen the cognitive effort needed to make and maintain your own conventions.

<ul id="sitenav">
    <li><a href="/">Home</a></li>
    <li><a href="/about/">About</a></li>

The Importance of Naming Conventions

A naming convention is simply an agreement among developers to use the same kind of name to refer to the same or similar things, and a different pattern to refer to something else. Such agreements are incredibly simple, but incredibly powerful. For example, I bet you can read the following sentence because English lettering follows widely agreed upon rules: I re_lly l_ve sem__tic __rkup!

Conventions enable anyone who’s familiar with their general principles to fill in the details even when those details are missing. The innate human ability to extrapolate information based on conventions and prior knowledge isn’t just useful when it comes to filling in the blanks. The same technique can be used as a way to communicate purposes and intentions.

For elements that are generic to most websites, such as global navigation lists and search fields, I use TitleCase names. For elements that are specific to one site, however, I use lower-case-dashed names. I’m using the naming convention as a kind of microsyntax to imply “generic” (aka “global”) versus “specific” (aka “local”) scope regarding the purpose of the element, a distinction that can help orient fellow developers within a big picture view of the codebase.

Following this convention, sitenav becomes SiteNav:

<ul id="SiteNav">
    <li><a href="/">Home</a></li>
    <li><a href="/about/">About</a></li>

Note that the use of TitleCase versus lower-case-dashed names are independent of whether or not they’re present in a CSS class or an id attribute value. Here’s how I might mark up a text input field in a search form:

<input type="text" class="SearchField" id="widgetco-search" title="Find a Widget" value="" />

We know that a “search field” is a generic concept so, according to my conventions, it gets TitleCased. By the same (obvious) token, Widget, Co.’s specific search field doesn’t exist on other websites, so it gets a lower-case-dashed name. Among my 5 top tips for beautiful markup is use markup patterns consistently; extending this concept to id and class values is a natural evolution.

From Convention to Common Code

Ultimately, the naming convention you choose doesn’t matter as much as sticking to it does. However, obvious conventions are easier to pick up quickly, so one way to test your name is to try speaking your code aloud as though it were English. Does the grammar of the name you chose make sense when you hear it, or does it sound awkward?

Consider the form field. In English, it might read: “The widgetco-search text input is a SearchField. It lets you Find a Widget.” This makes grammatical sense, and both the class attribute’s “is a” relationship, as well as the id attributes “the” designation is made clear.

More to the point, you already know that an element with a class of Skyscraper is probably going to be using relatively widespread and standard presentations and behaviors (and indeed, a Skyscraper is an IAB standard web advertisement format), while an element with a class of wonderful-sale probably isn’t. And since you know this instantly, you can more confidently segregate your custom code from reusable reusable components in an organic way.

  • Chris McKee

    Cant say I agree with mixing cases within a css document; its an unnecessary level of complexity for future developers to grasp.

    • I agree. CamelCase and hyphens make ID and class names easier to read, but it’s at the expense of coding speed. It’s too easy to mistype the idname (or is that IdName, ID-Name, or id-name) in CSS and JavaScript.

    • If you have a strong convention for why you do it, what about mixing cases inherently makes it more complex?

    • arts-multimedia

      Spot on, Chris.
      I use Camel Casing only for variables in php, not in html or css because it indeed can lead to problems.

      • So, I’m still sensing that a lot of people are uncomfortable with this suggestion “because it indeed can lead to problems,” but other than suggesting typos, no one’s been clear about what the potential drawbacks can be. And I’m just not really afraid of typos, frankly, because they creep into code all over the place all the time, and they get fixed just as quickly! :)

        On the other hand, I feel like the benefits of improved code organization and developer communication have been made clear. Dorsey provided a good example of why this idea is not unique. So what makes the web the red-headed stepchild of the computer science world to the point where tried-and-true methodologies like naming conventions in other fields are rejected by web designers?

        Can anyone explain that to me? Please? Thanks. :)

  • zeemidesign

    Interesting idea to distinguish site-specific and “global” ids/classes, but I agree with some of the previous commenters – it might get confusing to mix hyphens and camelcase.

    I guess once html5 is more commonly used the much more specific tags such as nav, section, aside, footer, etc. will actually fill exactly that hole and define these global elements

  • Ulyses

    Bringing order in a world of chaos. But…


    Minimize uses of class and id attributes
    One benefit of patterns that can be easily overlooked is that—when they’re well designed—they radically improve the structure of your markup. This, in turn, reduces the need for you to use IDs or classes in elements in order to style them, which keeps your markup leaner. It also keeps your style sheets easier to understand, since your CSS selectors will use the structural context of the markup to provide the same context in CSS files.

    In fact, avoiding IDs and classes all together can be a very instructive exercise. If your markup is well structured, then you can achieve a surprising amount of the styling you need to using the humble descendant combinator. As support for CSS selectors that use structural context improves (like :last-child, and :only-child), the need for arbitrary styling hooks is further reduced.

    So, which is it? I’m guessing a little of both?

    • So, which is it? I’m guessing a little of both?

      Sure, that’s one way to say it, Ulyses. Certainly “minimizing” ID and class names doesn’t mean omitting them entirely. That would still be “a very instructive exercise,” but there’s a reason why IDs and classes exist and I wouldn’t argue for their total removal.
      I think the idea of conceptually segmenting “kinds of” IDs and classes through naming conventions, as discussed in this post, is simply another way to “improve the structure of your markup” and “keep your style sheets easier to understand,” since your CSS can use the naming conventions you’ve come up with to signal more about what’s going on.
      What do you think?

      • Ulyses

        I guess you’re headed towards OOP in HTML and CSS. And not just you.

        But, html is simple&easy and there is the key to success. Too much order could mean different specs (see XHTML). One spec for a different occasion.

        And this is the road to hell. I believe some of the mistakes made in XHTML are happening againg in HTML5 with this classification. IF we wanted a hybrid between Word and Media Player…

        But a html document does not need elements like nav or footer. These are just “the vicar of bray”, opportunists in a road towards freedom.

        So I believe in a human society where we each have diferent names, as our parents choose. Templates should be enough when repetition is needed. Otherwise, OOP. For HTML and CSS. There goes the world as we know it.

  • Many years ago, I worked on a large multi-developer project in C (not a web site) that was backed by an equally huge database. One of the things we all agreed on early was to adopt – and more importantly follow! – variable naming conventions. In those days, underlying data types were more important than they are now with automatic typing and casting, so you really had to know if a DB column and corresponding variable was an integer (short or long), a real number (single or double precision), a date type (date or time or both), or a string.

    Using a simple convention such as i_Inventory told us that the variable represented an inventory count in the range +/-32767. Subsequently, I read about (but never used) a convention that added an abbreviation like str, int, flt, dbl, et al to the beginning of each variable for the same purpose.

    Once you learned the “language”, it was much simpler to convey your intent and understand an author’s intent. It was also easier to spot data-related bugs, too. We enforced the naming convention for the DB columns and didn’t rename variables unless it was absolutely necessary. I recall that during code reviews and design sessions using a whiteboard, it really helped to all be singing from the same sheet of music.

  • I love seeing the Rockstar analogy applied to various minutiae of web design. Looking forward to How to file your bank statements like a Rockstar and How to check your spam folder like a Rockstar :)

    • How to indent your source code like a Rockstar? :)

  • vinit

    Well I always go with camel case for any name. There is no categorization further.

  • liberalcoder

    To each his own.

    Stick to one convention.

Get the latest in JavaScript, once a week, for free.