CSS `do-*`
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!
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 ofdo-
. 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 ajs-
prefix for classes added from the JS eg.do-tabs
andjs-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.
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.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.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.
What about a class that is used both by JS and for styling? Do you suggest adding two classes in that case?
We then use two classes in our team
Yeah, we are using two classes, e.g.
js-nav-open
andnav-open
I use dataset for this.
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.
How about using data attributes instead?
We use
js-
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!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?
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:
I’d go for something closer to
js-
thando-
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 preferwatch-
, but it’s a bit long.I agree that
js-
is language-dependant btw.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.
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.
Yes I use the
js-
prefix as well which came from:http://ozmm.org/posts/slightly_obtrusive_javascript.html
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
orjs
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.
I like that a lot.
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:
I meant:
In this cases I also use
data-js
or something similar.Same here, I use
jquery-*
for years (depending of which library is triggered). That’s a good practice.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.
I use
.js-*
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.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.