Introduction
Tailwind CSS has taken the front end development world by storm. If you haven't heard of it yet, Tailwind describes itself as, "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." Rather than using semantic class names (like "button" or "title"), you utilize these smaller utility classes to build your components.
There are many ways to integrate Tailwind within a Vue application. In this article, we'll be talking about a few of the best practices for installing and utilizing Tailwind in a Vue application.
Vue CLI
Installing Tailwind in a Vue CLI app is probably the easiest experience available. There is a CLI plugin that does everything we need, including installing Tailwind, and configuring PostCSS for us. Even better, it works for both Vue 2 and 3!
In your terminal, at the root of your application, run the following command:
vue add tailwind
The CLI will then install the plugin. You will be asked how complete a Tailwind configuration file you want (none, minimal, or full). Choose "minimal" for now - it will create the file, but will not populate it with any custom values. Once the terminal has finished, you're done!
There are a couple considerations to keep in mind when using this approach:
- As of this writing, the CLI plugin has not been updated in a few months. It is currently installing Tailwind version 2.0.2 (the current latest is 2.2.4). This is easy enough to adjust manually, but you need to be aware of it to make the change yourself.
- The plugin is also providing the PostCSS 7 compatible build. For the most part, this doesn't make a huge difference. The Tailwind docs notes that the compatibility build is identical with the main build, so you won't be missing out on any features. For now, this should be fine, but it could lead to issues down the road if you want to use PostCSS 8 plugins (or if Tailwind decides to stop providing backwards-compatible builds). If you're using Vue 3.0.6 or greater, you should be able to upgrade to the main builds. However, your should make sure to update all your PostCSS plugins to the latest main builds, not just Tailwind.
Vite
The Tailwind Docs include instructions on installing Tailwind with Vite. While it isn't as straightforward as the Vue CLI plugin, it's still pretty simple to get started in Vite.
First, install Tailwind, PostCSS 8, and Autoprefixer in your repository:
npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
Then, run the Tailwind CLI command to create a default configuration file for both Tailwind and PostCSS:
npx tailwindcss init -p
This will create two files:
- tailwind.config.js
- postcss.config.js
Unless you want to make a change to either Tailwind or PostCSS, you won't have to touch these files. The docs recommend that you configure the purge
option, which is used by Tailwind to purge its unused styles. With this change, your tailwind.config.js
file should look like this:
// tailwind.config.js
module.exports = {
mode: 'jit',
purge: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
darkMode: false, // or 'media' or 'class'
theme: {
extend: {},
},
variants: {
extend: {},
},
plugins: [],
}
Note that we also added the mode: 'jit'
key to the configuration. This enables Tailwind's Just-In-Time mode, which is a more performant experience, and enables a number of other Tailwind features. Read the documentation to learn more, and better understand what you're getting out of this.
Now, let's create a base CSS file to import Tailwind's classes into. The Tailwind docs suggest using ./src/index.css
, but I would recommend creating a separate CSS file just for Tailwind. Let's call it tailwind.css
. In that file, put the following:
/* ./src/tailwind.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
This uses PostCSS to import the various classes and utilities that Tailwind uses. Then, we just need to import this file in our main.js
file like this:
// ./src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import './index.css'
import './tailwind.css'
createApp(App).mount('#app')
And we're done! Tailwind is now available in your Vite application. Make sure to clear out the index.css
file of any styles you do not want. In practice, that file will probably be much smaller than you may be used to, but it's still useful to keep your custom styles separate from Tailwind.
Nuxt
Nuxt has an amazing plugin ecosystem, and there is a Tailwind plugin available for us to use here as well. Unlike with Vue CLI, there's a bit more manual work involved to install a Nuxt plugin, so let's get started!
First, make sure your Nuxt application is at least version 2.15.3. This is the release of Nuxt that supports PostCSS 8. Unlike Vue CLI, this plugin provides the main build of Tailwind, not the compatibility build for PostCSS 7. You can upgrade Nuxt by running npm update nuxt
.
Once you have confirmed that your Nuxt app is ready, run the following command in your terminal:
npm install --save-dev @nuxtjs/tailwindcss postcss@latest
This will install Tailwind and its required plugins for you. Then, in your nuxt.config.js, add the plugin to your buildModules
:
export default {
buildModules: ['@nuxtjs/tailwindcss']
}
Finally, run npx tailwindcss init
to create the Tailwind configuration file. And that's it! Tailwind is now ready to go in your Nuxt application.
You may notice that there's a lot less work here than in Vite (and a lot fewer files being created than in Vue CLI). With the Nuxt plugin, if you do not have a tailwind.css
file where styles are being injected, Nuxt will create it for you (the same is true for the tailwind.config.js
file, but typically you'll want that anyway to enable JIT mode, or other custom configurations).
Tailwind Viewer
One benefit of the Nuxt plugin is the Tailwind Viewer. This allows you to previous the styles currently enabled in your Tailwind configuration, and copy/paste the classes into your UI. By itself this is a great feature, but when you start working with custom colors or other features, it can be invaluable to preview them before adding the classes to your template.
Conclusion
We've walked through adding Tailwind to a Vue application in three of the most common tools to build Vue applications. In general, the process is the same:
- Install Tailwind, PostCSS, and Autoprefixer
- Configure Tailwind and PostCSS
- Import a CSS file that includes the Tailwind classes to your application
If you are using a custom setup for your Vue site, you should be able to apply these steps to your own setup in order to get Tailwind up and running. There are also a number of resources available if you run into any problems, including a Discord server and GitHub Discussions, where you can ask for help from other Tailwind users.
A note on utility-first CSS
As I'm writing this, I'm aware that utility-first CSS is not for everyone. If that sounds like you, and you made it this far, one thing about Tailwind that isn't highlighted as much as it should be is how the configuration allows for building a coherent design system. How often do you see multiple configuration files for Sass that are nothing but variables ($primary
, $red
, etc.)? All of this can be handled within Tailwind's configuration file, with the added benefit of generating classes for text, backgrounds, borders, and more to utilize those colors. Also, Tailwind already comes built-in with a number of great design decisions for padding and margin, flexbox, and more, making the work of building a design system that much easier.
Also, Tailwind provides a special directive, @apply
, that lets you utilize Tailwind classes in standard CSS. This means that, rather than using the utility classes Tailwind provides in your template, you can build out custom classes (like .card
or .button
) while still benefitting from Tailwind's other features. Even better, using a plugin like PostCSS Nested, you can get nested CSS, just like in Sass or other CSS preprocessors.
Conisder the following component:
<template>
<button class="bg-red-100 px-4 py-3 hover:bg-red-300">
Tailwind Button
</button>
</template>
This is a fairly simple button, with a background color, padding on width and height, and a hover attribute. Already, we can see a number of other changes to make (add some drop shadow, transitions, different styles for disabled state, and so on). Using purely Tailwind, that could lead to a large number of classes on the button element.
Let's say you don't like having those large class attributes, but you still want the other benefits of Tailwind. Here's the same example, using @apply
to build a custom .button
class:
<template>
<button class="button">
Class Button
</button>
</template>
<style lang="postcss">
.button {
@apply bg-red-100 px-4 py-3;
&:hover {
@apply bg-red-300;
}
}
</style>
Nice! Our template is a lot simpler, and the styles are contained in our style block. That said, most Tailwind users will probably want to go without using @apply
(Adam Wathan, the creator of Tailwind, has said that he almost never uses @apply
). That doesn't make this any less valid, and is a perfect way to balance to strengths of Tailwind with traditional methodologies of writing CSS like BEM. If you're hesitant to try Tailwind because of its large number of classes, give this a try and see how you like it!
And remember, the goal of using Tailwind or any other CSS framework or methodology is to build a stellar experience for your application's users. Don't lose focus of that while deciding whether to adopt Tailwind in your latest Vue application. Try it out, see if it works for you, and decide for yourself whether it fits your project or style of writing CSS.
Until next time!