DEV Community

Cover image for Setting up Tailwind CSS with Flask
Jakub Švehla
Jakub Švehla

Posted on • Originally published at

Setting up Tailwind CSS with Flask

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.

Set up your Flask app

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

pip install Flask-Assets
Enter fullscreen mode Exit fullscreen mode

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

npm install tailwindcss postcss-cli autoprefixer @fullhuman/postcss-purgecss
Enter fullscreen mode Exit fullscreen mode

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()

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

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')),
        ctx.env === 'production' && require('@fullhuman/postcss-purgecss')({
            content: [
                path.resolve(__dirname, 'templates/**/*.html')
            defaultExtractor: content => content.match(/[A-Za-z0-9-_:/]+/g) || []
Enter fullscreen mode Exit fullscreen mode

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: [
Enter fullscreen mode Exit fullscreen mode

This post was originally published on my personal blog.

Top comments (0)