Here’s a rewritten version of the article with a more polished and professional tone, while preserving the original insights and structure:

Tailwind @apply illustration

If you’ve followed my work for a while, you probably know I’m a fan of Tailwind CSS. But here’s a twist: I don’t particularly enjoy using raw, unstructured Tailwind. In fact, I find it quite unpleasant in its default form. That said, I do acknowledge that Tailwind’s underlying philosophy offers real advantages — especially when it comes to writing scalable, maintainable, and performant styles.

Today, I want to highlight one of Tailwind’s most underrated features: the @apply directive.

What @apply Actually Does

Tailwind’s @apply directive allows you to include utility classes directly inside your CSS. Think of it as a way to “copy and paste” Tailwind’s utility styles into your own custom CSS rules.

Typically, @apply is demonstrated with simple, single-property utilities — which doesn’t showcase its full potential. For example:

/* Input */
.selector {
@apply p-4;
}

/* Output */
.selector {
padding: 1rem;
}

Used this way, @apply doesn’t seem particularly useful — and even Tailwind creator Adam Wathan has suggested avoiding it in most cases. In a tweet, he admitted that @apply was mainly introduced to make Tailwind more approachable for newcomers who are hesitant about long utility class lists.

But I believe @apply deserves a second look — because when used thoughtfully, it’s far more powerful than it appears.

Tailwind’s @apply Is Similar to Sass @include

If you’ve worked with Sass before, you’re probably familiar with mixins. You define a mixin with @mixin and reuse it with @include — effectively injecting a block of styles wherever needed.

Example:

// Define the mixin
@mixin some-mixin() {
color: red;
background: blue;
}

// Use the mixin
.selector {
@include some-mixin();
}

/* Output */
.selector {
color: red;
background: blue;
}

Tailwind’s @apply works similarly. You can define a utility (or group of styles) and reuse it throughout your project:

/* Define the utility */
@utility some-utility {
color: red;
background: blue;
}

/* Apply the utility */
.selector {
@apply some-utility;
}

/* Output */
.selector {
color: red;
background: blue;
}

Why Tailwind Utilities Are More Flexible Than Sass Mixins

One key advantage of Tailwind utilities is that you can use them directly in your HTML — no need to write a CSS rule first. For instance:

@utility some-utility {
color: red;
background: blue;
}

With Sass, you’d need to define a selector to house your @include before referencing it in HTML:

@mixin some-mixin() {
color: red;
background: blue;
}

.selector {
@include some-mixin();
}

Tailwind also makes it easy to apply responsive variants directly in HTML — something Sass doesn’t offer out of the box:

A Practical Example: Vertical and Horizontal Layouts

Here’s a simple and useful example from Splendid Layouts, a component library I’ve developed:

– vertical: creates a vertical flex layout
– horizontal: creates a horizontal flex layout

We define them like this:

@utility horizontal {
display: flex;
flex-direction: row;
gap: 1rem;
}

@utility vertical {
display: flex;
flex-direction: column;
gap: 1rem;
}

Now, we can use them directly in our HTML:

This sets up a vertical layout on mobile, and switches to horizontal at the sm (640px) breakpoint. If you prefer using traditional CSS, you can apply these utilities like so:

.your-layout {
@apply vertical;

@media (min-width: 640px) {
@apply horizontal;
}
}

This approach makes your layouts more readable and maintainable — you can understand what’s happening just by glancing at the class names.

Tailwind Utilities vs Sass Mixins: Power Comparison

Sass mixins are more powerful in some ways. They support:

– Multiple arguments
– Conditional logic (e.g., @if, @for)

Example:

@mixin avatar($size, $circle: false) {
width: $size;
height: $size;

@if $circle {
border-radius: $size

Similar Posts