Setting up Tailwind CSS v2 with Vue.js

  You block advertising 😢
Would you like to buy me a ☕️ instead?

Tailwind CSS is one of the rising stars in the CSS framework world. It’s especially popular in the Laravel and Vue.js community. In this article, we learn how to set up Tailwind CSS to work with a Vue CLI powered application. Because Tailwind CSS is a utility-first CSS framework which provides a lot of utility classes out of the box, its file size without any optimizations is pretty massive. But luckily, we can use PurgeCSS to improve the final bundle size of our application tremendously. Unfortunately, we can’t use the Just-in-Time mode yet with Vue CLI because it requires the latest version of PostCSS (v8) to work.

If you want to take a look at the final code, you can check out the full code on GitHub.

In this article, you learn how to set up Tailwind CSS v2 and PurgeCSS with Vue.js manually. But if you use the Vue CLI, you can also use vue-cli-plugin-tailwind to get up and running even faster.

Table of Contents

Using Tailwind with Vue CLI

Before we can get started building Tailwind CSS powered Vue.js applications, we have to set it up.

npm uninstall tailwindcss postcss autoprefixer
npm install --save-dev tailwindcss@npm:@tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9
// postcss.config.js
const autoprefixer = require('autoprefixer');
const tailwindcss = require('tailwindcss');

module.exports = {
  plugins: [
    tailwindcss,
    autoprefixer,
  ],
};

If you get an error like TypeError: Invalid PostCSS Plugin found at: plugins[0] make sure that you installed the compat versions of the package.

After installing tailwindcss as a dependency of our project and adding it to the list of PostCSS plugins inside of our postcss.config.js file, we are ready to import Tailwind CSS into our project.

// src/assets/styles/index.css
@tailwind base;
@tailwind components;
@tailwind utilities;
 // src/main.js
 import Vue from 'vue';
 import App from './App.vue';

+import './assets/styles/index.css';

 Vue.config.productionTip = false;

 new Vue({
   render: h => h(App),
 }).$mount(`#app`);

First, we create a new index.css file in src/assets/styles and load all Tailwind related styles in it. Next, we import this newly created file inside of our main main.js entry point of our app.


Screenshots of three premium Vue.js templates.

Customizing the Tailwind configuration

If we want to change certain aspects of our Tailwind CSS setup, we can create a configuration file. This makes it possible to change things like the font family, colors, margins, and even the media query breakpoints, for example.

npx tailwind init

This creates a new file, tailwind.config.js in the root directory of our application. We can use this configuration file to adapt Tailwind CSS to our needs.

// tailwind.config.js
module.exports = {
  purge: [],
  theme: {
    extend: {},
  },
  variants: {},
  plugins: [],
};

Reducing the file size with PurgeCSS

Now we have everything set up to start building Tailwind powered applications. But if we take a closer look at the final bundle size of our app, we notice that Tailwind adds a considerable large chunk of CSS. Fortunately, we can work around this by enabling PurgeCSS.

 // tailwind.config.js
 module.exports = {
-  purge: [],
+  purge: [
+    './public/**/*.html',
+    './src/**/*.vue',
+  ],
   theme: {
     extend: {},
   },
   variants: {},
   plugins: [],
 };

We add the ./public/**/*.html add all *.html and *.vue files to the list of files PurgeCSS should check for classes that must be not removed. Make sure to add all relevant paths here. By default PurgeCSS does only run when building for production, so make sure that NODE_ENV is set to production when deploying to production.


Do you want to learn more about advanced Vue.js techniques?

Register for the Newsletter of my upcoming book: Advanced Vue.js Application Architecture.


Writing purgeable Vue components

As it’s stated in the official Tailwind CSS documentation, we have to follow some rules to avoid PurgeCSS removing CSS styles, which it is not supposed to remove.

<template>
  <Component
    :is="`h${level}`"
    :class="`font-light leading-tight text-${size}xl`"
  >
    <slot/>
  </Component>
</template>

In the example headline component above, we use template-strings to programmatically set the tag rendered for the component and the text size class. This is problematic when using PurgeCSS. Because that way, it does not know that the styles for the h1-6 tags and the text-1xl, text-2xl, … classes are necessary and must not be purged.

 <template>
   <Component
-    :is="`h${level}`"
+    :is="['h1', 'h2', 'h3', 'h4', 'h5', 'h6'][level - 1]"
-    :class="`font-light leading-tight text-${size}xl`"
+    class="font-light leading-tight"
+    :class="[
+      ...(size <= 1 ? ['text-1xl'] : []),
+      ...(size === 2 ? ['text-2xl'] : []),
+      ...(size === 3 ? ['text-3xl'] : []),
+      ...(size === 4 ? ['text-4xl'] : []),
+    ]"
   >
     <slot/>
   </Component>
 </template>

Unfortunately, this approach is a lot more verbose than the initial solution, but this is one of the tradeoffs we have to take when using PurgeCSS.

Keep in mind that every CSS class or HTML tag has to appear as plain text string somewhere in your Vue.js components if you don’t want PurgeCSS to remove the corresponding styles.

Wrapping it up

Although setting up Tailwind CSS to work with Vue.js is rather straightforward, things become a little more tricky after also adding PurgeCSS into the mix.

But this was only the beginning: now you are ready to read the next article about how to build reusable functional components with Tailwind CSS and Vue.js.

References


Do you want to learn how to build advanced Vue.js applications?

Register for the Newsletter of my upcoming book: Advanced Vue.js Application Architecture.



Do you enjoy reading my blog?

You can buy me a ☕️ on Ko-fi!

☕️ Support Me on Ko-fi