Bootstrap or Tailwind, Which is Better?
I have spent most of my career working in Bootstrap and recently in the last year have worked exclusively in Tailwind. So which is better – Bootstrap or Tailwind?
Bootstrap
Bootstrap started back in 2011 as an internal styling framework for Twitter. I started working with Bootstrap in 2012 because I was tired of rebuilding things from scratch and using my home-baked CSS framework (more of an organized set of CSS files). Bootstrap was a huge step forward and allowed me to build sites faster and keep the code in a consistent file structure. Bootstrap has styles for buttons, accordions, dropdown navigation and so much more, which is amazing if you need to get something up fast. The downside is Bootstrap automatically pulls everything into your site. Bootstrap loads all the CSS styles and JS for you unless you go in and remove the files that you don’t want. Bootstrap knows that it can be bulky and on the docs, they even recommend ways to make it leaner.
To customize Bootstrap, you set your variable overrides high in the list of SCSS files and it will set that variable in the CSS.
/* Required */
@import "../node_modules/bootstrap/scss/functions";
/* Your Custom Variables */
$custom-colors: (
"custom-color": #fa6f23;
);
$navbar-padding-y: $spacer * .5;
$navbar-padding-x: $spacer * .8;
$font-family-base: 'Roboto', Arial, sans-serif;
/* Merge the colors back into the theme-colors */
$theme-colors: map-merge($theme-colors, $custom-colors);
/* Required */
@import "../node_modules/bootstrap/scss/variables";
@import "../node_modules/bootstrap/scss/maps";
@import "../node_modules/bootstrap/scss/mixins";
@import "../node_modules/bootstrap/scss/root";
You can change colors, spacing, and fonts to match the site design. Bootstrap has a limited amount of SCSS variables so if you don’t see one that will work, you will need to create your own custom SCSS variable. For a new developer, Bootstrap may be easier to learn as most of it is just SCSS. Menu dropdowns, carousels and pagination are already set up so all you need to do is add them in and style them to match the design. Bootstrap served me well for many years but the large files and the challenges of customizing were a pain point.
Tailwind
When I started at Viget I was really excited to start working in Tailwind. With so many years of writing CSS, it took some time to remember the Tailwind class for the CSS properties. Some of the classes are easier to remember and some are a bit harder.
You can still do custom CSS in Tailwind like a normal stylesheet with:
/*Your custom css file*/
@layer components {
.button-default {
background: #eee;
/* or with @apply */
@apply rounded-b-lg shadow-md;
}
}
But this can get messy if you find that you need three or more different button styles for the site. That can lead you right back to writing custom CSS for all your styles, which defeats the benefits of Tailwind. This is where the config file come in really handy. It has all your site variables in one place and instead of overwriting the CSS it takes the config file and creates the CSS from that file.
//tailwind.config.js
module.exports = {
theme: {
colors: {
transparent: 'transparent',
black: '#000',
white: '#fff',
gray: {
100: '#f7fafc',
// other gray colors
900: '#1a202c',
},
}
}
}
You can still run into limitations with just the config file, which is when I started learning about Tailwind plugins. A Tailwind plugin allows you to pass in variables such as colors, padding, font size, and or anything you want to pass into it and the plugin exports a set of custom classes and CSS. This header plugins allows you to set the font size and font weight and the plugin will output the CSS classes. You could pass in more options like color, font family, line height and so on. See it working in Tailwind Play.
//heading.js
const plugin = require('tailwindcss/plugin')
module.exports = plugin(function({ matchUtilities, theme }) {
matchUtilities(
{
hd: (value) => value,
},
{ values: theme('heading') }
)
})
// Then pass in variables with
module.exports = {
theme: {
extend: {
heading: {
xl: {
fontSize: '10rem',
fontWeight: '900',
},
lg: {
fontSize: '6rem',
fontWeight: '500',
},
md: {
fontSize: '3rem',
fontWeight: '300',
},
},
},
},
// Then in your tailwind.config.js file you require the plugin
// or put it in your plugin section in the config
plugins: [
require('./config/tailwind/heading.js'),
],
}
// Which will give you the classes
.hd-xl {
font-size: 10rem;
font-weight: 900;
}
.hd-lg {
font-size: 6rem;
font-weight: 500;
}
.hd-md {
font-size: 3rem;
font-weight: 300;
}
There is a lot you can do with Tailwind plugins, more are covered in this article, but the possibilities are endless. I was also amazed by the final file size from Tailwind. By default Tailwind only builds the CSS that is being used in the HTML which gives you a really small CSS files.
So which do I like better?
Tailwind is by far easier to use as a team because everyone is using the same classes. It is straightforward to jump into a project and start using Tailwind. If you are a UI or frontend developer I would go with Tailwind. Tailwind’s infrastructure keeps things organized and clear to understand.
If you are new to web development, make sure you are familiar with basic CSS before you jump headlong into Tailwind. If you are a developer that just needs a framework to be useable out of the box then either framework will be fine.
While I have not been working with Tailwind long, in the last year I have loved the flexibility and the endless possibilities to customize the framework that Tailwind provides. Want to learn more about Tailwind and how we use it at Viget? Checkout Tips for your Tailwind Config, How Does Viget CSS?, and Tailwind CSS for the Experienced Flyer. If you have not given Tailwind a shot, try it in your next project and let us know what you think.