Exploring CSS: Micro-frameworks (Tailwind)
Tags: css, tooling
Published: 2021-02-04 00:34:43

Next up in this series is trying out [Tailwind CSS](https://tailwindcss.com/), another framework.  I've heard a lot about how great Tailwind is, so I've really wanted to check it out for quite some time, what better time than now?  Tailwind is:
>A utility-first CSS framework packed with classes like `flex`, `pt-4`, `text-center` and `rotate-90` that can be composed to build any design, directly in your markup.

There is a lot more to this framework than there was with Plume, so just know that I'm only scratching the surface at this point.

## What's To Like

#### Documentation
My first thought when I looked at the documentation was "Wow, there's a LOT more to unpack here than there was with Plume!" but the good news is that the documentation is top-notch.  Not only does it do an excellent job of walking through how to use Tailwind, but it also contains instructions for related topics, like what is a pre-processor or how to build JavaScript components.

#### Set Up
There are a couple of options for setting up Tailwind, and the documentation does a great job of talking you through not only *how* to set it up with each method, but also *why* you might want to use each method.  The easiest way is through a CDN.  All you have to do is include the link in your HTML and you're done.  Nothing to install or download.  However; the documentation warns against this as you lose a lot of the best features.  The recommended method is to install Tailwind as a PostCSS plugin, but I didn't go this route, mostly because I haven't gotten to exploring preprocessors yet - one thing at a time.  The last option is to use NPX to install Tailwind into your project as a CSS file: `npx tailwindcss-cli@latest build -o tailwind.css`.  This is the route I took and, as a bonus, it is pretty close to what I did with Plume.

#### Utilities & Components
This is where Tailwind really shines.  Where Plume is awesome for quickly setting up the basic components across your site, but not great at customizing individual elements, Tailwind is just the opposite.  There are hundreds of options in Tailwind, and they are all applied to the individual element, rather than making broad strokes across the site. As well, they are designed very tactically, meaning that each option only does one thing and can be chained with other options to get to the full effect that you are going for.  This means that, if I know I want to do something like create a flex-box that is centered in the page, all I have to do is look at the documentation for each "piece" of the formatting (display, sizing, spacing, and background), then just go down the list of options and copy/paste the class that gives the effect I want.


Additionally, Tailwind gives you some pretty great pre-made components for free!  I particularly like the select and dropdown menus.  You'll generally need to build your own components using the provided utilities; however, unless you pay for Tailwind's premium content.

#### Customization
Tailwind allows you to customize everything and create a very detailed "theme" for your site styling.  This goes well beyond what Plume can do, but is also a much heavier effort.  Although it doesn't seem too bad to customize, and the documentation does a great job of walking you through it, I decided to see how far I could get without doing any customization, so it's outside the scope of this article.  One really cool thing I did see; however, is that you can customize on several "layers" to help you avoid specificity clashes!

#### Component Extraction and Abstraction
A major drawback of Tailwind is that there is a **LOT** of duplicated code in your HTML (more on this below).  Fortunately, this can be avoided by extracting common components or abstracting the styles using Tailwind's `@apply` feature.  This either requires very thoughtful planning, or a retro-active approach (after you've finished, go back and find/abstract your more common components), the latter being not so ideal.  But I imagine once I've used it a few times and I'm more familiar I'll have a pretty good idea of what I'll want to abstract away before even getting started.  Unfortunately, when I tried to use this feature I was unable to get it to work since I'm not using any CSS preprocessors.  A project for another time.

#### Responsiveness
Unsurprisingly, Tailwind components support responsive design.  But the thing is, since everything is applied to each component, Tailwind makes it insanely easy to keep your site *consistently* responsive.  It has built-in breakpoint prefixes, so you can tell each component what to do when the screen is small, and then how to change when it gets to a medium size, for example.  Personally, breakpoints are one of my biggest pet-peeves about writing CSS because it tends to feel like I'm re-writing the entire style for each breakpoint.  I also get really ADHD about it and end up with two dozen breakpoints, each changing a few things at a time.  Time consuming, inefficient, and unwieldy.  The fact that Tailwind saves me from myself in this regard might make this my favorite feature!

#### Transformations & Transitions
Tailwind even includes transformations and transitions!  For my simple test I didn't use these, but based on how easy all the other utilities have been to use, I'm excited to try these out soon to make the experience of writing transitions better.

## What's Not To Like

#### Learning Curve
There is a ton of functionality in Tailwind.  This makes it extremely powerful, but it also makes it feel like I have to re-learn CSS.  As I use it more and more, it will undoubtedly become second nature and this won't be an issue anymore, but it certainly takes some getting used to at first.


#### Code Duplication
As I mentioned before, a big drawback of Tailwind is that there is a **LOT** of duplicated code. In fact, even in my simple testing layout, I would need to manually copy/paste the entire HTML code from the first article to each of the following ones, and let's not even get into what a nightmare it would end up being if you are building HTML elements programmatically in JavaScript!  For example, take a look at all the code I'd need to copy for each and every similar button that I want to put on my page:
```
<button class="bg-gradient-to-r from-blue-500 to-blue-900 my-4 max-w-max px-8 py-2 text-white font-bold">Cool Button</button>
```
Luckily, if you're using a pre-processor, the brilliant creators have already thought of this and they have us covered by including extraction and abstraction features as mentioned in the To-Like section.  It requires another step, but that's a small price to pay for all of the benefits above.

#### The Dreaded Paywall
While there are some very generous free components available, you'll need to fork out some cash in order to get all of them.  Some of these paywalled components (buttons for example) are on the more basic side too.  The good news, of course, is that you can build anything you want using their utilities which are all free, it just takes time and practice.


## Verdict
Tailwind is absolutely amazing!  I almost feel like, if I could start all over, it might have been great to learn Tailwind first and THEN learn custom CSS.  It's powerful and customizable enough to perfectly create any style or element that you could ever want, but at the same time it's surprisingly simple to use thanks to the very deliberate and tactical design, and the accompanying documentation.  Definitely beats writing your own CSS, especially if you use a preprocessor and can abstract out some of those common, Tailwind-heavy elements.


As always, here's my testing layout:
![Site Layout Using Tailwind](https://dev-to-uploads.s3.amazonaws.com/i/nhffc42zn5543kk18g2h.png)

And the code to make it:
```
<!DOCTYPE html>
<html lang="en">
  <head>
    <title> </title>
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
    <link rel="stylesheet" href="tailwind.css">  
    <link rel="stylesheet" href="style-tailwind.css">
  </head>
  <body>
    <div class="bg-gray-100 text-gray-500 p-5">

      <article class="flex flex-col flex-wrap max-w-4xl px-4 pb-9 mx-auto bg-white mb-5">
        <figure class="mx-auto pb-4"> 
            <h3 class="text-5xl pt-3 pb-8 font-medium font-serif text-center">Project 1</h3>
            <img src="http://placekitten.com/g/600/300" alt="Visual Store"/>
            <figcaption>
                <p class="text-center text-sm">This is the first project in the list.</p>
            </figcaption>
        </figure>
        <p class="text-left pb-3 text-lg"><strong>Main Features:</strong> Some cool things are in this.</p>
        <p class="text-left pb-3 text-lg"><strong>Backend Techs:</strong> Here's what I used to build the API.</p>
        <p class="text-left pb-3 text-lg"><strong>Frontend Techs:</strong> Here's how the site was built.  Make sure to include Plume!</p>
        <span class="mx-auto">
            <button class="bg-gradient-to-r from-blue-500 to-blue-900 my-4 max-w-max px-8 py-2 text-white font-bold">Cool Button</button>
            <button class="bg-green-500 my-4 max-w-max px-8 py-2 text-white font-bold">Good News!</button>
            <button class="bg-red-500 my-4 max-w-max px-8 py-2 text-white font-bold">Bad News!</button>
        </span>
      </article>

      <article class="flex flex-col flex-wrap max-w-4xl px-4 pb-9 mx-auto bg-white mb-5">
        <figure class="mx-auto pb-4">  
            <h3 class="text-5xl pt-3 pb-8 font-medium font-serif text-center">Project 2</h3>
            <img src="http://mrmrs.github.io/photos/whale.jpg" alt="Visual Store"/>
            <figcaption>
                <p class="text-center text-sm">This is Number 2.</p>
            </figcaption>
        </figure>
        <p class="text-left pb-3 text-lg"><strong>Main Features:</strong> Some cool things are in this.</p>
        <p class="text-left pb-3 text-lg"><strong>Backend Techs:</strong> Here's what I used to build the API.</p>
        <p class="text-left pb-3 text-lg"><strong>Frontend Techs:</strong> Here's how the site was built.  Make sure to include Plume!</p>
        <span class="mx-auto">
            <button class="bg-gradient-to-r from-blue-500 to-blue-900 my-4 max-w-max px-8 py-2 text-white font-bold">Cool Button</button>
            <button class="bg-green-500 my-4 max-w-max px-8 py-2 text-white font-bold">Good News!</button>
            <button class="bg-red-500 my-4 max-w-max px-8 py-2 text-white font-bold">Bad News!</button>
        </span>
      </article>

      <article class="flex flex-col flex-wrap max-w-4xl px-4 pb-9 mx-auto bg-white mb-5">
        <figure class="mx-auto pb-4"> 
            <h3 class="text-5xl pt-3 pb-8 font-medium font-serif text-center">Project 3</h3>
            <img src="http://mrmrs.github.io/photos/cpu.jpg" alt="Visual Store"/>
            <figcaption>
                <p class="text-center text-sm">Third entry is the charm.</p>
            </figcaption>
        </figure>
        <p class="text-left pb-3 text-lg"><strong>Main Features:</strong> Some cool things are in this.</p>
        <p class="text-left pb-3 text-lg"><strong>Backend Techs:</strong> Here's what I used to build the API.</p>
        <p class="text-left pb-3 text-lg"><strong>Frontend Techs:</strong> Here's how the site was built.  Make sure to include Plume!</p>
        <span class="mx-auto">
            <button class="bg-gradient-to-r from-blue-500 to-blue-900 my-4 max-w-max px-8 py-2 text-white font-bold">Cool Button</button>
            <button class="bg-green-500 my-4 max-w-max px-8 py-2 text-white font-bold">Good News!</button>
            <button class="bg-red-500 my-4 max-w-max px-8 py-2 text-white font-bold">Bad News!</button>
        </span>
      </article>

    </div>
  </body>
</html>
```

That's it, no custom CSS required!