Making CSS/HTML readable — BEMIT it?

CSS can be a mess. HTML can be a mess. Naming things is a pain in the arse. Standardisation can help. BEMIT can help.

As an example, if some idiot* was making the youtube homepage without knowing others would read their code, each video displayed could probably be called a “card”. In that card, there would be a image, a title, a creator and maybe some stats with views, etc. So let’s call it “details” and then each underneath it could take the names “image”, “title”, “creator”, etc. But we add another section at the bottom which has channels you may want to subscribe too. That has an image, a title, a creator and some stats. Well… crap. Our naming will make our CSS overlap.

Maybe we put a prefix on it to state where it comes from? And if we all do the same then I will be able to read yours as easy as you can read mine!

What’s BEMIT?

Woah there, let’s do BEM first.

What’s BEM?

Woahhh there… just kidding.

BEM stands for Block, Element and Modifier:

  • Block is a thing
  • Element is a thing in a thing
  • Modifier is a thing of a certain type required to be displayed differently

So how does that fit into our example:

  • A Block in our YouTube example would be the card.
  • An Element in this example would be the image or the details.
  • A Modifier in our example is whether it is a video card or a channel card or maybe a small card or a big card.

Okay so I think the way we classify things are clear, let’s talk about notation before we go further.

/* in CSS file */.block {}
.block__element {}
.block--modifier {}

Or in our example:

.card {}.card--video__image {}
.card--video__details {}
.card--channel__image {}
.card--channel__details {}

Why is this better? Well it removes ambiguity. Let’s look at the above without BEM:

.card {}
.video {}
.channel{}
.image{}
.details{}

It becomes a little confusing.

If you went for explicitly naming things it could help :

.card {}
.car-channel {}
.car-video {}
.card-channel-image {}
.card-video-image {}
.card-channel-details {}
.card-video-details {}

But I may struggle to know that card-video is not a video but in fact the name of the element. Also I have no idea that card-channel and card-video have some cross-over CSS. Oh, and what happens when you have a two word descriptor like “watch later”? Do I now have to use camel case? watchLater. Do I use a dash as well? card-video-watch-later.

Also what happens when we accidently name things, which are completely different, the same name — like having multiple “body” or “main” elements. In the above we may then get confused about what elements they actually refer to.

In short, the way we name things in CSS, especially when we are learning or have been working on our own for a while, can cause big issues and time wasting when we work in larger teams. Having rules, guidelines and a common language in our code helps and BEM and BEMIT are two guidelines.

Okay I get it. But what about when you having blocks in blocks, etc.?

Yeah now this is where it gets messy. You need to ask yourself a few questions.

  • Does applying the naming convention here actually help understand where it is?
  • Will this styling be used in other places?
  • Is the styling unique?

These could potentially be opinionated answers so BEM is no silver bullet, but it does help from having no structure before. Remember also that the name you use doesn’t have to be the only thing you name the html element. You can apply multiple class’ names and should as this will reduce repeated code.

Right so BEMIT?

BEM is so 2013. Essentially people have criticised BEM for only showing relationships between parents and child (blocks and elements). It doesn’t actually show what is reusable. This has become a more prominent as frameworks like React have gained popularity as they are designed to rely heavily on building code like lego pieces — having small reusable elements of code that work together to build bigger bits.

BEMIT wants some extra prefixes and suffixes to help instantly show a developer what does what.

The Prefixes

The prefixes focus on understanding what function the element has:

  • c- stands for Component — potentially made from objects or just used occasionally
  • o- stands for Objects — reusable and commonly used (think a button design)
  • u- stands for Utilities — generally applied CSS
  • is- \ has- stands for State — I am not going to get into .this.

These mean we can instantly look at the JS, HTML or CSS and understand the function of the components. Note that there is no unified practice hence, just like BEM, there are multiple thoughts, versions and changes. BEMIT is just one.

Now I hear you cry, “isn’t this all a bit much?”, and I would tend to agree for hacky or personal projects. For example, if I am hacking a site together quick do I really need to create a utility class for something like display:flex when I could just add that to things that need it.

Now though, think about a larger company looking after an e-commerce site. The site is constantly changing, add new ways to look at the products, changing products, adding features moving layouts etc. Plus there are 20 people looking, changing and trying to work together. Now BEMIT seems more helpful. You are writing some html and you know what you want it to look like and you know the CSS is already made and is robust. Potentially you won't even need to go into the CSS file and instead style from class names! Now you have some robust and readable code.

There are two BEMIT notations I have avoided on purpose (as well as a few that I won’t mention).

  • _ stands for a hack
._c-footer--mobile {
height: 80px;
}

See from that example you already know that someone has hacked together a component for the mobile footer. We are learning!

Back to business. The hack notation.

Hacks are ugly — give them ugly classes. Hacks should be temporary, do not reuse or bind onto their classes. Keep an eye on the number of Hacks classes in your codebase. (https://csswizardry.com/2015/03/more-transparent-ui-code-with-namespaces/)

Harry from CSSWizardry is a good person to follow for this and is the true expert — I am just reading and trying to understand his work.

Essentially the hack BEMIT notation is a release valve for devs under immense pressure. Pressure has built and built to the point that we have found a fix but it can not be completed properly and we don’t have time. Refactoring code is necessary for this. The business may not like it as refactoring is essentially redoing work for no change in function. Hence the business feels like it is paying twice. The product owner doesn’t feel like refactoring is helping add value to the customer. All of this has some truth on the surface, but there is also benefit. Any refactoring change is to make things easier. It will help allow add features quicker, fix problems quicker, etc. It is like sharpening knives in a restaurant. The customers don’t care, but spending the time doing it could help some of the things that the customers do care about — speed for example. The decision isn’t to refactor or not, it is when is the best time too.

  • js- stands for …(*drumroll*)… JavaScript

Essentially it is meant to separate behaviour of an element due to styling (CSS) and behaviour due to action (JS). This separation makes things reusable. Atomic form should be strived for. Again a word from Harry:

…a developer had built a text-callout UI component that had a distinct appearance, and some behaviour to fade text in and out of it. A Product Owner asked that we reuse the same piece of UI elsewhere, but we didn’t need to fade multiple pieces of text in and out; it was just going to say the same thing all the time. Because the component had been built with JS and CSS binding onto the same hook, it meant that I couldn’t have a configuration of the component with its look and feel but without its behaviour. It took a chunk of refactoring to fix, and it could have been avoided simply by binding onto separate hooks.

A js tag would have saved this. One issue with this is that it uses class names instead of id names to target JS. In my development history I have justed the getElementById() more often than getElementsByClassName(). Because of this I would tend to target js by Id but that doesn’t mean that the code is readable. In any business setting, make sure you know what your team do.

The Suffixes

I said there were two parts to BEMIT. I know it is long. I am sorry.

Breakpoints are interesting. Essentially a breakpoint is a way to change how the display looks dependant on screen size. If the width is more than/less than/between X pixels do this CSS on top of what was above. This is helpful for better user navigation but does introduce further complexity. BEMIT takes aim at making changeable CSS more obvious. The same logic also applies to printing as it is considered a media view.

For example, if you are adding a component and notice that every other component has a class name of u-hidden@print you may think, “wow all of these have a utility class which hides them when a user prints” and then may simply add those 14 characters and BOOM. CSS applied as it should be.

Is there anything else?

Yeahh, if you use a text editor with autofill, this consistency in naming will become baked in and it will start suggesting things that will help structure your class names more consistently.

Also Harry notes that you can then highlight areas quickly. Want to know how many components there are on a page and where they all sit? Simply:

[class^="c-"],
[class*=" c-"] {
outline: 5px solid cyan;
}

Honestly, read his post — it is gold. https://csswizardry.com/2015/03/more-transparent-ui-code-with-namespaces/

The Summary

So BEMIT is BEM plus a few other things. BEM is essentially labelling. BEMIT is essentially more labelling.

BEM labels block, element and modifier.

BEMIT adds labelling for components, objects, utilities, state, js and hacks.

One last thing:

In my travels reading up on this I found this which I will be using from now on to structure my CSS:

/* Project Meta */

/* reset */

/* general */

/* typography */

/* grid */

/* header */

/* footer */

/* Page template A */

/* Page template B */

/* Media Queries */

*me

Focused on saving our time: everyhour.xyz for your life balance; tree-meals-a-day.earth for our food emissions and compairbnb.info/hello for booking airbnbs.