CSS `do-*`

By  on  

For years we've used CSS classes as not only stylistic functionality but also as signifiers or "triggers" for JavaScript functionality.  For example, Mozilla uses a #tabzilla element (coupled with a JavaScript file that looks for it) to inject the Tabzilla widget.  Using #tabzilla is nice, and even though it's an ID, it isn't necessarily descriptive.

Now cut to cases where there isn't an ID, and you're triggering JavaScript functionality solely based on a CSS class.  You could add a CSS class signifier like highlight-me or login, but when you try to maintain the HTML, those classes area relative mystery.  What I propose is a system by which we add a do- prefix to any CSS class that is implemented solely for the sake of JavaScript functionality.  A few examples:

<div class="do-launch-login">...</div>

<a class="do-close-modal">...</a>

<input class="do-autocomplete" />

So I'm not proposing anything groundbreaking and hopefully you already have a system in place, but if you don't, you should consider a do- or likewise system.  The days of using generic CSS classes are over and a class prefix like this will help you quickly identify if a class is relevant to styling or simply implemented for the case of identifying elements for JavaScript functionality.

Again, this probably seems like a simple idea and exercise but it's an important practice.  If you open a HTML template, look at an element, and have no idea if it's used for JavaScript or not, you're possibly in for a world of hurt.  And the word "possibly" should be scare the hell out of you.

The prefix isn't important as long as you keep one.  As long as you keep a className that you can immediately identify as JavaScript-only, you'll be in good shape!

Recent Features

  • By
    39 Shirts &#8211; Leaving Mozilla

    In 2001 I had just graduated from a small town high school and headed off to a small town college. I found myself in the quaint computer lab where the substandard computers featured two browsers: Internet Explorer and Mozilla. It was this lab where I fell...

  • By
    Camera and Video Control with HTML5

    Client-side APIs on mobile and desktop devices are quickly providing the same APIs.  Of course our mobile devices got access to some of these APIs first, but those APIs are slowly making their way to the desktop.  One of those APIs is the getUserMedia API...

Incredible Demos


  1. We’ve been using a similar scheme at my workplace for a while now, they only difference being that the prefix we use is js- instead of do-. It certainly feels as though this convention has saved us a bunch of headaches since we started using it.

    • js- also stands out quite a bit!

    • I’ve been doing something similar using a js- prefix too. The only time it gets a bit confusing is when using JS to add state-based classes – should those also be prefixed? Should the prefix be the same?

      Perhaps a do- class for attaching JS functionality and a js- prefix for classes added from the JS eg. do-tabs and js-tab-is-active perhaps?

    • Your mileage may vary, but we’ve been using “js-” for functional code and “is-” for state classes (that can affect styling) which will be added and removed by JavaScript.

  2. We did something similar at the company I used to work for that has the Nikon Americas contract. We added evt- in front of CSS classes that were for triggering events.

  3. We use js- too. Also found it has the advantage of people working it out intuitively who didn’t know we were doing it in the first place.

  4. Scott Swabey

    We have been using similar prefixes for a while to indicate “functional” classes, but have recently switched to adding these indicators as data attributes, e.g. data-do-widget.

    This has the immediate benefit of cleansing the class attribute of non-class elements, and is more semantically accurate.

  5. bp

    What about a class that is used both by JS and for styling? Do you suggest adding two classes in that case?

    • Jerry

      We then use two classes in our team

    • Albert

      Yeah, we are using two classes, e.g. js-nav-open and nav-open

  6. I use dataset for this.

  7. I use dataset for this, though not exactly in the same way. It could very easily be made to work like this though.
    My example is for data-close, but it could easily be data-request instead containing a URL for your ajax function to load from.

        var btns = document.querySelectorAll('[data-close]');
        for(var i=0; i < btns.length; i++) {
            btns[i].addEventListener('click', function() {
  8. Bob Walsh

    How about using data attributes instead?

  9. Kevin Vandenborne

    We use js-

  10. Kevin Vandenborne

    We use js- here at work too, it’s a lifesaver. Prevents other people from removing classes that have no style, they’ll know it’s for javascript purposes by looking at it. Everyone should use something like it!

  11. Antonin

    Hi there!

    Wouldn’t it also be viable to use a custom data attribute like


    It would nicely separate stylistic and JavaScript functionalities.

    Is there performance, semantic or compatibility issues?

    • Schadeck

      I just started using this same idea recently. But I set it up so I can throw multiple potential functions in there by parsing the data trigger:

      data-trigger="jsFunctionOne jsFunctionTwo";
  12. McBenny

    I’d go for something closer to js- than do- because event hough javascript bound to an element is always to DO something, most of the time you “bind” an element, you watch it, and in this situation, do- seems a bit odd to me. I’d prefer watch-, but it’s a bit long.

    I agree that js- is language-dependant btw.

    • Steve

      Agreed. This prefix idea is interesting but “do-” seems like a very poor choice as it will rarely if ever make any sense in context.

  13. Why not use data attributes?

    Having a single attribute for all your behavior related thingies makes things even more concise. For instance data-module="autocomplete"?

    • Using data attributes tend to be a performance hit when compared to classes and ids. Of course, if it doesn’t matter I prefer to use data attributes as well.

  14. Yes I use the js- prefix as well which came from:

  15. I’ve been using classes only for CSS and IDs for JavaScript. It’s not perfect but has worked for 95% of the situations I’ve come across.
    *95% is not a real stat :)

    I do like the do or js prefix though.

    • Okay, I missed the big use case in which multiple elements trigger the same event and classes are needed. Then this is huge.

      <a href="..." rel="nofollow" class="muted js-close-module">...</a> (or 'do')

      I like that a lot.

  16. Red Feet

    Off topic:
    I suggest a similar approach for classes that are influenced by media queries as well. Or is there already a well known pattern in place?
    I mean something like:

    Long desc
    Short desc
    • Red Feet

      I meant:

      <div class="mq-wide-show">Long desc</div>
      <div class="mq-narrow-hide">hide me on narrow screens</div>
  17. Diego C.

    In this cases I also use data-js or something similar.

  18. Same here, I use jquery-* for years (depending of which library is triggered). That’s a good practice.

  19. Jeff

    We’ve used js_ for a few years now, it’s been a real life saver. Early in the project the interaction developers were tripping all over the designers and vice-versa. We’ve had a few conversations about switching to data attributes, but thus far most of the team is happy with the current solution.

  20. I use .js-*

  21. This is really a simple and awesome practice. I believe that using -js would affect the characteristic of application scalability, theoretically fixing bindings only to JavaScript… Anyway, -do would be more appropriate for this.

  22. Prefixing class names with js-, do-, or whatever is terrible practice. In properly semantic markup, a class indicates what an element is, not what it looks like or behaves like. And what an element is may have to do with behavior, styling, or both. If both CSS and JS need to act on the same set of elements, then they should use the same selector.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!