Close Menu
    DevStackTipsDevStackTips
    • Home
    • News & Updates
      1. Tech & Work
      2. View All

      CodeSOD: A Unique Way to Primary Key

      July 22, 2025

      BrowserStack launches Figma plugin for detecting accessibility issues in design phase

      July 22, 2025

      Parasoft brings agentic AI to service virtualization in latest release

      July 22, 2025

      Node.js vs. Python for Backend: 7 Reasons C-Level Leaders Choose Node.js Talent

      July 21, 2025

      The best CRM software with email marketing in 2025: Expert tested and reviewed

      July 22, 2025

      This multi-port car charger can power 4 gadgets at once – and it’s surprisingly cheap

      July 22, 2025

      I’m a wearables editor and here are the 7 Pixel Watch 4 rumors I’m most curious about

      July 22, 2025

      8 ways I quickly leveled up my Linux skills – and you can too

      July 22, 2025
    • Development
      1. Algorithms & Data Structures
      2. Artificial Intelligence
      3. Back-End Development
      4. Databases
      5. Front-End Development
      6. Libraries & Frameworks
      7. Machine Learning
      8. Security
      9. Software Engineering
      10. Tools & IDEs
      11. Web Design
      12. Web Development
      13. Web Security
      14. Programming Languages
        • PHP
        • JavaScript
      Featured

      The Intersection of Agile and Accessibility – A Series on Designing for Everyone

      July 22, 2025
      Recent

      The Intersection of Agile and Accessibility – A Series on Designing for Everyone

      July 22, 2025

      Zero Trust & Cybersecurity Mesh: Your Org’s Survival Guide

      July 22, 2025

      Execute Ping Commands and Get Back Structured Data in PHP

      July 22, 2025
    • Operating Systems
      1. Windows
      2. Linux
      3. macOS
      Featured

      A Tomb Raider composer has been jailed — His legacy overshadowed by $75k+ in loan fraud

      July 22, 2025
      Recent

      A Tomb Raider composer has been jailed — His legacy overshadowed by $75k+ in loan fraud

      July 22, 2025

      “I don’t think I changed his mind” — NVIDIA CEO comments on H20 AI GPU sales resuming in China following a meeting with President Trump

      July 22, 2025

      Galaxy Z Fold 7 review: Six years later — Samsung finally cracks the foldable code

      July 22, 2025
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»News & Updates»Tailwind’s @apply Feature is Better Than it Sounds

    Tailwind’s @apply Feature is Better Than it Sounds

    April 10, 2025

    By this point, it’s not a secret to most people that I like Tailwind.

    But, unknown to many people (who often jump to conclusions when you mention Tailwind), I don’t like vanilla Tailwind. In fact, I find most of it horrible and I shall refrain from saying further unkind words about it.

    But I recognize and see that Tailwind’s methodology has merits — lots of them, in fact — and they go a long way to making your styles more maintainable and performant.

    Today, I want to explore one of these merit-producing features that has been severely undersold — Tailwind’s @apply feature.

    What @apply does

    Tailwind’s @apply features lets you “apply” (or simply put, copy-and-paste) a Tailwind utility into your CSS.

    Most of the time, people showcase Tailwind’s @apply feature with one of Tailwind’s single-property utilities (which changes a single CSS declaration). When showcased this way, @apply doesn’t sound promising at all. It sounds downright stupid. So obviously, nobody wants to use it.

    /* Input */
    .selector {
      @apply p-4;
    }
    
    /* Output */
    .selector {
      padding: 1rem;
    }

    To make it worse, Adam Wathan recommends against using @apply, so the uptake couldn’t be worse.

    Confession: The `apply` feature in Tailwind basically only exists to trick people who are put off by long lists of classes into trying the framework.

    You should almost never use it 😬

    Reuse your utility-littered HTML instead.https://t.co/x6y4ksDwrt

    — Adam Wathan (@adamwathan) February 9, 2020

    Personally, I think Tailwind’s @apply feature is better than described.

    Tailwind’s @apply is like Sass’s @includes

    If you have been around during the time where Sass is the dominant CSS processing tool, you’ve probably heard of Sass mixins. They are blocks of code that you can make — in advance — to copy-paste into the rest of your code.

    • To create a mixin, you use @mixin
    • To use a mixin, you use @includes
    // Defining the mixin
    @mixin some-mixin() {
      color: red; 
      background: blue; 
    }
    
    // Using the mixin
    .selector {
      @include some-mixin(); 
    }
    
    /* Output */
    .selector {
      color: red; 
      background: blue; 
    }

    Tailwind’s @apply feature works the same way. You can define Tailwind utilities in advance and use them later in your code.

    /* Defining the utility */
    @utility some-utility {
      color: red; 
      background: blue; 
    }
    
    /* Applying the utility */
    .selector {
      @apply some-utility; 
    }
    
    /* Output */
    .selector {
      color: red; 
      background: blue; 
    }

    Tailwind utilities are much better than Sass mixins

    Tailwind’s utilities can be used directly in the HTML, so you don’t have to write a CSS rule for it to work.

    @utility some-utility {
      color: red; 
      background: blue; 
    }
    <div class="some-utility">...</div> 

    On the contrary, for Sass mixins, you need to create an extra selector to house your @includes before using them in the HTML. That’s one extra step. Many of these extra steps add up to a lot.

    @mixin some-mixin() {
      color: red; 
      background: blue; 
    }
    
    .selector {
      @include some-mixin(); 
    }
    
    /* Output */
    .selector {
      color: red; 
      background: blue; 
    }
    <div class="selector">...</div>

    Tailwind’s utilities can also be used with their responsive variants. This unlocks media queries straight in the HTML and can be a superpower for creating responsive layouts.

    <div class="utility1 md:utility2">…</div> 

    A simple and practical example

    One of my favorite — and most easily understood — examples of all time is a combination of two utilities that I’ve built for Splendid Layouts (a part of Splendid Labz):

    • vertical: makes a vertical layout
    • horizontal: makes a horizontal layout

    Defining these two utilities is easy.

    • For vertical, we can use flexbox with flex-direction set to column.
    • For horizontal, we use flexbox with flex-direction set to row.
    @utility horizontal {
      display: flex;
      flex-direction: row;
      gap: 1rem;
    }
    
    @utility vertical {
      display: flex;
      flex-direction: column;
      gap: 1rem;
    }

    After defining these utilities, we can use them directly inside the HTML. So, if we want to create a vertical layout on mobile and a horizontal one on tablet or desktop, we can use the following classes:

    <div class="vertical sm:horizontal">...</div>

    For those who are new to Tailwind, sm: here is a breakpoint variant that tells Tailwind to activate a class when it goes beyond a certain breakpoint. By default, sm is set to 640px, so the above HTML produces a vertical layout on mobile, then switches to a horizontal layout at 640px.

    Open Live Demo

    If you prefer traditional CSS over composing classes like the example above, you can treat @apply like Sass @includes and use them directly in your CSS.

    <div class="your-layout">...</div> 
    .your-layout {
      @apply vertical; 
    
      @media (width >= 640px) {
        @apply horizontal;
      }
    }

    The beautiful part about both of these approaches is you can immediately see what’s happening with your layout — in plain English — without parsing code through a CSS lens. This means faster recognition and more maintainable code in the long run.

    Tailwind’s utilities are a little less powerful compared to Sass mixins

    Sass mixins are more powerful than Tailwind utilities because:

    1. They let you use multiple variables.
    2. They let you use other Sass features like @if and @for loops.
    @mixin avatar($size, $circle: false) {
      width: $size;
      height: $size;
    
      @if $circle {
        border-radius: math.div($size, 2);
      }
    }

    On the other hand, Tailwind utilities don’t have these powers. At the very maximum, Tailwind can let you take in one variable through their functional utilities.

    /* Tailwind Functional Utility */
    @utility tab-* { 
      tab-size: --value(--tab-size-*);
    }

    Fortunately, we’re not affected by this “lack of power” much because we can take advantage of all modern CSS improvements — including CSS variables. This gives you a ton of room to create very useful utilities.

    Let’s go through another example

    A second example I often like to showcase is the grid-simple utility that lets you create grids with CSS Grid easily.

    We can declare a simple example here:

    @utility grid-simple {
      display: grid;
      grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
      gap: var(--gap, 1rem);
    }

    By doing this, we have effectively created a reusable CSS grid (and we no longer have to manually declare minmax everywhere).

    After we have defined this utility, we can use Tailwind’s arbitrary properties to adjust the number of columns on the fly.

    <div class="grid-simple [--cols:3]"> 
      <div class="item">...</div>
      <div class="item">...</div>
      <div class="item">...</div>
    </div>

    To make the grid responsive, we can add Tailwind’s responsive variants with arbitrary properties so we only set --cols:3 on a larger breakpoint.

    <div class="grid-simple sm:[--cols:3]"> 
      <div class="item">...</div>
      <div class="item">...</div>
      <div class="item">...</div>
    </div>
    Open Live Demo

    This makes your layouts very declarative. You can immediately tell what’s going on when you read the HTML.

    Now, on the other hand, if you’re uncomfortable with too much Tailwind magic, you can always use @apply to copy-paste the utility into your CSS. This way, you don’t have to bother writing repeat and minmax declarations every time you need a grid that grid-simple can create.

    .your-layout {
      @apply grid-simple; 
      @media (width >= 640px) {
        --cols: 3;
      }
    }
    <div class="your-layout"> ... </div>

    By the way, using @apply this way is surprisingly useful for creating complex layouts! But that seems out of scope for this article so I’ll be happy to show you an example another day.

    Wrapping up

    Tailwind’s utilities are very powerful by themselves, but they’re even more powerful if you allow yourself to use @apply (and allow yourself to detach from traditional Tailwind advice). By doing this, you gain access to Tailwind as a tool instead of it being a dogmatic approach.

    To make Tailwind’s utilities even more powerful, you might want to consider building utilities that can help you create layouts and nice visual effects quickly and easily.

    I’ve built a handful of these utilities for Splendid Labz and I’m happy to share them with you if you’re interested! Just check out Splendid Layouts to see a subset of the utilities I’ve prepared.

    By the way, the utilities I showed you above are watered-down versions of the actual ones I’m using in Splendid Labz.

    One more note: When writing this, Splendid Layouts work with Tailwind 3, not Tailwind 4. I’m working on a release soon, so sign up for updates if you’re interested!


    Tailwind’s @apply Feature is Better Than it Sounds originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    Source: Read More 

    Facebook Twitter Reddit Email Copy Link
    Previous ArticleRilasciato OpenSSH 10: Un aggiornamento significativo per la sicurezza e la crittografia
    Next Article Distribution Release: Pardus 23.4

    Related Posts

    News & Updates

    The best CRM software with email marketing in 2025: Expert tested and reviewed

    July 22, 2025
    News & Updates

    This multi-port car charger can power 4 gadgets at once – and it’s surprisingly cheap

    July 22, 2025
    Leave A Reply Cancel Reply

    For security, use of Google's reCAPTCHA service is required which is subject to the Google Privacy Policy and Terms of Use.

    Continue Reading

    How to Sort Dates Efficiently in JavaScript

    Development

    Create a unit testing framework for PostgreSQL using the pgTAP extension

    Databases

    CISO’s Guide To Web Privacy Validation And Why It’s Important

    Development

    CVE-2025-29287 – MCMS Ueditor Unrestricted File Upload Vulnerability

    Common Vulnerabilities and Exposures (CVEs)

    Highlights

    CVE-2024-53621 – Tenda AC1206 Buffer Overflow Vulnerability

    June 30, 2025

    CVE ID : CVE-2024-53621

    Published : June 30, 2025, 3:15 p.m. | 2 hours, 26 minutes ago

    Description : A buffer overflow in the formSetCfm() function of Tenda AC1206 1200M 11ac US_AC1206V1.0RTL_V15.03.06.23_multi_TD01 allows attackers to cause a Denial of Service (DoS) via a crafted POST request.

    Severity: 0.0 | NA

    Visit the link for more details, such as CVSS details, affected products, timeline, and more…

    Pinta 3.0 Released With New Effects and GTK4 Port

    April 12, 2025

    Samsung MagicINFO 9-servers doelwit van botnet, update niet beschikbaar

    May 8, 2025

    Authorities Seize Over 100 Servers of the Pro‑Russian NoName057(16) Hacktivist Network

    July 16, 2025
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

    Type above and press Enter to search. Press Esc to cancel.