If you're new to web development, you may have heard these two CSS frameworks being name-dropped. TailwindCSS, in particular, has caught on 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 and 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.
An example will help crystallise the differences - let's say we want to build a photo gallery with a “Load More” button:
We also want it to be responsive, so on the tinier screens of our smartphones, the gallery morphs into a column layout:
Here's how you could achieve the layout with Bootstrap (codepen):
<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:
col-*classes are for layout
- Bootstrap's layout is based on a grid of 12 units, so
col-12is 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-4says, 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.
- Bootstrap's layout is based on a grid of 12 units, so
btn(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:
margin-bottom: 4remby default.
- 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-messageclass in my CSS/SASS stylesheet, with a modifier like
chat-message-primaryto set the colour. (If it sounds tricky deciding how to name classes, it is! People have come up with whole methodologies like BEM in an attempt to solve this.)
A similar layout built with Tailwind (codepen):
<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 via classes like
- responsiveness is achieved using the breakpoint prefixes, e.g.
md:flex-rowchanges 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-4adds a padding of 1rem (it has a different default scale from Bootstrap) to the left and right (the x-axis).
bg-blue-500sets the background to a "medium" blue.
hover:bg-blue-600darkens the background colour when someone hovers over it.
- 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:
<%# 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.
Adam Watham's Youtube channel is a great resource for learning best practices on Tailwind. He also has a set of (mostly paid) pre-built Tailwind components that you can use as a base. It's definitely in the spotlight now, there's even an official tailwind-rails gem.
Hopefully I've given you enough information to make that choice on your own, but if you must hear 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 have unanswered questions, please do comment below or send a tweet - I'd love to incorporate your feedback into this post to help others!