Which CSS framework - Bootstrap or Tailwind?
Tags: css
Published: 2021-02-04 19:40:04

If you're new to web development, you may have heard these two CSS frameworks being name-dropped. TailwindCSS, in particular, has [caught on](https://explodingtopics.com/topic/tailwind-css) recently, but you'd likely have also heard about the venerable Bootstrap. What should you pick?

Both take different approaches:
- Bootstrap is what I'd call a **Component-based Framework**.  It's designed to help developers quickly _bootstrap_ a typical website or app and so comes with a set of pre-made components, along with some utilities for spacing etc. Other similar frameworks include [Bulma](https://bulma.io/) and [Foundation](https://get.foundation/).
- TailwindCSS is a **Utility-first Framework**. In contrast to Bootstrap, which provides a few utilities, Tailwind is _all_ utilities. The core framework has no pre-made components, so you'll need to build your own.

---
# Learning by Example

An example will help crystallise the differences - let's say we want to build a photo gallery with a “Load More” button:

![Photo Gallery Desktop](https://dev-to-uploads.s3.amazonaws.com/i/r50brlvjcikcto5bv798.png)

We also want it to be responsive, so on the tinier screens of our smartphones, the gallery morphs into a column layout:

![Photo Gallery Smartphone](https://dev-to-uploads.s3.amazonaws.com/i/piuy5syqc5w21wxjsavg.png)

---
## Bootstrap
Here's how you could achieve the layout with Bootstrap ([codepen](https://codepen.io/wasabigeek/pen/wvzNLXd
)):
```html
<section class="container">
  <div class="row">
    <div class="col-12 col-md-4">
      <div class="card mb-4">
        <img src="https://via.placeholder.com/300x200.png" />
        <div class="card-body">
          <p class="card-text">Card Text.</p>
        </div>
      </div>
    </div>
    <!-- repeat 2x... -->
  </div>
  <div class="text-center">
    <button class="btn btn-primary">Load More</button>
  </div>
</section>
```
Looking at the CSS classes, you'll probably have already noticed Bootstrap's built-in components:
- `container`, `row` and `col-*` classes are for layout
  - Bootstrap's layout is based on a grid of 12 units, so `col-12` is telling Bootstrap that this column should take up the full width of it's `container`. This is why if you resize the browser window smaller, it will stretch to the full width.
  - `col-md-4` says, on a medium-sized (md) screen and above, take only 4 units. This is why in a typical desktop view, it will show (12 / 4 =) 3 columns.
- The `[card](https://getbootstrap.com/docs/4.5/components/card/)` and `[btn](https://getbootstrap.com/docs/4.5/components/buttons/)` (button) components are hopefully quite self-explanatory.

We also used some of Bootstrap's utility classes, which map pretty close to the actual CSS being applied:
- `mb-4` applies `margin-bottom: 4rem` by default.
- `text-center` applies `text-align: center!important`.

### Observations:
- Because we were able to use Bootstrap's own components, there was little we had to write, and very little CSS we had to actually know. Some built-in components will also handle Javascript interactions for you, such as [accordions](https://getbootstrap.com/docs/4.6/components/collapse/#accordion-example) or one of my favourites, [scrollspy](https://getbootstrap.com/docs/4.6/components/scrollspy/).
- In keeping with the framework's conventions, we'd probably start grouping and naming our CSS classes by components too. e.g. I might add a `chat-message` class in my CSS/SASS stylesheet, with a modifier like `chat-message-primary` to set the colour. (If it sounds tricky deciding how to name classes, it is! People have come up with whole methodologies like [BEM](https://css-tricks.com/bem-101/) in an attempt to solve this.)

### In the Wild
Bootstrap has an [examples] (https://getbootstrap.com/docs/4.5/examples/) page showing some basic layouts, and you can take a look at some [curated examples](https://expo.getbootstrap.com/) in production and their [official themes](https://themes.getbootstrap.com/).

---
## TailwindCSS
A similar layout built with Tailwind ([codepen](https://codepen.io/wasabigeek/pen/abmMvgg)):

```html
<section class="flex flex-col">
  <div class="flex flex-col md:flex-row md:justify-center md:space-x-4 items-center space-y-4 md:space-y-0">
    <div class="border border-gray-200 rounded">
      <img src="https://via.placeholder.com/300x200.png" /> 
      <p class="p-5">Card Text.</p>
    </div>
    <!-- repeat 2x... -->
  </div>

  <div class="flex justify-center mt-4">
    <button class="px-4 py-2 rounded bg-blue-500 text-white hover:bg-blue-600">
      Load More
    </button>
  </div>
</section>
```
While Bootstrap provided some utility classes, the Tailwind core _only_ has utility classes:
- for layout, we are making use of [flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/) via classes like `flex` and `flex-col`
- responsiveness is achieved using the breakpoint prefixes, e.g. `md:flex-row` changes the flex-direction to "row" only on medium-sized ("md") screens or larger
- for the "components" like the button, we are almost writing the CSS using the utility classes e.g.:
  - `px-4` adds a padding of 1rem (it has a different default scale from Bootstrap) to the left and right (the x-axis).
  - `bg-blue-500` sets the background to a "medium" blue.
  - `hover:bg-blue-600` darkens the background colour when someone hovers over it.


### Observations
- Using Tailwind isn't too far off from writing plain CSS, which isn't necessarily a bad thing. If you are working with a design that deviates from the norm, a framework like Bootstrap doesn't help much - you'd end up writing most of your own CSS. With Tailwind, that becomes easier because of the utility classes.
- We're able to do all our styling without leaving our HTML, just by adding utility classes. So instead of structuring our components via CSS class names, we'd be relying on extracting components via our frontend framework. In Rails we might break up the code into partials:
```erb
<%# gallery.html.erb %>
<section class="flex flex-col">
  ...
  <div class="flex justify-center mt-4">
    <%= render partial: "button", text: 'Load More' %>
  </div>
</section>

<%# _button.html.erb %>
<button class="px-4 py-2 rounded bg-blue-500 text-white hover:bg-blue-600">
  <%= text %>
</button>

```

There's a whole debate about whether this is a good thing, you can read Adam Watham's (the creator of Tailwind) argument [here](https://adamwathan.me/css-utility-classes-and-separation-of-concerns/).


### In the Wild

Adam Watham's [Youtube](https://www.youtube.com/channel/UCy1H38XrN7hi7wHSClfXPqQ) channel is a great resource for learning best practices on Tailwind. He also has a set of (mostly paid) [pre-built Tailwind components](https://tailwindui.com/) that you can use as a base. It's definitely in the spotlight now - for Rails devs, there's even an official [tailwind-rails](https://github.com/rails/tailwindcss-rails) gem.

---
# So, which to pick?
My personal opinion:
- If you're a new **backend** or **"full-stack"** developer (e.g. Rails developers), I'd highly recommend trying Bootstrap first - make use of their built-in components, and only pick up CSS as needed when tweaking the styles or starting your own components. That way, you'd have more time to spend on learning the other parts of your chosen stack.
-  If you're set on the **frontend** path or are more seasoned with CSS, then Tailwind (or maybe even no framework) is a good choice, seeing as you'll need to get good with CSS anyway. I am personally using Tailwind for my new projects and while I'm still figuring out how to structure my code, am enjoying it.

If you have unanswered questions, please do comment below or send a [tweet](https://twitter.com/wasabigeek) - I'd love to incorporate your feedback into this post to help others!