The BEMIT naming convention
Giving this site a spring clean has been in my sights for some time. It's only when I take a look at the HTML and CSS (not Sass yet—that's pencilled in for later in the year) that I realise how difficult it is to organise and maintain, even on a small, one-person website like this. For example, there's a class that I simply called structure
. Structure of what? I obviously wasn't feeling generous towards future-me on the day I came up with that. It's going to take some digging to figure out what it's for.
On his CSS Wizardry site, Harry Roberts talks a lot about naming conventions and approaches to organising markup to keep it clean and maintainable, particularly for large teams. I'd like to spend the next few blog posts lifting the bonnet on CSS Wizardry, and this first post is about Roberts' latest innovation, the BEMIT naming convention.
Skip to navigationA distinguished pedigree
BEMIT is a concatenation of BEM, the block-element-modifier naming convention, and Harry Roberts' own ITCSS (Inverted Triangle CSS) approach to structuring style sheets. This video, Harry Roberts—Managing CSS Projects with ITCSS (YouTube), gives an in-depth account of his proposed method, and this article in Net magazine (issue #267, June 2015) also outlines it. So, what are BEM and ITCSS?
BEM: Who's your daddy?
Now that we're seeing more of a tendency to structure web content into patterns, rather than pages, the BEM model for naming seems to fit quite nicely. The principle is based on being able to identify blocks of content, such as the ‘Recent Posts’ teasers on the home page of this blog. We might call one of these teaser
.
Within this block, there will be related elements, such as the title of the article, the date it was published, a description of the content, and a ‘Read more’ link. According to the BEM model, we should name these using the containing block name, two underscores, and then the element name. This gives us teaser__title
, teaser__date
, teaser__description
and teaser__read-more
.
There might also be situations where a teaser needs special styling. For example, I might want the latest teaser to have a different background colour, or to say “New!” at the beginning. For this, BEM says I need a modifier, which I refer to with the block name, two hyphens and the modifier name: teaser--latest
.
So, the teaser for the post you're reading right now might have this markup:
I wonder whether all of these classes are really necessary. For example, if I want to style the heading within a teaser, I could use .teaser h2 {}
. Surely, I'll remember six months or two years down the line what .teaser h2 {}
is, right? I suppose the argument goes that, yes, the BEM approach might be overkill for a pissant little website like this one. But, if you're working on a large project with tens of designers and a high staff turnover, you need an idiot-proof way of referring to elements in your HTML and CSS. It may be perfectly obvious to me what .teaser h2
is, but it might not be obvious to that new recruit who's just blagged herself on to the team.
ITCSS: Who's your second daddy?
If we're going to use a naming convention like BEM, we should think about how we're going to keep all these elements and blocks tidy in our style sheets. I have an idea: let's organise it into typography, layout, colours and…er…misc, OK? Mmm. That might be fine for a small site like this (and as the guy who maintains this site, I can tell you there's nothing fine about it), but I imagine when you're working on a big project, this kind of arbitrary approach is quickly going to get messy.
Thankfully for dumbos like me, ITCSS puts forward an alternative. The ‘inverted triangle’ is a metaphor for the scope and specificity of elements in the style sheet. At the beginning of the style sheet, we want the big, global definitions, such as @include
s and other external, ‘admin’ links. After that, we want site-wide global styles, like * {}
and body {}
. Next, it's styles that effect common elements; this is where you define all the paragraphs in your site p {}
and all the links a {}
. Resets, if you worry about that kind of thing, presumably go in this position (you can read about the merits and drawbacks of CSS resets here, here and here).
Now we're getting more specific. Next comes styling for our reusable patterns. It's here that I style the elements I created above: .teaser {}
, .teaser--latest {}
, .teaser__title {}
, and so on. Then, I style unique elements, such as the site logo or main navigation: .logo {}
and .nav {}
. I suppose these are arguably “reusable patterns”, but they're unique in the sense that that they only appear once on any given page. At the bottom of the style sheet, we have what Roberts calls ‘trumps’, which are those grubby little styles that have !important
after them.
With ITCSS, instead of asking “am I styling the colour or the typography here?”, I ask “What's the scope of the element I'm styling?” If it's an element that appears everywhere on my site, such as a paragraph, I know it's somewhere towards the top of the style sheet. If I'm styling a pattern that only appears on one page, like my teaser, I know it'll be towards the bottom. Roberts argues that this kind of structure makes it far easier to maintain and collaborate on style sheets, especially when combined with CSS preprocessors like Sass.
I believe Harry Roberts is working on a book about all this, so watch this space. And this Twitter account.
Skip to navigationExtending BEM and ITCSS
With BEM and ITCSS, we have a set of guidelines that describe how to name classes and where to put them in a style sheet. This is probably enough for small-scale projects. But there are still problems to be solved. What about the scope of elements? A name like teaser
gives me an indication of what it does, but it doesn't tell me how important it is to the website as a whole. Maybe I know that it only appears on the ‘recent posts’ page, but does Jane Bloggs, who works on the other side of the world? And what about responsive web design? Occasionally, it's going to be handy to give a class to an element so that we can explicitly say what it does at different screen sizes. Again, it's not necessarily for me; it's for Ms Bloggs, who is a great designer, but not a mind reader. In BEMIT: Taking the BEM Naming Convention a Step Further, Roberts proposes extensions to BEM and ITCSS that address these issues.
Namespace prefixes
To address the issue of scope, Roberts suggests we use namespace prefixes. Does the element potentially appear on every page of the site? If so, it's probably an object, and should have an o-
in front of it. An example might be a block that contains a responsive image and its corresponding caption, which we give the class o-image
. Is the element repeated, but only used on one particular page, such as the teasers on the ‘Recent Posts’ page of this site? Then it's probably a component, and should take the prefix c-
, for example, c-teaser
.
Another prefix is u-
for utilities, classes which might be a bit ‘breaky’, but just make it easier to achieve certain results, such as centring text in a couple of elements (u-text-centre
). Further such class prefixes are t-
for themes; s-
for scope; is-
and has-
for temporary states; _
for outright hacks; js-
for classes which influence the behaviour of the element through JavaScript; and qa-
for styles related to quality assurance. The link above describes each of these situations in detail.
[Thinking more about this, it seems that component and object prefixes could go further. There are two questions we could ask about the scope of an element: how many pages does it appear on, and how many times could it appear on a given page? Thinking about the elements on a typical blog website, we could divide them as follows:
Appears on several pages, potentially several times per page:
- Subheadings (h2, h3, etc)
- Paragraphs
- Most inline elements (a, em, strong)
- Images, videos, audio players
- ‘Skip to’ links (see this post)
Appears on several pages, once on each page:
- Site banner, including logo and strapline
- Main navigation
- Main article heading (h1)
- Footer, including contact and social media links
Appears on one page, several times:
- Article teasers on the landing page of the site
Appears on one page, once:
- Contact form
- Photo of the blogger's head
How this fits in with components and objects, I'm not sure, but using an element's class to indicate its scope within this framework could be really useful on large projects.]
Anyway, what a great idea! Just by looking at prefix on a class, we can guess at the effect that tinkering with the styles might have on the site. If Jane Bloggs sees an element with an o-
prefix, she'll know to tread lightly. But if she sees a c-
prefix, she can fill her boots. This could save a lot of head-scratching when it comes to maintaining a site.
Responsive suffixes
The second way that Roberts suggests to extend BEM is to add a suffix, preceded with @
, which is targetted at media queries. For example, c-teaser@sm
gives us a hook to style my teaser block at small screen widths, while o-image@print
is a class that allows us to style an image object for print. One important point, the @ symbol has to be escaped in CSS, so you'd write it like this: .c-teaser\@sm {}
.
I'm not experienced enough as a web designer to appreciate the value of responsive suffixes. Say I want to style my teaser at smaller screen widths. Wouldn't this be enough?
Perhaps if we're being idiot-proof to the max, it might be necessary. I suppose simply by giving an element a class with a responsive suffix, we're informing the designer that something happens at this screen size, so watch out.
Skip to navigationRecap
Let's have a quick quiz. What do these three classes mean?
c-teaser--latest@sm
o-image__caption@print
u-clearfix
The first one is our teaser. Thanks to the c-
prefix, we know it only appears on one particular page. If we tinker with it, it's probably not going to impact the whole site. Also, it's not just any teaser; it's the latest. It will probably be styled slightly differently to the other teasers on the page. We also know that this class is to be used for styling the teaser at small screen widths.
The second class is a caption for an image. From the o-
prefix, we know it could appear on several pages across the site. The @print
suffix also tells us that this class is intended for styling the element in print.
Finally, we have a good old clearfix utility. Use this on an element to fix the layout after using floats.
Skip to navigationConclusion
BEM gives us a much clearer system for communicating the relationships between blocks and the elements contained within. It's semantic and meaningful, so it is standards-compliant. To summarise BEM:
- Blocks are HTML elements that are likely to contain other content which is related in some way. I'm thinking of things like cards or
<figure>
elements which contain an image and a caption. - Inside a block, you'll find smaller elements. These should be marked up with the suffix
__element-name
. - Some blocks are different to others of the same type, so they have a modifier. They are marked up with the suffix
--modifier-name
.
ITCSS gives us a system for structuring style sheets which makes it much easier to locate styles. By thinking about a style's scope, rather than its function, we can decide where to put it in our style sheet. This also makes it easier when we come back to it months later, or pass it on to a colleague.
BEMIT blends the idea of blocks, elements, and modifiers with the notion of scope. In summary:
- We can give other developers an idea of the scope of a element using namespace prefixes, such as
o-
for objects that appear throughout the site (so handle with care), andc-
for components that probably only appear once (party time). There are several other types of namespaces. - Finally, we can add an
@
suffix for elements that need particular responsive treatment, such as@sm
for small screen sizes (however your project defines that) or@print
. Just remember to escape it in CSS:\@
.
Used alone, a system like BEM or ITCSS can greatly improve the transparency and maintainability of our markup. Used together, they are extremely powerful indeed. And with BEMIT, we are giving designers and developers even more at-a-glance information about what styles are doing. The gains in terms of frustration avoided and time saved figuring out what classes do should be substantial.
Skip to navigationFurther reading
SMACSS. Very much an earlier iteration of ITCSS, Scalable and Modular Architecture for CSS, an approach to structuring CSS by Jonathan Snook, is worth a look. Like ITCSS, SMACSS advocates working with the cascade by using semantic class names and organising elements in a style sheet by scope. There is an earlier edition of the SMACSS book available to read online.
SUIT, by Nicolas Gallagher, is another CSS-structuring approach which focusses on semantic naming and good dependency management. There's a fantastic Related Reading section at the end.
Skip to navigation
Comments
comments powered by Disqus