Tailwind vs BEM - Part 2 (Architecture)
Published: 2023-11-23 04:49:33

[The first article here](https://dev.to/nikolaymakhonin/tailwind-vs-bem-part-1-performance-comparison-2jgj)

Engineering is not about tasting. You can't just list pros and cons, taste them, and choose what you like best. One of the main tasks of good architecture is to avoid pitfalls, and if you do step on them, to do so knowingly, with a clear understanding that it's going to hurt but it's the best choice among the alternatives. When choosing a tool that affects architecture, I want to clearly understand what pitfalls await me in the future, am I ready to deal with these pitfalls, is the client ready for it? The issue of pitfalls is much more acute than even the question of development speed and convenience. Initially, a project may develop quickly, but as it grows, it may turn out that small changes take unacceptably long, and work becomes more and more exhausting. People tend to count the volume of work only in terms of time spent, not considering how much mental effort is exerted during this time.

When thinking about good architecture, experience in creating and maintaining long-term projects is very important. Only such experience allows you to step on all the pitfalls and understand the mistakes built into the project's foundation. In this article, I'll share my pitfalls. If anyone has anything to add, please write in the comments. Let's analyze them all.

I refer to pitfalls as unexpected complexities in solving seemingly simple tasks, which significantly increase the time or mental resources required to complete them.

> It's important to note that when writing this article, I relied solely on my extensive experience with **Svelte**. A couple of years ago, I tried to integrate BEM with **React**, and it didn’t work out, which surprised me a lot. There were no options to do this in such a way that style isolation worked, and you could change styles from the parent component without breaking all other components, and styles were in CSS, and classes in HTML could be indicated simply as text, exactly in the same way as in CSS. In Svelte, all this is easy, there you practically write normal HTML + CSS, then dilute it with logic, and Svelte does all the magic for flexible style isolation. Perhaps it’s impossible to use BEM in React in a human way, and Tailwind saves the situation with styles, but I don't have much experience in this.

# 1. Initial Data
**1.1. Common development tools for all architectures:**
1.1.1) PostCSS
1.1.2) Modern UI framework: React / Vue / Svelte / ...

**1.2. Architectures:**
1.2.1) Vanilla CSS + BEM
1.2.2) Tailwind (orthodox) with styles in HTML and without active use of @apply

**1.3. Possible tasks:**
1.3.1) design all pages from scratch
1.3.2) create several components with different internal logic, but with very similar style
1.3.3) create several components with the same logic, but with minor style changes
1.3.4) create several pages with minor changes in the styles of some elements
1.3.5) create theme designs with as many possibilities as possible for changing the styles of elements
1.3.6) pinpoint fixes/changes in layout
1.3.7) change the style of elements of a certain category

**1.4. Possible changes in elements:**
1.4.1) change all small margins, colors, fonts
1.4.2) hide a couple of elements
1.4.3) style some elements differently
1.4.4) change a gradient or picture

**1.5. Influencing factors:**
1.5.1) the entire project with strict guidelines
1.5.2) the entire project without strict guidelines
1.5.3) Pixel Perfect requirement
1.5.4) 1-2 developers on the project
1.5.5) several people or a large team on the project
1.5.6) simple one-page site or landing page
1.5.7) large site
1.5.8) fixed project with no future changes
1.5.9) unpredictability of development, i.e., you can't say in advance what changes and in which elements may occur. There can only be general predictions, like the absence of theme designs.

# 2. Analysis
We will look for optimal ways to solve tasks for all architectures, taking into account additional influencing factors.

## 2.1 Design all pages from scratch
* If the entire project has strict guidelines, it's easier to work with Tailwind. If there are no strict guidelines, you can make them strict and approximate the design.
* When designing from a Figma layout without strict guidelines, it’s easier to copy pure CSS than to match Tailwind classes by eye and memory.
* Pixel Perfect is easier to do with vanilla CSS, as DevTools allows you to easily adjust sizes and margins and then copy the CSS into the code.
* If several people are working on the project, using Tailwind means they don’t need to understand the common CSS classes of other developers. In this case, it's more difficult to change common classes, which will happen from time to time during development.

## 2.2 Create several components with different internal logic, but with very similar style
* For Tailwind, you need to create components without common styles. This is easy to create but hard to change if there are many components.
* With vanilla CSS, you can make common styles and reuse them in different components. These styles are easy to change at once for all components.

## 2.3 Create several components with the same logic, but with minor changes in style
* In Tailwind, changes in styles need to be integrated into logic, changing classes in HTML depending on parameters. A component's parameter is like a modifier in BEM. I'm afraid to imagine what a component will turn into if it has many different modifiers, the changes introduced by which are scattered throughout the HTML.
* Vanilla CSS handles this well. You can change the style of a component through parameters, but by replacing only one BEM class modifier for the container in the code. And set the style of the modifier separately in one place. In addition, vanilla CSS allows you to change the styles of nested components without changing the code of these components.
* Many styles can be changed through CSS variables. Tailwind's capabilities here are limited. To precisely indicate which styles of which elements can be changed through variables, you will have to use vanilla CSS.

## 2.4 Create several pages with minor changes in the styles of some elements
* In Tailwind, you will have to write classes with unique names for each changeable element and use vanilla CSS for their modification from the outside.
* If you use BEM, then all element names are already written, so to create a new page with a slightly different style, you don't need to change the nested components. Just write CSS of changeable styles in one place in the root component of the page.

## 2.5 Create theme designs with as many possibilities as possible for changing the styles of elements
* Tailwind gives limited possibilities in creating theme designs. If you change something, then everything on the page changes at once: all colors, all margins. It’s also problematic to implement CSS variables without vanilla CSS. You can only create utility classes with CSS variables globally, not for a specific component.
* Vanilla CSS has huge possibilities both in using CSS variables and in pinpoint changes of any properties of elements. If BEM is used, it’s very easy to change the style of a separate element or elements of a certain kind located in a certain place. But to change all colors on the site or all margins, you have to pre-write all CSS variables and distribute them throughout the code. In Tailwind, all these variables are already written.

## 2.6 Pinpoint fixes/changes in layout
* Tailwind elements are hard to find. You can’t just find out by the class attribute where the corresponding code is in the project. It’s even worse if there are several such places and you need to change them all. It’s also hard to understand what role a certain element plays in the code: is it a container, a wrapper, an independent block, etc. Refactoring is extremely difficult because of this. Miller's Law says that a person can simultaneously keep 5-7 entities in attention. To recognize the role of a certain element, a developer has to fill up his entire "attention wallet", as he needs to analyze all the classes of the element to understand its role. It’s even harder when there are several elements with one role in the code and you need to find them all.
* BEM elements are very easy to find, of course, if BEM classes are written in CSS in the same form as in HTML. You just need to copy the class name and find it in the project. It’s very easy to find all places where this class is used. To change the style of several elements of the same kind, you just need to edit only one style, if, of course, some structure is maintained in the layout. And BEM forces the developer to think about the structure of the layout. It’s very easy to understand the role of an element by the name of the class. Refactoring such code is not difficult. Miller's "wallet" can accommodate several elements at once. It’s also easy to find all elements with a certain role in the file by search.

## 2.7 Change the style of elements of a certain category
* It’s very hard to change the style of elements of a certain category in Tailwind layout, as Tailwind doesn’t imply thoughtful layout structuring. No structure - search for everything manually. If there are many elements, you will have to search for each manually.
* BEM forces you to think about the structure of the layout. Therefore, it’s easy to search for elements of a certain category with a simple search by class names.

# 3. Preliminary Conclusions
3.1) Design all pages from scratch
* No strict guidelines + Pixel Perfect => strictly vanilla CSS
* There are strict guidelines => Tailwind is more convenient

3.2) Create several components with different internal logic, but with very similar style
* There's not much difference

3.3) Create several components with the same logic, but with minor changes in style
* Tailwind has strong limitations here and forces the style of a component to mix with other logic
* Vanilla CSS is very flexible in this respect

3.4) Create several pages with minor changes in the styles of some elements
* Tailwind can’t be used, only vanilla CSS

3.5) Create theme designs with as many possibilities as possible for changing the styles of elements
* Tailwind can be used for theme designs, but with significant limitations
* Vanilla CSS has almost no limitations on theme designs

3.6) Pinpoint fixes/changes in layout
* Tailwind is difficult to read and edit.
* Using BEM and naming all elements makes it very easy to find them, and if you don’t write Tailwind classes in HTML, navigating the code is even easier.

3.7) Change the style of elements of a certain category
* It’s very difficult to do this in Tailwind layout, especially if there are many elements in different parts of the site.
* BEM allows you to easily find all elements with a simple search by class names.

# 4. My Conclusions
In terms of development flexibility, Tailwind is significantly inferior to vanilla CSS + BEM. Some believe that BEM and Tailwind do not contradict each other. Yes, they can technically be mixed together, but they are different architectures. Mixing them together, we get both the pluses and the minuses of both architectures. Mixing different approaches can lead to the code turning into a mess. Such a mixed architecture must be well thought out. But I haven't seen a SINGLE article on Tailwind architecture, not to mention Tailwind + BEM architecture. Meanwhile, there are plenty of articles on vanilla CSS architecture.
So far, I don't understand how to solve tasks 4, 5, 6, 7 on Tailwind. These Tailwind minuses are critical for me, but the minuses of BEM are not.

----

Write if you have something to say. I'm especially interested in how you solve the tasks I described here using Tailwind. Maybe, I still don't know some Tailwind development secrets.