Editor’s note: This post was updated 22 September 2022 to include information about the benefits of Tailwind CSS, why you should use it, if Tailwind CSS is easier and more popular than Bootstrap, and for general updates on Tailwind CSS v3.0.
We’re experiencing a renaissance of amazing web platforms and responsive design. Responsive user interfaces are often implemented using UI kits such as Bootstrap, Foundation, Bulma, and good old-fashioned media queries.
These UI kits enable us to easily implement directives to achieve the exact UI and proper responsiveness we require with less code. But have we been doing it right?
What if we could achieve a responsive UI without being bound by the rules of a UI kit? Is there a way to achieve responsiveness and still keep our custom user interface designs? For developers who value a high degree of customizability Tailwind CSS offers more flexibility than a UI kit such as Bootstrap.
In this guide, we’ll explore the differences between Tailwind CSS and Bootstrap, review some examples to demonstrate the advantages of using a utility-first CSS framework over a traditional UI kit, and highlight some of the most recent major changes to the ever-evolving Tailwind CSS framework.
@apply
According to the official documentation, Tailwind CSS is a utility-first CSS framework for rapidly building custom user interfaces. I like to think of it as a cool way to write inline styling and achieve an awesome interface without writing a single line of your own CSS.
In my opinion, the one thing that most developers will find a bit distracting with Tailwind CSS is the fact that your markup looks a lot busier than you might like. Tailwind CSS isn’t the first utility-first CSS library, but it is the most popular at the moment.
Tailwind CSS, unlike other CSS frameworks, is low-level and utility-first, which means it offers you a collection of classes you can slap onto your HTML and style, all without ever touching CSS.
Tailwind CSS provides developers lots of flexibility and control over how a component looks and feels, whereas typical UI kits come with several prebuilt components, thereby making it harder to create a unique UI. Its utility classes make it simple and quick to develop reusable components that align with your UI’s overall look and feel.
There are many benefits to using Tailwind CSS as opposed to using a traditional UI kit. Let’s go over some of the important benefits.
First, Tailwind CSS gives you a smaller CSS file size. Styling your web application with pure CSS requires you to write more CSS as you add more features and components to your web app. This causes your CSS files to increase in size and become heavier. With Tailwind CSS utility classes, you can simply create and apply reusable styles, so you rarely need to write new or any CSS at all.
Next, you can worry less about breaking changes. Utility classes in HTML, unlike CSS, are local. That is, you can update them without having to worry about breaking anything else on your web application. However, if you use the traditional method, making changes to CSS may break something in different part of your web app.
Tailwind CSS is also highly customizable. It’s generally a very flexible framework. Although it comes with a default setup, a tailwind.config.js
file can easily override it. The configuration file allows for simple adjustment of color palettes, styling, spacing, themes, and so forth.
Next, we have common utility patterns. With Tailwind CSS, you can avoid the effort of naming classes. The availability of common utility patterns solves a variety of difficulties, including class specification, organization, and cascading, among others. Utility classes make it easier to create custom components.
Finally, you can also remove unused CSS for optimization. PurgeCSS can be used to optimize Tailwind CSS, which is a significant advantage. PurgeCSS can significantly reduce file size by scanning the HTML and deleting unnecessary classes.
Bootstrap is the most popular HTML, CSS, and JavaScript framework for building responsive, mobile-first projects on the web. Tailwind CSS, on the other hand, is the most popular utility-first CSS framework for fast UI development.
The main difference between TailwindCSS and Bootstrap is that Tailwind CSS is not a UI kit. Unlike UI kits such as Bootstrap, Bulma, and Foundation, Tailwind CSS doesn’t have a default theme or inbuilt UI components. Instead, it comes with predesigned widgets you can use to build your site from scratch.
Bootstrap is known for its responsiveness, whereas proponents of Tailwind CSS typically value the framework’s customizability. The best choice for you depends on your priorities and project requirements, but let’s talk about why Tailwind CSS is quickly gaining popularity and more widespread use.
Is Tailwind CSS more widely used than Bootstrap? How can we be certain about this? To begin, let’s use GitHub data to establish which of the two CSS frameworks is more popular.
On GitHub, Tailwind CSS has 3.1k forks and 61.1k stars, while Bootstrap has 77.3k forks and 160k stars. We can make the general assumption from this that Bootstrap is more popular than Tailwind CSS. Here’s another fact: Bootstrap is seemingly more popular than Tailwind CSS, according to the most recent data from State of CSS on the awareness tab.
Frameworks like Bootstrap have abstracted the creation of components to the point where it compels developers to use only the available patterns provided. The same goes for other UI kit-type frameworks. Some might argue that overriding the framework with our own CSS is an option, but if we override a lot, then is there really any point in using the framework? We’d be pulling in the library and still writing our own code — this is just more files to worry about, and we are not even saving time.
Another problem I have found with Bootstrap sites is that they almost always look alike, so this inhibits our ability to incorporate creativity into the dev environment. This is one of the advantages of Tailwind CSS: its ability to easily build complex user interfaces without encouraging any two sites to look the same.
Another key advantage of using Tailwind CSS over Bootstrap is that, since apps and sites are composed of predesigned widgets, Tailwind CSS doesn’t impose difficult-to-reverse design decisions. Working with Tailwind CSS means using a set of utility classes that lets you work with exactly what you need. In my opinion, this is a neat way to create user interfaces that are more flexible to developers’ creativity.
Another advantage I really appreciate — and I am sure every frontend developer would also appreciate — is never having to worry about changes to one element affecting another related element. No more tabbing back and forth between HTML and style sheets in your editor, no more going back to check and see what you named that other element. In my opinion, this is the future.
Bootstrap is a component-based framework, which means it comes with prebuilt components and includes other utilities for layering displays, spacing, etc.
Tailwind, on the other hand, CSS is a utility-first framework. Using Tailwind CSS is akin to writing regular CSS. Unlike Bootstrap, it has no prebuilt components.
With Bootstrap’s prebuilt components, there is little CSS for you to write. As a result, subtle changes in the design could lead to hiccups. With Tailwind CSS, you style your elements from scratch using Tailwind’s styling syntax. It’s easier to make changes with Tailwind CSS because you only have to remove some CSS classes.
So which is easier, Tailwind CSS or Bootstrap? It depends largely on the use case and learning curve. If you’ve mastered CSS, you’re already well on your way to mastering Tailwind CSS. For this reason, Tailwind CSS is an excellent choice for most projects.
Although CDN is a good way to import styling in your project, many features of Tailwind CSS are not available using the CDN builds. To take full advantage of Tailwind’s features, you must first install Tailwind via npm.
Tailwind is available on npm and can be installed using npm or Yarn:
# Using npm npm install tailwindcss --save-dev # Using Yarn yarn add tailwindcss --dev
Next, create a Tailwind config file. Tailwind is configured almost entirely in plain JavaScript.
To do this, you’ll need to generate a Tailwind config file for your project. It is recommended to create a tailwind.js
file in your project’s root. The CLI utility helps you handle this easily:
# Using npm npx tailwind init [filename] # Using Yarn yarn tailwind init [filename]
If you’re an experienced Tailwind user who doesn’t need the comments in the config file, you can use the --no-comments
flag when generating your config file to strip them out.
Tailwind CSS is a utility-first library, which simply means that, unlike Bootstrap, Tailwind doesn’t provide automatically prestyled components. Rather, it provides utility classes that help us style our components in certain ways and allow us to build our own classes.
Let’s look at two simple examples to explore this concept.
See the Pen
Box example . by Ekwuno Obinna (@ekwunoobinna)
on CodePen.
From the above example, you can see how easy it is to implement a button component with Tailwind CSS.
The code below is a simple example of a card created with the Tailwind CSS framework . If you are familiar with CSS, you might already be able to make out some of the things going on with the styling. It might be a bit tricky to memorize all of this at first, but once you have some familiarity with the syntax, you will be alright.
The code snippet below has a container that has a shadow for large screens due to the shadow-lg
class and a white background implemented with bg-white
. You’ll also notice the px-4
and py-1
classes — these are just to help with padding in the x- and y-axes for the message button.
<div class="bg-white mx-auto max-w-sm shadow-lg rounded-lg overflow-hidden"> <div class="sm:flex sm:items-center px-6 py-4"> <img class="block h-16 sm:h-24 rounded-full mx-auto mb-4 sm:mb-0 sm:mr-4 sm:ml-0" src="https://avatars2.githubusercontent.com/u/4323180?s=400&u=4962a4441fae9fba5f0f86456c6c506a21ffca4f&v=4" alt=""> <div class="text-center sm:text-left sm:flex-grow"> <div class="mb-4"> <p class="text-xl leading-tight">Adam Wathan</p> <p class="text-sm leading-tight text-gray-400">Developer at NothingWorks Inc.</p> </div> <div> <button class="text-xs font-semibold rounded-full px-4 py-1 leading-normal bg-white border-2 border-purple-400 text-purple-500 hover:bg-purple-600 hover:text-white">Message</button> </div> </div> </div> </div>
Here is a CodePen that shows what the above code looks like:
See the Pen
Tailwind Css Card by Chidume David (@philipsz-davido)
on CodePen.
The default Tailwind configuration comes with 36.4KB minified and g-zipped. Compared to Bootstrap at 22.1KB , Tailwind is 14.3KB heavier. You might be thinking, ”Is this really the way to go in terms of performance?”
The reason for this is simple: Tailwind comes prepacked with a lot of options and styles for users to choose from, and it packs all these variations to reduce the tendency to write your own CSS. Fortunately, Tailwind comes with a few strategies you can use to keep your generated CSS small and performant.
Because the inbuilt utility modules in Tailwind use the plugin system under the hood, it’s possible to delete a ton of code and make the plugin system the way that new classes are registered inside Tailwind CSS.
This makes it possible to include only code we actually need in projects while ignoring everything else — unlike Bootstrap, in which there is a lot of overhead code. This upgrade feature shortens the build time from 158s to 8s.
We can get the exact amount of color variations we need in a project, like so:
module.exports = { // ... textColors: { 'black': colors['black'], 'grey-darker': colors['grey-darker'], 'grey-dark': colors['grey-dark'], 'red-dark': colors['red-dark'], 'red': colors['red'], 'blue-dark': colors['blue-dark'], 'blue': colors['blue'], // ... } }
Just made a nice O(n) to O(1) performance optimization to the @tailwindcss build process 💪🏻 You monsters using at-apply for everything will be happy 😇 — Adam Wathan (@adamwathan) March 1, 2018
Tailwind also removes unused CSS with PurgeCSS, a tool for removing unused CSS from your project. It does this by simply comparing the CSS class names available in your template against the class names used and then removing the unused CSS.
Tailwind CSS allows you to pick the exact amount of screen sizes you need. Here’s how defining fewer screens affects the output:
Tailwind CSS 2.2 introduced major optimizations to the Tailwind CLI tool. The Tailwind CLI was totally revamped from the ground-up to make it more performant.
With the upgraded CLI, Tailwind CSS requires no installation or configuration. You can pass subcommands to the Tailwind CLI to process CSS files to your specification. The command npx tailwindcss
can be passed subargs, so this does away with any Tailwind configuration; everything can be done via the command line.
Tailwind CLI can run in watch mode. This means that the Tailwind CLI runs in the background to watch for changes in our CSS and rebuilds the CSS whenever a change is detected. This is highly performant because it eliminates the need to rebuild your CSS manually after each change.
In addition, the Tailwind CLI now includes PostCSS plugin support. By creating a postcss.config.js
file and including PostCSS extra plugins, you can use the --postcss
flag in your npx tailwind
command to include the PostCSS plugins when building your CSS.
Finally, the revamped Tailwind CLI can be set to build your CSS for production. Building for production will cause the Tailwind CLI to remove unused CSS. This results in a highly optimized and smaller build, which leads to optimal performance because of the low file-size footprint. To set production, we use the NODE_ENV=production
and the --minify
flag to compress the CSS for an optimal build.
Tailwind is very flexible because it allows you to add your own utilities and provides a guide to help you implement this.
Let’s take a simple style implementation as an example. A normal Tailwind setup is a single CSS file that looks like this:
@tailwind preflight; @tailwind components; @tailwind utilities;
To override the default utilities, we would have to import the override last so that it’s applied first (which is a common CSS rule):
@tailwind preflight; @tailwind components; @tailwind utilities; .bg-cover-image { background-image: url('/path/to/image.jpg'); }
But if you’re using postcss-import
or a preprocessor like Less, Sass, or Stylus, keeping your utilities in a separate file and importing them would be the best move:
@tailwind preflight; @tailwind components; @tailwind utilities; @import "leveledup-utilities";
The same can be done for responsive layouts. Custom utilities will always take precedence over prefixed utilities as long as it is done properly.
@apply
Let’s say you’re reusing a certain button style in multiple places. Retyping the same type of specification for the same component becomes a bit boring. Not to worry: Tailwind has a way to reuse styling with @apply
.
Here’s an example:
<button class="btn-gray"> Button </button> <style> .btn-blue { @apply bg-gray text-white font-bold py-2 px-4 rounded; } .btn-gray:hover { @apply bg-gray-dark; } </style>
N.B.,
hover:
,focus:
, and{screen}:
utility variants can’t be mixed in directly.
On 17 June 2021, Tailwind released “one of the most feature-rich Tailwind releases of all-time,” Tailwind CSS v2.2. This release came on the heels of Tailwind CSS v2.1, which introduced Just-in-Time mode, a new JIT compiler that generates styles on demand as you write your templates rather than generating everything in advance at initial build time.
In addition to the new Tailwind CLI, the most recent major release includes the introduction of pseudo-class support, shorthand color opacity syntax, a host of new variants, and much more. Check out Tailwind’s release history to keep up with the most recent changes.
Let’s highlight a few features that were introduced in Tailwind v2.2.
first-letter
and first-line
variantsThis feature is a pseudo-element variant. It allows us to add the ::first-letter
and ::first-line
CSS pseudo-selectors to our elements.
The ::first-letter
CSS selector selects and styles the first letter of the element’s text node it was applied to.
<p class="first-letter:font-bold"> This blog post represents everything you can find in today's work. </p>
The above code will make the first letter of the p
element’s text node bolder than other letters in its text node.
<p class="first-letter:font-bold first-letter:text-4l"> This blog post represents everything you can find in today's work. </p>
The above code makes the first letter of the p
element’s text node bolder and larger than other letters in the text node. The ::first-line
pseudo-selectors style the first line of a block-level element.
<p class="first-line:text-red-500"> This blog post represents everything you can find in today's work. </p>
This turns the first line of the p
element’s text node to the color red. This feature is used in Tailwind CSS’s JIT mode.
before
and after
variantsThis new feature makes it possible to style before
and after
pseudo-elements. These pseudo-selectors insert some text before and after an element.
We can now use the before
and after
pseudo-selectors in Tailwind.
Here’s an example:
<p class="before:content-['B'] before:block before:bg-red-500"> This blog post represents everything you can find in today's work. </p>
The above adds the text B
add the beginning of the p
element. The background of the content is set to deep red. Let’s see how we can affect the after
selector with the same example:
<p class="after:content-['A'] after:block after:bg-red-500"> This blog post represents everything you can find in today's work. </p>
This adds the text A
at the end of the p
element. The text will appear in deep red.
This feature too is enabled in Tailwind’s JIT mode.
Tailwind CSS now includes a selection
text variant that enables you to style the selected text on an element.
<p class="selection:bg-blue-500"> This blog post represents everything you can find in today's work. </p>
This will style the background color of the selected text in the p
element to deep blue.
Like the other new features described above, the selection
text variant is available in JIT mode.
The marker
variant compiles down to the ::marker
pseudo-selector. It enables you to style the marker of a list item. This selector works on display:list-item
elements.
<ul class="marker:text-blue-500"> <li>Reactjs</li> <li>Vuejs</li> <li>Angular</li> <li>Svelte</li> <li>Nextjs</li> </ul>
The above code makes the color of the li
items deep blue. Tailwind CSS’s new features added basically all pseudo-classes, including:
only
(only-child
)first-of-type
last-of-type
only-of-type
target
default
indeterminate
placeholder-shown
autofill
required
valid
invalid
in-range
out-of-range
For a deeper dive into the new features introduced with Tailwind CSS v2.2, check the release history.
Tailwind CSS v3.0 is the latest release from Tailwind CSS, and this major upgrade comes with some really cool features. Let’s explore:
For more Tailwind CSS v3.0 features check out this blogpost. You can also check out the release history for a deeper dive into the new features.
In this article, we discussed all things Tailwind CSS vs. Bootstrap. We talked about their general differences, compared the two against various criteria, discussed updates to Tailwind, and more.
Thank you for sticking around this far!
As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording everything that happens in your web app, mobile app, or website. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.
Modernize how you debug web and mobile apps — start monitoring for free.
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowLearn how to implement one-way and two-way data binding in Vue.js, using v-model and advanced techniques like defineModel for better apps.
Compare Prisma and Drizzle ORMs to learn their differences, strengths, and weaknesses for data access and migrations.
It’s easy for devs to default to JavaScript to fix every problem. Let’s use the RoLP to find simpler alternatives with HTML and CSS.
Learn how to manage memory leaks in Rust, avoid unsafe behavior, and use tools like weak references to ensure efficient programs.
13 Replies to "Comparing Tailwind CSS to Bootstrap: Is it time to ditch UI kits?"
Need to update your code in the first example. `bg-purple` and `bg-purple-dark` no longer exist. Try `bg-purple-600 hover:bg-purple-800`
“Another advantage I really appreciate — and I am sure every front-end developer would also appreciate — is never having to worry about changes to one element affecting another related element.”
So if I change a component I need to change all other components manually to keep my layout consistent? That sounds really cumbersome and I don’t see how this is an improvement.
You can create your own classes to keep everything consistent.
(I hate Tailwind anyway)
Hey Bas!
You have two basic choices for repeated elements here:
1. use @apply in your CSS and build up your own class es for repeated components
2. use Vue-, React- or PHP-Components and just include them whereever needed.
It’s not too bad, for elements that lie beyond direct control, like WordPress’ WYSIWYG-Fields I just wrap that in a content class and use apply to style elements in there.
Cheerio.
To Bas,
No – there are at least two solutions to prevent that problem. Here are two different videos which show the two solutions:
https://tailwindcss.com/course/composing-utilities-with-apply
https://tailwindcss.com/course/extracting-reusable-components
Also for Bas,
It can also depend on where you want to put your eggs.
Do you want components you can guarantee won’t be effected or broken over time with a maximum css file size.
Or do you want to update a handful of classes in the off chance your design requirement might change half way through. Which even if it does change, you get the benefit of not breaking other components by changing your design requirements 🙂
People often forget that other programming languages apply the styling directly to the elements rather than global style sheets, so if it works for them! Can work for you
Nice introduction! Really helpful for beginners.
Tailwind button in first example does not appear to be rendering
It looks like ‘button’ needs to added to the class of the Tailwind button.
Have you written inline css in your dom element? Tailwind is something like that in the form of classes. Its makes your dom element dirty with too many classes. And for similar kind of components writing little classes is far more better than writing many classes again and again.
Boostrap grid and Less.That’s all i need.
This article feels like a very opinionated and honestly can’t see any real points why Tailwind is better than Bootstrap. First, can you define what do you mean by saying “UI kit”? Bootstrap has prebuilt templates but that is up to you to use it or not, it provides responsive classes too like Tailwind if you need to have more control over what you are building. So having prebuilt templates and all what Tailwind provides I would go with Bootstrap any time. Just because Tailwind is new does not make the case, COVID-19 was new too, but no one liked it since it took a few years from our lives.
Talk about re-inventing the wheel. Bootstrap has the exact same utility classes and more and yet people ignorant of these think they’ve stumbled on the holy grail.