A few weeks back, I put out a
Tweet to a
jsFiddle describing an idea I’d had in
which I grouped two or more related class attributes to make them easier to
notice when scanning an HTML file, and—coincidentally—trivial to manipulate very
effectively with Vim, my text editor of choice.
I was grouping them by enclosing them in square brackets, and that looks
something like this:
Since sharing the demo, I’ve used this method on a few builds, and people on Twitter have asked me about the presence of
the brackets, so I thought I’d write it up into a full article. Before we get
into things too far though, there are a couple of things I’d like to say up
front.
Firstly, after I shared the link to the jsFiddle, I got a few replies about a
much earlier method along similar
lines
from Ben Everard, so the idea of visually separating classes isn’t all that new. Where this method differs, however, is
the concept of grouping them, as opposed to just delimiting them. More on that
later.
Secondly, and more importantly, this article is not a direct endorsement of,
or recommendation for, this method, this is just a writeup of an idea. It has
benefits and drawbacks—as do most things—so your mileage may vary. I will
discuss relative merits and pitfalls later in the article so that you can decide
whether this is a good thing for you, rather than it being a good or bad thing in and of itself.
There is no hard and fast rule as to how and when to begin grouping your
classes, but the guidelines I’ve set for myself are:
There must be more than one ‘set’ of classes.
One ‘set’ must contain more than one class.
This basically just ringfences any groups that need it, for example:
If these rules seem a little convoluted—and they might—feel free to experiment
with your own. You could simplify it right down to ‘any groups always need
enclosing’, like so:
How you group them can be entirely your choice, the concept here just deals with
the fact that we’re grouping things at all.
It’s important to note here that I’m using BEM-style
naming,
which already starts to group classes anyway. If you’re not using BEM, your HTML
might look like this:
We can see here that the classes .box and .promo-box are related, and
.sign-up is an orphan, for want of a better word.
Scanning your code
Featured case study: NHS
How I helped the NHS rapidly build a brand new product.
Read case study…
I’ve long been a vocal advocate of using more classes in your
markup:
it just makes for more pragmatic, manageable, scalable development. It does,
however, make your markup a little heavier. This is a small price to pay for the
advantages that a nicely decoupled, single
responsibility
UI, built on a well-abstracted, highly composable codebase brings, but it’s
always nice to try and mitigate the effects of more verbose HTML. I feel that it
would be nice to have the best of both worlds (hence my proposal for
Naming UI components in
OOCSS),
so I’m constantly looking for ways to try and keep an even balance.
BEM
is already an incredibly solid start in making your HTML a lot more transparent:
having namespaces in your classes paints a really clear picture of which classes
are related to one another, if at all. It leaves you with highly descriptive
markup that is simple to work with and debug.
One of BEM’s key strengths is its scannability, and, to my mind, there are two
levels of reading code: the first is actually reading it, taking it in, learning
what it is doing; the second is scanning it, which is a really high-level look
over some code, perhaps to find something, perhaps to just give it a once-over
to check its general sanity, or just poking around. I often feel we put a lot of
weight on the former—reading code—and nowhere near enough on the
latter—scanning it.
What I find the square brackets offer me is a very visual way of absorbing (i.e.
scanning) an HTML page. The square brackets become very apparent—very
noticeable—when giving some code a very high-level read, so I can very easily
spot composed patterns without having to get too involved in the code itself.
Vim
Another absolutely huge benefit of grouping classes inside something (rather
than just delimiting them with something like slashes or pipes) is that you can
begin to manipulate them with certain text editors (my editor of choice being
Vim).
Using commands like ya[ (yank around square-brackets), ci[ (change inside
square brackets), da[ (delete around square brackets), we can, respectively:
copy everything inside the square brackets, including the brackets themselves;
change everything inside of the square brackets, leaving the square brackets
intact; delete everything inside of the square brackets, and delete the square
brackets as well. Once we’ve done this, we can then go and put (paste) the
copied groups elsewhere.
This means that I can modify, duplicate, move, delete, and generally manipulate
entire groups of classes very rapidly. Powerful stuff, particularly if—like
me—you like to work by composing UIs and patterns in your HTML (think grid
systems, OOCSS, etc.).
I made a very crude screencast of this in action—all commands are done without
needing to reach for a mouse, or nudging around text-selections whilst holding
the Shift key.
Working with grouped classes inside of Vim.
However, this feature is a combination of Vim’s power and us leaving handy
markers for Vim to work with. If you aren’t using Vim, or a similarly powerful
text editor, then these benefits will not be quite so apparent. If you fancy
learning Vim—and I really would recommend it—simply open your terminal and run:
This will give you a really easy-to-follow, well-paced introduction to Vim.
Validity
Using square brackets in HTML’s class attribute is completely valid. In fact,
where HTML is concerned, class attributes can legally contain any character
at all. From the HTML5 spec:
There are no […] restrictions on the tokens authors can use in the class
attribute…
In CSS, however, the [ and ] characters are invalid in a class, unless it
is escaped. That is to say, this will not work:
However, this will:
Using square brackets in your class attributes is valid, and won’t trip browsers
up (I’ve tested this personally in browsers as far back as IE7–8).
As we shall see next, though, this being valid does not free us from the chance
of errors occurring.
Errors
As I mentioned previously, however, this method is not without its drawbacks, so
please take these—and your own
context—into
account when considering adopting it.
The first possible pitfall with this method of using square brackets to group
your classes is that it becomes a lot more easy to introduce errors. Traditional
classes are pretty difficult to get wrong. In fact, nine-times-out-of-ten, the
only way you could get a non-matching class would be a simple typo.
When introducing these square brackets, however, we are also introducing a huge
potential for error. Whilst the following is perfectly valid, and will work just
fine:
Making a mistake by writing the following will invalidate things completely:
This is something to be wary of, because .foo--bar and .foo--bar] are two
very different things. This becomes even more of a problem in situations
where:
You’re writing classes to the view dynamically. If you have templating
logic in your markup, it can often be hard to see where these errors might
occur, and they also become harder to debug.
You have team members unfamiliar with the convention. Seeing something
like this may well be confusing to a developer who’s never used it before, so
it is possible that they won’t understand the caveats required for it to work.
One response I’ve had more than once is the concern with more bytes over the
wire. This is something of a non-discussion, but I’ll address it anyway: if
you really care about class-attribute bytes over the wire, you should be using a
CSS obfuscater like Google’s Closure
Stylesheets.
Crunching raw HTML bytes is a job for a tool, not a developer.
Teams
One of the main drawbacks of this method is its use in team environments, which
is quite ironic considering my work centres a lot around managing codebases in
teams.
The first and foremost—and most obvious—issue is the fact that it needs
explaining at all. The fact I’ve managed to get a few-hundred-word article out
of this may be testament to its unusual and potentially confusing nature.
This will always the case when adopting new methodologies—like BEM, for
instance—but it is an overhead that cannot be ignored. The existing team will
need to learn and be on board with this grouping methodology, and any new hires
will also need teaching. It’s another hurdle; a small one, but definitely
another.
JavaScript
As Todd Motto pointed out over
Twitter, this method
may have some impact on JavaScript interacting with your classes. I only
ever bind onto .js-* classes, so these would typically never get grouped, but
you may hit problems elsewhere. Again, your mileage may vary.
Todd did follow up with:
Adding classes is okay, even with ‘nested’ grouping […] if you’re using
.js-* then you’ll be fine.
To use, or not to use?
This is entirely up to you. I’ve been using it on all builds recently, and I’m
really liking it. It has been alien to other developers I’ve been working with,
but I’ve been able to explain it, and I have had one incident of
dynamically-generated classes breaking.
Because I use Vim, I really do get a lot of use out of this, and because I’m a
vocal advocate of using more classes, it helps me spot and manage them in my
markup.
By Harry Roberts
Harry Roberts is an independent
consultant web performance engineer. He helps
companies of all shapes and sizes find and fix site speed issues.
Get started…
Hi there, I’m Harry Roberts. I am an award-winning
Consultant Web Performance Engineer, designer, developer,
writer, and speaker from the UK. I write, Tweet, speak, and share code about measuring and
improving site-speed. You should hire me.
Connect
Projects
Next Appearance
I help teams achieve class-leading web performance, providing consultancy, guidance, and hands-on expertise.
I specialise in tackling complex, large-scale projects where speed, scalability, and reliability are critical to success.
I am a passionate blogger with extensive experience in web design. As a seasoned YouTube SEO expert, I have helped numerous creators optimize their content for maximum visibility.