Spoilers! Like with so many things, the answer is “it depends.” How come? Read on.
Tailwind and BEM are two approaches to writing and maintaining CSS. Comparing them is a bit like comparing apples and oranges, in that while they’re separate, they’re still fruit. This is to say that having an approach to manage your CSS—like any other code—is a good thing.
Tailwind is the newer of the two, with the first stable release in May of 2019. BEM was made open source in 2010, although it’s been around since 2006. Chances are good that if you’re working on a modern web project you’ll find one of these approaches.
I won’t bore you with the particulars of my experiences, but I will say that I’ve been a consultant for over five years and have had practical experience using both on a variety of projects and scales. Here’s the benefits and drawbacks for both:
Tailwind provides a series of pre-written classes to work with. These classes are utility CSS, meaning many small, single-purpose classes that are assembled en masse to create an overall visual effect.
- The utility CSS approach creates an API-style approach to thinking about CSS, which helps many developers work with it.
- Tailwind’s classes create sensible defaults, with considerations and properties many developers aren’t aware of.
- Because you describe how something looks rather than what it is, you avoid the classic “naming things” problem.
- A utility CSS approach keeps specificity low across your entire website or web app.
- Tailwind’s implementation will be very similar across multiple projects and teams, which promotes easier cross project familiarity.
- You need to learn Tailwind class names in addition to learning CSS property names to figure out the visual styling you want. Tailwind is reliant on, and will be outlived by CSS, so it is more long-term beneficial to focus on CSS’ capabilities directly.
- Tailwind describes most, but not all of CSS’ capabilities, especially newer features.
- Tailwind works best when there’s a component system present. Without this kind of abstraction, it becomes difficult to keep component instances consistent.
- Due styling conventions shared between components, Tailwind oftentimes creates small collections of common classes. This represents an opportunity for abstraction in Sass, but is counter to a utility CSS approach.
- Complicated components can be difficult to make responsive, with responsive classes creating a lot of class name clutter.
- Tailwind needs a build tool to work, and greatly benefits from having another task that removes unused classes.
Instead of predefined class names to draw from, BEM is a methodology to inform how to describe things. It’s a technique pioneered by Nicolle Sullivan’s Object Oriented CSS (OOCSS).
BEM stands for Block, Element, Modifier, an acronym used to describe its styling methodology. Blocks are standalone entities, what we’d consider a component. Elements are the parts of the component, and Modifiers serve as flags for conditionally altering appearance or user-facing state.
- BEM will allow you to describe any user interface component you can dream up in a flexible, extensible way. As it is an approach to encapsulate the full range of CSS properties, it will allow you to style things Tailwind simply does not have classes for—think highly art directed experiences.
- BEM embraces the single responsibility principle, with each class focused on managing only one thing—itself. This makes it a great way to modularly construct something, especially if the elements size or location conditionally shift.
- BEM encourages using namespaces for components, allowing an author to quickly determine what classes are used for things like layouts, components, and state.
- Since it uses authored CSS and not predefined classes, Sass logic and CSS custom properties can be easily threaded into BEM classes.
- BEM can be enhanced by a build tool or preprocessor, but does not require them. This makes it extremely portable.
- A stylesheet built with BEM will only be as large as the amount of code written. There are no extra classes that require automated removal.
- BEM runs full-tilt into one of the hardest problems in computer science—naming things. You need to not only describe your component, but also all its constituent parts and their states.
- Naming is further complicated when distributed across a team, especially larger team. Each team member writing BEM exponentially increases the chance of duplicative styling, as well as potential ambiguity about when and where to apply the right class names.
- There is no mechanism aside from code review from a knowledgeable peer to prevent an unfamiliar or rushed developer from slapping in an unrelated Element or Modifier class into a block because it creates the visual effect they’re trying to achieve.
- BEM can easily be over-extended without proper discipline. I’ve seen my fair share of grandchildren selectors (element classes tacked on an existing element class), a clear signal that a refactor is in order.
- Extremely large projects with many different components will create large stylesheets, potentially large enough that it will outpace Tailwind’s.
- User-facing state is sometimes is better described by a styled, semantic attribute instead of a modifier class.
¿Por qué no los dos?
Personally, I’ve been really enjoying CUBE CSS, a new approach that capitalizes on the strengths of both approaches (plus a nice dash of axiomatic CSS). And capitalizing on strengths is the name of the game: By keeping an open mind about these sorts of things, you’re able to adapt to the challenges each projects requires.