# Setting up Tailwind CSS with Flask

Jakub Svehla—Nov 13, 2020

Recently, I have decided to switch from Tachyons to Tailwind and while I really like Tailwind and the ecosystem around it, setting it up in my Flask project was quite a pain for me. I guess it's fairly simple if you are a front end developer and have some CSS build system in place but I was using no such thing and was simply importing all CSS libraries using the link tag. And while it's possible to import Tailwind using the link tag, most of the stuff that makes it so powerful, such as customization, is only possible when using a proper build pipeline.

We will be using Flask-Assets to manage our assets pipeline so let's first install it.

pip install Flask-Assets


Next, let's install Tailwind, PostCSS (a CSS preprocessor used by Tailwind), Autoprefixer and PurgeCSS.

npm install tailwindcss postcss-cli autoprefixer @fullhuman/postcss-purgecss


Now, in your Flask app, let's create a CSS bundle that will take all source CSS files and processes them using PostCSS.

from flask_assets import Environment, Bundle

assets = Environment()
assets.init_app(app)

css = Bundle('src/css/*.css', filters='postcss', output='dist/css/main.css')
assets.register('css', css)


## Set up PostCSS

The tricky part was setting up the PostCSS (using the postcss.config.js file) because for some reason webassets (which is used internally by Flask-Assets) changes its working directory when executing postcss binary and executes it inside the directory where the currently processed CSS file is. PostCSS is able to find your postcss.config.js (which is typically in the root directory of your project) by walking up the directory until it finds one but Tailwind expects its config file (tailwind.config.js) to be in the current working directory by default so you have to explicitely tell it where to find it.

That's why we have to set all paths relative to the postcss.config.js file (using __dirname variable) instead of relative to the current working directory.

Below is our final postcss.config.js:

const path = require('path');

module.exports = (ctx) => ({
plugins: [
require('tailwindcss')(path.resolve(__dirname, 'tailwind.config.js')),
require('autoprefixer'),
ctx.env === 'production' && require('@fullhuman/postcss-purgecss')({
content: [
path.resolve(__dirname, 'templates/**/*.html')
],
defaultExtractor: content => content.match(/[A-Za-z0-9-_:/]+/g) || []
})
]
})


Also, note that in production we use PurgeCSS to remove all unused CSS classes by scanning all HTML templates in your project.

## Set up Tailwind CSS

Finally, let's customize Tailwind using the tailwind.config.js file (in your project root) to see that all is set correctly.

const defaultTheme = require('tailwindcss/defaultTheme')

module.exports = {
future: {
// removeDeprecatedGapUtilities: true,
// purgeLayersByDefault: true,
},
purge: [],
theme: {
extend: {
fontFamily: {
sans: ['Inter var', ...defaultTheme.fontFamily.sans],
},
},
},
variants: {},
plugins: [
require('@tailwindcss/ui'),
],
}


If you have any comments, feedback or questions, let me know on Twitter or via email.