Tarik Hamilton

I Added Tailwind CSS to An Existing WordPress Stylesheet

Tailwind CSS is a utility-first CSS framework. Tailwind has a CSS class for just about every CSS property you’d like to express and instead of writing CSS, you use these classes to rapidly build out pages. That may sound beyond stupid to you, but Adam Wathan, Tailwind creator, explains how he arrived here in a very relatable journey in finding the best approach to writing CSS and CSS architecting.

I added Tailwind CSS to my existing stylesheet on this website. When I first was shown Tailwind, I was told to try it out on a new project. I did do that … sorta. I wanted to convert a very fresh Laravel app that was already started with Bootstrap to Tailwind. I slowly phased Bootstrap out, but I noticed that having CSS loaded from both frameworks didn’t really pose much of an issue.

When I wanted to add a new section to my website, the header on the front page, I knew it’d require some new CSS. I started the new theme about two years ago, and even though my CSS is simple and easy to use, I didn’t like my approach anymore.

My Existing CSS Architecture

I was very obsessed with “separation of concerns” when I started this theme. The obsession started at my first development job. I was finishing a WordPress theme that mixed in some utility classes for spacing. I was having trouble getting the spacing consistent and some of the utility classes juxtaposed with Bootstrap utility classes caused the layout to break. I didn’t realize the inconsistencies were coming from the utility classes.

After that website, I started using Bootstrap’s grid utility classes only. A lot of developers did this too, though Bootstrap provides you actual mixins for the column style, so col-sm-6 header-left could just be header-left with the column mixin. Once I discovered this, I realized that all my styling could be done in the stylesheet, achieving what I felt was “separation of concerns.” I later improved nesting issues with BEM, and eventually, I began using “content-agnostic” components like card and used BEM modifiers for variants.

So, tarikhamilton-dot-com used the above approach. I used the Bootstrap grid mixins, created some basic design tokens, partials (like the blog post), and basic typography. This gave me a very lean stylesheet. 35 KB / 7 KB gzipped. This was really good for adding Tailwind because I didn’t use any generic class names. There shouldn’t be any name collisions.

Integrating Tailwind Efficiently

If you demo Tailwind out, you’ll probably use the default CSS config which is like 400-500 KB (45 KB gzipped).

That’s 6-7x larger than my current stylesheet alone. However, I knew if I kept adding custom CSS and used the mixin approach, I felt the CSS file would grow and grow.

I also didn’t want to do too much CSS architecting. If I wanted some cool custom pages, I could have a bunch of SCSS imports with scoped classes and all this work. This is my personal blog, not paid work.

Tailwind works as a PostCSS plugin. Tailwind also works as a CLI tool, so if PostCSS is something you haven’t learned yet, you could still make a custom config using the Tailwind CLI. So, your setup may look different.

postcss.config.js

module.exports = {
	plugins: [require( "tailwindcss" ), require( "autoprefixer" )( {} )]
};

The PostCSS config is very straight forward … almost. Order matters. I had issues with tailwind being required after autoprefixer.

tailwind.config.js

module.exports = {
  theme: {
    screens: {
      xs: '320px',
      sm: '480px',
      md: '768px',
      lg: '1024px',
      xl: '1280px'
    },
    colors: {}, // 50% of Tailwind's size!
    textColor: {},
    fontFamily: {},
    placeholderColor: {}
  },
  variants: {},
  plugins: []
}

This is where the magic happens. In the docs, you’ll see theme: { extends: { ...yourSettings } }, but if you want to remove anything from Tailwind’s output, just override the property on theme. The thing that made the biggest difference was removing the colors. It cut the project in half.

I added a xs to screens because Tailwind didn’t have one, but Bootstrap did, and I wanted the grids to match up. Yes, with Tailwind, it is that easy to define new breakpoints.

Why did I remove colors? I already have a color system. And while I can override the color values that Tailwinds provides, even changing their names to match mine, I already have this system in place and I didn’t want to invest the time in changing it. I mainly wanted the grid/flex helpers. That’s the great thing about Tailwind. The configurability makes it very flexible for any use case or environment.

style.scss

$screen-xs: 320px;
$screen-sm: 480px;
$screen-md: 768px;
$screen-lg: 1024px;
$screen-xl: 1280px;

// Bootstrap can probably be phased out with Tailwind's flex grid

@import '~bootstrap/scss/functions';
@import '~bootstrap/scss/variables';
@import '~bootstrap/scss/mixins/breakpoints';
@import '~bootstrap/scss/mixins/grid';
@import '~bootstrap/scss/mixins/grid-framework';
@import '~bootstrap/scss/mixins/forms';
@import '~bootstrap/scss/grid';

@tailwind base; // has a reset built-in
@tailwind components;
@tailwind utilities;

@import 'abstracts/variables';
@import 'abstracts/mixins';

@import 'base/typography';
@import 'base/base';

@import 'layout/header';
@import 'layout/archive';
@import 'layout/content';
@import 'layout/single-post';
@import 'layout/forms';

@import 'components/article-snippet';
@import 'components/button';

@import 'pages/instagram-landing-page';

@import 'vendor/prism/prism';

Above is the final piece, my master SCSS file.

I put new screen size (breakpoint) variables for Bootstrap to match the ones in my Tailwind config. I have a lot of old code still using Bootstrap grid.

The @tailwind directive is processed by PostCSS. The PostCSS dependency is possibly the one quirky thing and your code editor might yell. You can apply Tailwind classes as mixins using the @apply directive.

.card {
  @apply mb-4 color-purple-500;
}

Again, a bit quirky and I am not a complete fan because it feels hard to change frameworks, if you ever wanted to, but also, how hard would it be to turn that back into normal CSS? Not very.

Small Price for a Good Experience

So, there you have it. A few small packages added, a config file, and now I have all these useful classes for building out unique one-off layouts. I mainly did this for landing pages and for when I wanted to be creative with layouts.

With some utilities removed, my existing CSS + Tailwind went from (75 KB to 50 KB gzipped. edit: 27 KB apparently). That’s a price I’m willing to pay to make things a little easier to modify.

I need to acknowledge that Bootstrap has utility classes too. They have Sass variable configs and you can pretty much match all of these features. Tailwind is also not the first utility framework. This is also a good thing because if you like the Tailwinds approach, you could probably recreate the output of other utility frameworks using Tailwind.

So, yeah, I’m digging this new CSS framework. It isn’t life changing, but I enjoy the shift and we’ll see how it is when used exclusively in my Laravel project. I think the thing that most appeals to me about Tailwind is that the config is super simple, it feels more barebones, and there are no packaged components or JavaScript.

If you want to talk to me about Tailwind, hit me up on Twitter!