May 18, 2020

First Impression with Tailwind CSS

As a utility-first CSS framework, Tailwind blew my mind away after using it for my personal website.

In the process of creating my 2020 personal website, I had a chance to explore several CSS frameworks like Bootstrap and CSS-in-JS tools such as Glamor, Styled Components, and Emotion.js.

One in particular that caught my attention is Tailwind CSS, a utility-first CSS framework for rapid design development.

According to the official documentation, Tailwind was made to be highly customized. It does not come with a pre-defined set of UI components or utilities like how Bootstrap works. Instead, the framework provides low-level utility classes that you can rely on to create custom designs.

Here's my impression after completely using Tailwind to style my website.

Tailwind Homepage

Low-Level Utility Classes

If you love using Bootstrap, you will like Tailwind. The classes that Tailwind provide by default are vast and easily customizable.

Let's say you want to add both top and bottom margin to a particular element. You can easily do it like so:

<div class="mt-6 mb-6">
  <!-- .. content .. -->

<div class="my-6">
  <!-- same as above just written differently -->

And in a more complex interface involving lots of classes, the code snippet below produces this alert design.

Complex Tailwind UI

// from tailwind documentation
<div class="max-w-sm mx-auto flex p-6 bg-white rounded-lg shadow-xl">
  <div class="flex-shrink-0">
    <img class="h-12 w-12" src="/img/logo.svg" alt="ChitChat Logo">
  <div class="ml-6 pt-1">
    <h4 class="text-xl text-gray-900 leading-tight">ChitChat</h4>
    <p class="text-base text-gray-600 leading-normal">You have a new message!</p>

The good thing about using Tailwind classes is that each class adds specific property to an element, rather than producing unintended effects on the entire document.

Impression: I was not used to the mindset of adding more properties to the list of class names. But after using Tailwind for quite some time, it picked up naturally. It was easy to turn something into a flex container with black background simply by just adding these classes: flex bg-black.

It's so simple!


Writing CSS to design responsive layouts --- whether through Flexbox or even Grid --- can still be a pain.

Given these breakpoints:

sm: '640px'      // => @media (min-width: 640px) { ... }
md: '768px',     // => @media (min-width: 768px) { ... }
lg: '1024px',    // => @media (min-width: 1024px) { ... }
xl: '1280px',    // => @media (min-width: 1280px) { ... }

Tailwind makes it easy to define different variations to your page layout by just adding these classes:

<div class="w-full sm:w-1/2 md:w-1/3 lg:w-1/4">
  <!-- content -->
  • On a small device with a screen width of less than 640 pixel, the width of this element is 100%.
  • If the screen width is between 640 and 768 pixels, the width is halved.
  • On a slightly bigger screen, the container's width is 33.333333% to be exact.
  • and so on...

Hopefully you get the idea.

Impression: I love that Tailwind makes it easy for me to tweak my components and layouts for certain breakpoints just by introducing breakpoint prefixes before the usual Tailwind classes names.

It’s intuitive and easy to understand.


When you use Tailwind, tailwind.config.js is a global configuration file that enables you to customize and pre-define values for your Tailwind utility classes.

A typical tailwind.config.js file has the following default content structure:

module.exports = {
  plugins: {},
  themes: {},
  extend: {}

Leaving it as such tells Tailwind to rely on existing properties that are already pre-built and ready for us to use.

These includes classes like block, mx-auto, pt-2, pb-4, bg-gray-900.

<div class="block mx-auto pt-2 pb-4 bg-gray-900">

Sometimes, you want to add additional values that are not originally defined by Tailwind. For instance, for the spacing properties (padding, margin, width), you can tweak your tailwind.config.js file like so:

module.exports = {
  plugins: {},
  themes: {},
  extend: {
    spacing: {
      96: '24rem'
      100: '32rem',

This allows us to use classes this way:

<div class="block pt-96">
  <p>A top padding of 24rem is added</p>

With one configuration file, you have a single document that acts as a source-of-truth. This is especially useful when working with larger teams.

CSS-in-JS Support

My personal website uses Emotion.js to style my components. It's a great way, in my opinion, to allow props drilling and dynamic CSS values adjustment using JavaScript.

With Tailwind, there's no complicated mess in using it alongside CSS-in-JS libraries like Emotion.js and Styled Components.

import styled from '@emotion/styled';
import tw from "twin.macro";

const TagsWrapper = styled.section`
  span {
    ${tw`inline-flex mr-2 align-middle items-center`}
    ${tw`bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700`}
    :last-child {
  svg {


The only catch is that Tailwind requires external libraries to allow it to run within any CSS-in-JS library. I am using a package called twin.macro to allow my Gatsby.js-powered site to understand Tailwind styles.

Impression: Native CSS-in-JS support isn't as easy as it seems, in my opinion. But Tailwind has written a great documentation that explains how to create plugins that will inject CSS ito JavaScript rather than traditional CSS files.

So if you're like me and you are using CSS-in-JS libraries, then using Tailwind is easy as long as there are plugins available.

On a side note: Gatsby.js provides an in-depth documentation on adding Tailwind CSS to your site


Tailwind is a great framework that provides greater freedom for designing your own user interfaces.

My opinion is that Tailwind will be one of the more popular frameworks going forward. Its abilty to be easily customizable through its tailwind.config.js file is a huge plus, especially for projects that include multiple maintainers and developers working together.

Thank you for reading along.

CSS-in-JS Tailwind CSS

Last updated: May 20, 2020