This article is Part 2 in a 3-Part series.

Tailwind and Sass

Jekyll supports Sass out of the box. Tailwind uses PostCSS to do its magic. Here I will use the jekyll-webpack gem to bind them into a nice compressed bundle. While you can use pure postcss with no webpack to generate optimised tailwind, I prefer to use a fully featured asset bundler that can also be used for more complex pipelines, eg JS, images and SVG.

Firstly, you need to install the jekyll-webpack plugin in your jekyll site. You can see that in Part 1 or follow the README for instructions.

Then, at the base of your jekyll project folder (assuming you’re using yarn but npm is fine) run:

yarn add --dev webpack tailwindcss@npm:@tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9

This will install the compat versions that you need.

Now create the following three files in the root folder of the project.

// webpack.config.js

const path = require('path');
const glob = require('glob')

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

const PATHS = {
  src: path.join(__dirname, '.')
}

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  plugins: [
    new MiniCssExtractPlugin()
  ],
  module: {
    rules: [
      {
        test: /\.m?js$/,
        exclude: /(node_odules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      },
      {
        test: /\.css$/,
        use: [
          'style-loader',
          MiniCssExtractPlugin.loader,
          'css-loader',
          {
            loader: 'sass-loader',
            ident: 'sass',
            options: { sourceMap: true }
          },
          {
            loader: 'postcss-loader',
            options: {
              ident: 'postcss',
              sourceMap: true,
            },
          },
        ]
      }
    ]
  }
};
// tailwind.config.js

module.exports = {
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
}
// postcss.config.js

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

This gives you the basic configuration that you need to compile static assets including a highly optimised bundle, since Tailwindcss has a purge option built in, there is no need to include a seperate PurgeCSS

As you can see we specified the JS entry point to be ./src/index.js in the webpack.config.js

Now we create that file and in it add:

// ./src/index.js

import './tailwind.css';

Now we create the the ./src/tailwind.css file and apply all the tailwind specific syntax here (@tailwind, @apply, …)

/* ./src/tailwind.css */

@tailwind base;
@tailwind components;
@tailwind utilities;

/* add some custom responsive utilities */
@responsive {
  .top-1\/2 {
    @apply top-50per;
  }

  .bottom-1\/2 {
    @apply bottom-50per;
  }

  .left-1\/2 {
    @apply left-50per;
  }

  .right-1\/2 {
    @apply right-50per;
  }

  .top-1\/4 {
    @apply top-25per;
  }

  .bottom-1\/4 {
    @apply bottom-25per;
  }

  .left-1\/4 {
    @apply left-25per;
  }

  .right-1\/4 {
    @apply right-25per;
  }

  .top-3\/4 {
    @apply top-75per;
  }

  .bottom-3\/4 {
    @apply bottom-75per;
  }

  .left-3\/4 {
    @apply left-75per;
  }

  .right-3\/4 {
    @apply right-75per;
  }
}

NOTE: It’s important to keep this file as a seperate CSS file from any SASS files that you might be using as it can cause problems when purging the necessary selectors.

Next if we create a simple index.markdown and add some tailwind css to it:-

---
layout: default
---

<div class='top-1/2 sm:top-1/2 md:top-1\/2 flex justify-center items-end w-full h-screen bg-fixed bg-center bg-no-repeat bg-cover'>
  <div id='logo' class='flex items-center justify-center text-center flex-col mb-4 mt-4'>
    MML
  </div>
</div>

Now, if you run NODE_ENV=production jekyll build the resulting bundle will be optimised to use only the custom utilities that you referenced in the markup. Pretty neat!