Spoilers! Like with so many things, the answer is “it depends.” How come? Read
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’
- Tailwind describes most, but not all of CSS’ capabilities, especially newer
- 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
- 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.
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.