Namespaced HTML classes

Florens Verschelde

Let’s say you’re releasing some library or library-ish code which makes use of HTML classes. You want to allow users of your code to just put a given class somewhere and get a specific result.

How do you make sure that the CSS code from your lib doesn’t clash with CSS code from other libs or from the website? If you write:

<div class="some-option big alternate"></div>

Then it’s way too likely that some code you don’t control will have declared styles for those class names already. Especially if the option names you use are common words.

How do we prevent that? I can think of a few possibilities, but I have no idea which is best.

Prefix all the things

Typically you would use a prefix in your classes:

<div class="mylib-some-option"></div>

But as users combine different classes that you offer as options, this can become quite verbose:

<div class="mylib-some-option mylib-big mylib-alternate"></div>

End users are also more likely to forget a prefix in one of those classes and wonder why it’s not working.

Prefix redux

You could use your “namespace” (yeah that’s not really the definition of a namespace but you get it) only once:

<div class="mylib some-option big alternate"></div>

And in your CSS code:

.mylib.some-option {}
.mylib.big {}
.mylib.alternate {}

But this only makes sure that your CSS code doesn’t messes up somebody else’s content, it doesn’t protect your content from other people’s CSS. So it’s not really a solution.

Using a custom attribute

For the ReMarkdown rewrite I decided to abandon HTML classes, and use a custom HTML attribute instead. Which goes like this:

<div data-mylib="some-option big alternate"></div>

You get total separation from other people’s code, including JavaScript code that may change or reset the element’s className.

You will need to use the [attr~=value] selector, which works similarly to the class selector. (For the record, .myclass is equivalent to [class~=myclass].) Arguably, this makes your selectors a bit more verbose and harder to comprehend for beginners:

[data-mylib~=some-option] {}
[data-mylib~=big] {}
[data-mylib~=alternate] {}

One drawback is that you lose the benefit of element.classList (IE 10+) or of the equivalent jQuery methods.

A composite class

This idea is a bit quircky so I haven’t used it anywhere yet. Basically it’s asking end users to compose a string with the options they want:

<div class="mylib-someoption-big-alternate"></div>

That string must start with the lib’s prefix, options are joined with hyphens, and the order of options doesn’t matter.

Then in your lib’s CSS, you would use such selectors:

[class*=mylib][class*=-someoption] {}
[class*=mylib][class*=-big] {}
[class*=mylib][class*=-alternate] {}

Which does make your selectors somewhat arcane (and longer).

Note that it could also match classes from other libraries, so that’s a risk:

<div class="mylib-someoption-big-alternate
            otherlib-small otherlib-otherstuff">
</div>

This would match your selector for a small option:

[class*=mylib][class*=-small] {}

And you also lose support for HTML class-wrangling utilities (e.g. element.classList.remove('mylib-small')). So it’s probably not worth it.

What’s your solution?

If you use a different solution or want to share what you use, chime in at @fvsch. Cheers!

Update