Utility-first approach
Utility-first is an approach that revolutionized CSS in recent years and made Tailwind CSS extremely popular. But what is it exactly about and why does it matter?
In this lesson, we'll use a (seemingly) simple button component to explain the concept of the utility-first approach.
Although small, the buttons can cause trouble.
Compared to, for example, Bootstrap, where buttons consist of only 2 classes
(e.g. .btn
and .btn-primary
), buttons built in
Tailwind appear to be more tricky.
Why?
Because in Bootstrap classes like .btn
or
.btn-primary
are responsible for a lot of things - padding,
margins, color, hover state, active state and many more.
<!-- Typical Bootstrap button -->
<button class="btn btn-primary">Button</button>
Abstraction layer
In such a situation, when we are unable to guess from the name itself what
exactly a given class (such as .btn
) does, we say that it
imposes a layer of abstraction.
Of course, we can guess quite easily that the .btn
class
creates a button, but we can't guess from the name itself what exactly the
padding, margins, color, etc. are. And although we can guess that the
.btn-primary
class creates primary buttons, we don't know what
"primary" actually means.
So these classes are abstract.
In simple terms - if we are unable to guess from the name of the class itself the specific CSS properties that this class applies, we say that it is abstract or that it imposes a layer of abstraction.
What does the utility-first approach propose instead?
Utility-first is a CSS methodology where you build up your styles using many small, purpose-specific classes.
Traditional CSS
To illustrate it let's take an example of a button styled using traditional CSS.
First, we need to create a class .btn
and apply to it desired
CSS properties:
.btn { padding: 0.5em 1em; background-color: blue; color: white;
border-radius: 0.25em; }
Then we can use this class in our HTML:
<button class="btn">Click me</button>
And this will be the result:
Tailwind CSS
The same button using a utility-first approach in Tailwind would look like this:
<button class="rounded-md bg-blue-500 px-4 py-2 text-white">
Click me
</button>
What catches the eye at first glance is that the Tailwind button is much more verbose.
In traditional CSS we have only one class, and in Tailwind as many as 5.
And this is just the beginning - to apply the styles for hover state, active state, disable state to our button, we will need a lot of classes.
But what do you get in return?
- Composability: You can compose complex designs by applying many utility classes. This allows you to avoid creating unique classes for every variation of a component.
- Direct mapping: The styling of an element is clear just by looking at the HTML. There's no need to jump to a separate CSS file to understand the styles applied.
- Customizability: You can generate a wide array of utility classes from your configuration file in Tailwind, allowing for project-specific customization.
- Responsive design: Tailwind provides utility classes for handling responsive designs out of the box. You can control the styles for different screen sizes using these utility classes.
- Efficiency: You avoid bloating your CSS with unnecessary or unused styles. This approach promotes the creation of styles as they are needed, which can lead to more efficient CSS.
- Consistency: This approach encourages consistency across a project, as it naturally creates a limited set of styles to use.
While utility-first approach might look verbose at first, it actually promotes consistency, customization, and efficiency in your styles. Also, once you get used to this approach, it can significantly speed up your development process.
About author
Michal Szymanski
Co Founder at TW Elements and MDBootstrap / Listed in Forbes „30 under 30" / Open-source enthusiast / Dancer, nerd & book lover.
Author of hundreds of articles on programming, business, marketing and productivity. In the past, an educator working with troubled youth in orphanages and correctional facilities.