DEV Community

Apiumhub
Apiumhub

Posted on • Originally published at apiumhub.com on

BEMIT: ITCSS + BEM

Introduction

In my previous article I discussed the advantages of using ITCSS to organize our styles, mainly for large projects where several people work. Its use will make our structure much more orderly and make the styles of our application more maintainable.

Having solved the problem of hierarchy and organization of our project, it remains to work on a nomenclature that will help us to have a self-documented code that is better understood. For this task it can help us to include the BEM nomenclature together with the ITCSS nomenclature. In this article we are going to approach BEMIT and what advantages it can offer us.

What is BEMIT?

BEMIT is simply BEM + ITCSS. Like BEM, it is a naming methodology to define the classes of the HTML nodes of our projects. The idea came from Harry Roberts himself, creator of BEM, and consisted of adding the ITCSS hierarchy system to BEM. Thanks to BEM, developers can know how classes are related to each other. If we look at the following code, we can have a pretty clear idea of how classes relate to each other.

<div class="footer">
  <div class="footer__brand-wrapper">
    <img src="" alt="" class="footer__logo round-picture" />
    <h2 class="footer__tittle">Brand Name</h2>
  </div>
  <ul class="footer__menu">
    <li class="footer __item footer__ item--active">Item 1</li>
    <li class="footer__item">Item 2</li>
    <li class="footer __item footer__ item--disabled">Item 3</li>
  </ul>
  <p class="footer __info footer__ info--gold">Lorem Ipsum</p>
</div>

Enter fullscreen mode Exit fullscreen mode

With this code snippet, we quickly know that footer, footer__brand-wrapper, footer__logo, footer__tittle, footer__item and footer__item–active are related to each other, while round-picture is a separate block. This information can help us to be able to make modifications or add new classes with more security. What is the problem? It does not give us a global view on how new rules behave, act or should be implemented or modifications on existing classes. It only gives us a relative view.

To increase the robustness of BEM, we use it in conjunction with ITCSS. We still keep the 3 types of classes: blocks, elements and modifiers, but we add information about their usage and state by adding prefixes and suffixes to them. This allows us to determine exactly what kind of work a class can do, how to use it and where to find its rules defined. We will see that these prefixes are closely related to the ITCSS structure we have in our project.

Prefixes

Roberts suggests that we use a series of prefixes to address the problem we have discussed.

  • c-. Prefix for Component. A component is always a BEM block, it is a concrete part of the interface. It is a very concrete implementation that will make any change safe and only affect that particular component, without negatively impacting others. No other node in the document will be affected. These are the most common and widely used classes. To see it more clearly, let’s convert the code of our footer with this new nomenclature:
<div class="c-footer">
  <div class="c-footer__brand-wrapper">
    <img src="" alt="" class="c-footer__logo round-picture" />
    <h2 class="c-footer__tittle">Brand Name</h2>
  </div>
  <ul class="c-footer__menu">
    <li class="c-footer __item c-footer__ item--active">Item 1</li>
    <li class="c-footer__item">Item 2</li>
    <li class="c-footer __item c-footer__ item--disabled">Item 3</li>
  </ul>
  <p class="c-footer __info c-footer__ info--gold">Lorem Ipsum</p>
</div>

Enter fullscreen mode Exit fullscreen mode

We would also rename the name of the footer file and the class in its corresponding scss (or css).

With this simple change, we know that the footer class is a component, which indicates that it is safe and modifying it will only affect that component. In addition it indicates us in which layer it is and in which file it is defined.

  • o-. Prefix for Object. These classes are reusable in the whole project in a generic way. This means that an object can appear in several places of our application and lack specific context, so it is risky to modify them. So, thanks to our -o prefix, we will know that if we are going to modify the rules of that object, several parts of our application may be affected. Actually, we are adding a prefix to our ITCSS objects to identify them and differentiate them from the components. For example, in the following form we have defined a class to center align the text, which is an object. We will have to rename it and do the same with the file and with the css code.
<form class="form">
  <div class="form__group">
    <label class="form__label">Choose a car: </label>
    <select class="form__dropdown">
      <option class="form__option o-ta-center">Volvo</option>
      <option class="form__option o-ta-center">Saab</option>
      <option class="form__option o-ta-center">Mercedes</option>
      <option class="form__option o-ta-center">Audi</option>
    </select>
  </div>
</form>

Enter fullscreen mode Exit fullscreen mode
  • u-. It is the prefix of Utility. They are quite particular classes, since they are neither blocks, nor elements nor modifiers. They are generic classes that provide some kind of utility and usually have a !important. Generally, once this class is created, it should not be modified. They are not mandatory and, in fact, if you do not have any in your project it would be even better.
.u-block {
  Display: block !important;
}
Enter fullscreen mode Exit fullscreen mode
  • t-. Theme prefix. There are times when we work with interfaces that offer the possibility of offering different themes, such as a light theme and a dark theme. These classes are not in a specific place, but accompany the class they modify and use a nested selector, gaining in specificity to the single classes. They are very specific, you will not see them unless your application has the functionality to work with different themes, but it does not hurt to know of their existence and usefulness.
c-btn {
  background-color: $main-color;
  color: $main-gray;
  display: inline-block;
  padding: 1em;

  &.t-dark {
    background-color: #main-color-dark;
    color: $white;
  }
}
Enter fullscreen mode Exit fullscreen mode
  • s-. Scope prefix (context or scope). These are classes that add context to a section of the application and are used to solve a fairly specific problem. A quite common example can be the html code that is entered by a user through an html text editor (such as WYSIWYG ). In this content there will be no classes that follow our BEMIT format, having to apply styles to the internal nodes with some auxiliary class that allows us to have access to them. We would thus have a segment of our code free from the rest of the system, but at the same time, controlled by the scope suffix. In CSS, these rules are defined within its own scope layer.
.s-editor-content {
  font: 16px;
  h1, h2, h3, h4, h5, h6 {
    font: bold 18px sans-serif;
  }
  a {
    color: $main-red;
    text-decoration: underline;
  }
}
Enter fullscreen mode Exit fullscreen mode
  • is-, has-. Prefix state. The state classes inform us about the temporary state of a node. They are the typical classes controlled by javascript and that modify the state of our html, as in a menu that appears or disappears, changes of size, color, etc. They have the added utility of helping developers to know the possible states in which a part of the interface can be. In the following example, we can see an example of a dynamic class using VueJS for a typical validation of a form:
<form class="c-form">
  <div class="c-form__group" :class="{ 'has-error': isValidName }">
    <label class="c-form__label">User Name</label>
    <input type="text" class="c-form__input">
  </div>
</form>

.c-form {
  &__group {
    border-color: $main-black;
    &.has-error {
      border-color: $error-red;
    }
  }
}

Enter fullscreen mode Exit fullscreen mode
  • _. Prefix for hacks. On certain, quite rare occasions, you may need to add a class to the html to help override or modify something temporarily. Actually, they are the type of classes that you should always avoid using, it is not advisable to use them but still it is convenient to know of their existence in case in extreme cases we have to resort to them. What cases are those? It occurs to me that you need to apply an urgent fix to a bug that has been detected and you don’t have time to apply a refactor at that precise moment although a temporary solution is easy to apply. Then, you can use a hack. But, as I said, it has to be temporary and should not be reused or linked to other classes.
._c-footer-mobile {
  height: 80px;
}
Enter fullscreen mode Exit fullscreen mode
  • js-. This type of class has become quite common. The goal is to properly track the separation of styles and javascript logic together in the same selector. It is a quite visible way that node will have a linked javascript event or behavior. It also adds the security of being able to work our css without affecting the javascript part, since these classes will not be linked with styles.
<span class="c-modal__button c-button js-close-modal">X</span>
Enter fullscreen mode Exit fullscreen mode
  • qa-. Prefix for QA (quality assurance). From the name, you can guess the purpose of these classes. Indeed, they are focused on the QA team. They are not very frequent but can be quite useful. If we have UI automation tests with tools like Selenium, it would be a good practice to separate CSS selectors from hooks for such tests. In my case, I have never used them, but it is important to know that they exist and if you have automated tests, it is an option to take into account.
<span class="c-message c-message--error qa-error-login">Login error</span>
Enter fullscreen mode Exit fullscreen mode

Suffixes

Suffixes have a single functionality: to serve as a tool to control the responsive behavior of our application. They are classes that are associated to other classes, usually utilities, although they can also be objects. If we have a class u-hidden@sm we are saying that this class is a utility that will hide an html element when the screen size is sm (which, in this case, we have predefined as a mixin). In code it would be something like this:

.u-hidden {
  visibility: hidden;
  $\@md {
    @include sm {
      visibility: hidden;
    }
  }
}


<div class="c-user">
  <img class="c-user__photo u-hiden@sm" />
</div>

Enter fullscreen mode Exit fullscreen mode

We can see that it has the same functionality as the u-hidden utility, but by adding the @ prefix, we will know that where we use it, it will only affect the media query we have defined for the sm screen size. If, on the contrary, we use u-hidden, we will hide the component in any screen size.

Keep in mind that this type of classes should not be used to apply responsive styles to a component. If we want our component to have a responsive behavior, the rules with their respective media queries are best added in the CSS of the selector.

Project Hierarchy

If we follow the file structure that we saw in the previous ITCSS article, we will only observe one change, and that is that the scopes folder has been added. Inside we will have our scopes file and this will be imported into our general styles file, the styles.scss.

yNyMnMRBVR8WNIPuL B wDjMeZjmScdGGKP9HuI6nPRnsJ9fC8d fxRIB2rvImKIYcBSb2FTHrY3WISWOj7TyQ6BcD4 QIIhdkIUgtR3Unt7pZrcbINPHZyAVEf34KsQFonamtT7

Conclusion (when to use it)

BEM provides a system to communicate clearly the relationships between blocks and the elements contained in them, helping to create a standard. ITCSS offers us a system to structure our style files and helps us to locate the rules defined in them, besides minimizing the inheritance and specificity conflicts that give so many headaches when our project starts to grow, both in size and people.

BEMIT combines the best of both. We can give the development team an idea of the scope of an element by using prefixes. When we see an o- we know where that class is located, since it is an object, and the implication that modifying it may have. Also, by using suffixes @ for elements that need particular responsive treatment,

BEMIT offers advantages in all types of projects, although it is true that in those that are large and where several people work is where it can offer better performance. Anyway, I usually do it even in small projects because the organization of the files and the CSS rules themselves make it much easier for me to read the code, so if you are convinced by its syntax and structuring, it can be a good idea to always use it.

Of course, this article serves as an approach, a brief sample of what it can offer. Below I leave links to the official articles of Harry Roberts where you can expand the information about this pattern and see extended examples to get into the use of BEMIT.

Links of interest

BEM prefixes and suffixes: https://csswizardry.com/2015/03/more-transparent-ui-code-with-namespaces/

You can also check my previous ITCSS article here

Top comments (1)

Collapse
 
yaireo profile image
Yair Even Or • Edited

I also love this (old) method: amcss.github.io

it's very elegant way instead of dumping lots of words mixed up in one attribute (class), the words using to describe the styles are separated between custom attributes.

Classes are not the only way to select an element,
and for many years the performance are not a bottleneck any more.