How to write better CSS with BEM

More recent posts can be found on medium.com/@devbyrayray

Raymon S — October 03, 2017

This blog and video are especially for Developers who want to optimize their CSS. It is very important to have readable CSS, for your teammates and yourself.

It will help you and your team with developing the website or application further at a later moment.

In my opinion, the CSS naming convention BEM is the perfect way to write your CSS classes and selectors better than before.

If you like a visual example of how I would change my already CSS developed to the more readable BEM, please check out the video.

If you are more a person to read, please follow the text below

https://youtu.be/ah1qRTWVVjY Video notes Example website

For this example I used a Bootstrap theme, you can download the Business theme for free.

Sublime Text

In this editor I used the Sublime Text editor. You can download it for free. If you want to a real pro with Sublime Text, please check out the course/book of our friend Wes Bos.

Detailed BEM information

If you want to read the BEM documentation, please check it on the BEM website.

In my video, I showed a detailed blog post about BEM on the CSSwizardy website.

Let's get into the code ! Step 1: HTML & CSS how we learned it When you learn to write CSS, it would be something simulair to this:

HTML

& lt ; nav & gt ; & lt ; ul & gt ; & lt ; li & gt ; & lt ; a & gt ; Home & lt ; / a & gt ; & lt ; / li & gt ; & lt ; li & gt ; & lt ; a & gt ; About & lt ; / a & gt ; & lt ; / li & gt ; & lt ; li & gt ; & lt ; a & gt ; Blog & lt ; / a & gt ; & lt ; / li & gt ; & lt ; / ul & gt ; & lt ; / nav & gt ;

CSS

nav { height : 60 px ; max - width : 1024 px ; } nav ul { margin : 0 ; padding : 0 ; text - align : center ; } nav ul li { display : inline ; } nav ul li a { display : inline - block ; padding : .5 em 1 em ; }

Analysing the HTML & CSS

If you analyse the HTML and CSS we see the following.

Structure with only elements

No class names

Multi level selectors

When I started with Frontend Development, this was the way I was told to write it.

Maybe you won’t see the problem, but at the end of this blog you will know it for sure!

The problems you will discover with this (in the video you will see it):

If you will use the same HTML somewhere else, things will be messy if you change it here, because it will reflect everywhere! So it’s not scalable.

To overwrite the styling you will have to write very specific selectors with multiple levels or even whorse, use !important to overwrite.

This will cause a lot of bugs with big CSS files.

The CSS selectors are not explaining where you can find the HTML elements on the page. So it is not self-explaining.

Step 2: Optimise your HTML & CSS a little bit better When I had a few years of experience in Frontend Development my HTML & CSS started looking like this:

HTML

& lt ; nav class = “navigation” & gt ; & lt ; ul & gt ; & lt ; li & gt ; & lt ; a & gt ; Home & lt ; / a & gt ; & lt ; / li & gt ; & lt ; li & gt ; & lt ; a & gt ; About & lt ; / a & gt ; & lt ; / li & gt ; & lt ; li & gt ; & lt ; a & gt ; Blog & lt ; / a & gt ; & lt ; / li & gt ; & lt ; / ul & gt ; & lt ; / nav & gt ;

CSS

. navigation { height : 60 px ; max - width : 1024 px ; } . navigation ul { margin : 0 ; padding : 0 ; text - align : center ; } . navigation li { display : inline ; } . navigation a { display : inline - block ; padding : .5 em 1 em ; }

Analysing the HTML & CSS

If you analyse the more optimised HTML and CSS we see the following.

The CSS selectors are shorter

The CSS selectors have a less specifity

The CSS selectors contains some more context, but not the context that BEM could give.

If i needed to overwrite styling, it was still needed to add a few layers to my selectors by making it more specific.

Sometimes when working with CSS libraries/frameworks I still needed to use !important sometimes .

The selectors were not that self-explaining.

When I was at the point of Developing this, it was quite optimised for me, I thought . But it took me a few years to find out that I needed some more optimisation. Because there were still a few issues. Step 3: Using BEM to write better HTML & CSS When I discovered that browsers are reading selectors different than humans, it was like “what? huh?” . This was so new for me! I discovered that my CSS selectors were not that good as I thought.

So when searching for methods to take action and make the CSS selectors better, I discovered BEM. In the video, you can check out how I apply BEM on the CSS and HTML on an example website.

In this example you can see how the HTMl & CSS according to BEM will look like.

HTML

& lt ; nav class = “main - nav” & gt ; & lt ; ul class = “main - nav__list” & gt ; & lt ; li class = “main - nav__list - item” & gt ; & lt ; a class = “main - nav__link - item” & gt ; Home & lt ; / a & gt ; & lt ; / li & gt ; & lt ; li class = “main - nav__list - item” & gt ; & lt ; a class = “main - nav__link - item” & gt ; About & lt ; / a & gt ; & lt ; / li & gt ; & lt ; li class = “main - nav__list - item” & gt ; & lt ; a class = “main - nav__link - item main - nav__link - item—active” & gt ; Blog & lt ; / a & gt ; & lt ; / li & gt ; & lt ; / ul & gt ; & lt ; / nav & gt ;

CSS

. main - nav { height : 60 px ; max - width : 1024 px ; } . main - nav__list { margin : 0 ; padding : 0 ; text - align : center ; } . main - nav__list - item { display : inline ; } . main - nav__link - item { display : inline - block ; padding : .5 em 1 em ; } . main - nav__link - item—active { font - weight : bold ; color : red ; background : grey ; }

Analysing the HTML & CSS

If you analyse the HTML & CSS you will discover a class names on every element. Class names that are self-describing. You don’t need to look to a website to read where this component stands on page.

It declares for itself that it is the main navigation. All the list items and links will also directly give context for you and your team who are working on the same code.

Let’s check out if you fix the problems we saw before.

Now you can copy the HTML and it will stay intact. If you want to re-use the HTML, change .main-nav for “footer-nav” and you won’t see any inherited styling from the main-navigation. So this is perfectly scalable.

If you want to overwrite the styling of 1 or multiple elements, you only have to add another class name, just that simple!

Especially when you use a CSS pre-processor your Development structure will have a good architecture.

The CSS selectors and class names are self-describing. So it is easy to find now. It gives a lot more context than before.