Using CSS Cascade Layers With Tailwind Utilities


Adam Wathan has (very cleverly) built Tailwind with CSS Cascade Layers, making it extremely powerful for organizing styles by priority.

@layer theme, base, components, utilities;
@import 'tailwindcss/theme.css' layer(theme);
@import 'tailwindcss/utilities.css' layer(utilities);

The core of Tailwind are its utilities. This means you have two choices:

  1. The default choice
  2. The unorthodox choice

Table of Contents

The default choice

The default choice is to follow Tailwind’s recommended layer order: place components first, and Tailwind utilities last.

So, if you’re building components, you need to manually wrap your components with a @layer directive. Then, overwrite your component styles with Tailwind, putting Tailwind as the “most important layer”.

/* Write your components */
@layer components {
  .component {
    /* Your CSS here */
  }
}
 

...

That’s a decent way of doing things.

But, being the bad boy I am, I don’t take the default approach as the “best” one. Over a year of (major) experimentation with Tailwind and vanilla CSS, I’ve come across what I believe is a better solution.

The Unorthodox Choice

Before we go on, I have to tell you that I’m writing a course called Unorthodox Tailwind — this shows you everything I know about using Tailwind and CSS in synergistic ways, leveraging the strengths of each.

Shameless plug aside, let’s dive into the Unorthodox Choice now.

In this case, the Unorthodox Choice is to write your styles in an unnamed layer — or any layer after utilities, really — so that your CSS naturally overwrites Tailwind utilities.

Of these two, I prefer the unnamed layer option:

/* Unnamed layer option */
@layer theme, base, components, utilities; 

/* Write your CSS normally here */ 
.component { /* ... */ }
/* Named layer option */
/* Use whatever layer name you come up with. I simply used css here because it made most sense for explaining things */
@layer theme, base, components, utilities, css; 

@layer css {
  .component { /* ... */ }
}

I have many reasons why I do this:

  1. I don’t like to add unnecessary CSS layers because it makes code harder to write — more keystrokes, having to remember the specific layer I used it in, etc.
  2. I’m pretty skilled with ITCSS, selector specificity, and all the good-old-stuff you’d expect from a seasoned front-end developer, so writing CSS in a single layer doesn’t scare me at all.
  3. I can do complex stuff that are hard or impossible to do in Tailwind (like theming and animations) in CSS.

Your mileage may vary, of course.

Now, if you have followed my reasoning so far, you would have noticed that I use Tailwind very differently:

  • Tailwind utilities are not the “most important” layer.
  • My unnamed CSS layer is the most important one.

I do this so I can:

  • Build prototypes with Tailwind (quickly, easily, especially with the tools I’ve created).
  • Shift these properties to CSS when they get more complex — so I don’t have to read messy utility-littered HTML that makes my heart sink. Not because utility HTML is bad, but because it takes lots of brain processing power to figure out what’s happening.

Finally, here’s the nice thing about Tailwind being in a utility layer: I can always !important a utility to give it strength.


...

Whoa, hold on, wait a minute! Isn’t this wrong, you might ask?

Nope. The !important keyword has traditionally been used to override classes. In this case, we’re leveraging on the !important feature in CSS Layers to say the Tailwind utility is more important than any CSS in the unnamed layer.

This is perfectly valid and is a built-in feature for CSS Layers.

Besides, the !important is so explicit (and used so little) that it makes sense for one-off quick-and-dirty adjustments (without creating a brand new selector for it).

Tailwind utilities are more powerful than they seem

Tailwind utilities are not a 1:1 map between a class and a CSS property. Built-in Tailwind utilities mostly look like this so it can give people a wrong impression.

Tailwind utilities are more like convenient Sass mixins, which means we can build effective tools for layouts, theming, typography, and more, through them.

You can find out about these thoughts inside Unorthodox Tailwind.

Thanks for reading and I hope you’re enjoying a new way of looking at (or using) Tailwind!


Share this content:

I am a passionate blogger with extensive experience in web design. As a seasoned YouTube SEO expert, I have helped numerous creators optimize their content for maximum visibility.

Leave a Comment