What is Tailwind CSS?
Tags: html, css, tailwindcss
Published: 2020-05-05 01:05:22

I started using Tailwind a few months ago and it has dramatically improved my workflow. So much so that I decided to write a gentle introduction attempting to demystify Tailwind's "utility-first" ideology.


## What is Tailwind CSS? 

Tailwind is a "utility-first" CSS framework that lends itself to rapid custom design prototyping. According to their website, Tailwind is a *"highly customizable, low-level CSS framework that gives you all of the building blocks you need to build bespoke designs without any annoying opinionated styles you have to fight to override."*

## What does "utility-first" mean?

I was initially confused about what made Tailwind distinct from other CSS frameworks I had tried; for example, Bootstrap, Foundation, Material UI etc. But after experimenting with it on a project, I understood. 

Other CSS frameworks ship with default themes and default-styled components which you have to painstakingly customize. These customizations require a lot of sleuthing to find every occurrence of that class and then modifying it *for every screen size*. At this point, you're probably using `!important` a LOT.

Instead, Tailwind provides you with a set of aptly-named classes. These classes are the "utilities" you use to style your elements; giving you complete control over their appearance and enabling you to create a "theme" if you wish. The result of this? You have to build everything from *scratch*. Depending on how you perceive it, it's either a glass half-empty or half-full situation.

### Trivial scenario:

I'm building a page and I need a button. This button should have a small border-radius, white text, blue background, and a darker blue background on hover.
I could do something like this: 

html
```
<button class="button"> Click me!</button>
```


CSS
```
.button {
  background: #4299e1;
  padding: 0.5rem 1rem;
  border-radius:0.25rem;
  color:#ffffff;
}

.button:hover {
  background: #2b6cb0;
}
```

![Button example](https://dev-to-uploads.s3.amazonaws.com/i/iyu9joeodw34eodeddd8.gif)

If I needed several buttons with the same metrics (spacing, padding, margin etc) but different colors, we can easily see how the CSS could balloon exponentially. 

eg. I now need to add a green button, so I refactor the base class and add 4 additional classes to account for differences in colour and hover effects:

```
.button {
  display: inline-block;
  padding: 0.5rem 1rem;
  border-radius:0.25rem;
  color:#ffffff;
}

.button.blue {
  background: #4299e1;
}

.button.blue:hover {
  background: #2b6cb0;
}

.button.green {
  background: #48bb78;
}

.button.green:hover {
  background: #2f855a;
}
```

But I only need this green button in one place....

## Tailwind to the rescue

Tailwind provides us with an easier way out of this predicament. Using the framework's utility classes, the original html becomes:

```
<button class="rounded py-2 px-4 text-white bg-blue-500 hover:bg-blue-700"> 
Click me!
</button>
```

![Tailwind button example](https://dev-to-uploads.s3.amazonaws.com/i/fad1jqxb2np7x3lrxl3h.gif)

And if I need a green button?


```
<button class="rounded py-2 px-4 text-white bg-green-500 hover:bg-green-700"> 
Click me!
</button>
```

![Green button example](https://dev-to-uploads.s3.amazonaws.com/i/jrvx4nl8toq7uf37ll7c.gif)

 Now I have the single instance of the green button I need, without adding additional code to the CSS file. If I wanted to extract the component classes to make them reusable, it would look like this:

```
.button {
    @apply py-2 px-4 rounded text-white;
 }
.button.blue {
    @apply bg-blue-500
 }
.button.blue:hover {
    @apply bg-blue-700;
 }
.button.green {
    @apply bg-green-500;
 }
.button.green:hover {
    @apply bg-green-700;
 } 
```

This is much simpler to read and write than pure CSS, or playing whack-a-classname.

Using this approach makes it easier to build custom components and share styles. Sharing colours across elements is also easier, and doesn't require sifting through a massive CSS file to locate the HEX (or RGB) code. Also, in the event that we customize the color palette all the changes will cascade seamlessly. And the CSS...well, I don't need to spend time defining every single thing as all the utilities are already defined in the framework. 

*Tailwind facilitates full customization; inclusive of colours, spacing (used to determine margins and padding), and font sizing.*


So let's break down the Tailwind utilities I've used.

**rounded:** Applies a default (0.25rem) border-radius to the element. Variations include rounded-sm, rounded-md, rounded-lg and rounded-full.

**bg-blue-500:** Specifies the colour and weight of the background. The number specifies the weight of the colour. In this case, 500. Using bg-blue-300 would result in a lighter shade of blue.

**hover:bg-blue-700:** Adds hover style; specifying a heavier weight of the same hue.

**py-2, px-4:** Applies vertical (y) and horizontal (x) padding in increments, respectively (0.5rem & 1rem). p-1 equates to a padding of 0.25rem.

**text-white:** Specifies text colour. Text, border, and background colours are all generated in the same way. For eg. if we wanted a text colour that was the same colour as the button we could use text-blue-500.


To see the examples in action, check out the codepen [here](https://codepen.io/FJKhan/pen/eYpvPGr) . For more information on Tailwind, take a look at their [documentation](https://tailwindcss.com/docs/). It is very thorough and includes examples for each utility class, as well as how to customize them.


## Benefits of Using Tailwind CSS

### Mobile-first & responsive
Tailwind uses a mobile-first breakpoint system that you're probably already familiar with (sm, md, lg, xl). Defining how elements should behave at various breakpoints is a breeze using these prefixes. eg. Changing the flex direction of a container from `column` on mobile, to `row` on larger screens: `<div class="flex flex-col sm:flex-row"> ... </div>`

### No more whacky class names.
(Almost) All the css rules you need to style an element can be achieved by using one, or a combination of several Tailwind utilities. Classnames made easy. No distress necessary.

### Smaller css files
Since (almost) all the classes you need are already predefined, you rarely have to write custom css which reduces bloating and results in...smaller css files. Combine Tailwind with PurgeCss to strip out classes you never use to result in *really* tiny minimized css files.

### Less anxiety
Collaborate with other developers without worrying about introducing breaking changes. Tailwind provides a common language through shared classnames. Classes in your HTML is local and so are changes, so you can modify styles without worrying about other elements breaking.


## In the end...

... Tailwind saves me from writing hundreds of lines of css with increasingly ridiculous classnames in order to style elements and provides a common language for developers across the project. No more bloat from ad-hoc classnames because the developer couldn't find a particular style to modify. Everyone is utilizing a set of pre-defined utility classes. My favorite part? Not having to hunt for, and manually override framework classes.


I understand how ridiculous it might look at first glance. I was very skeptical of all the "inline" styles at first; but give it a try. I highly recommend it over other frameworks for projects that require a greater degree of control over the UI or have custom designs. It will save you hundreds of lines of CSS and lots of headaches; literally.

Share your experience using Tailwind CSS in the comments!