cssvue.jstailwind-csstailwind-css-4

How to use @apply in Tailwind v4?


Since Tailwind v4 update, all @apply directives have ceased to function.

The docs provide a workaround with @reference but the posted example is vague.

I tried this but it doesn't work:

<style lang="postcss">
// @reference './../../assets/styles/scss/main.scss'; // workaround (incorrect)
@reference "tailwindcss"; // should be sufficient

header {
  @apply bg-neutral-0; // used to work in Tailwind v3
}
(...)
</style>

When I inspect the Header in the browser, it doesn't have assigned any background color.

Edit. I was missing @tailwindcss/vite but some utility classes still don't work. I.e. @apply block works, but @apply bg-neutral-0 doesn't. It throws an error:

19:26:13 [vite] (client) hmr update /src/components/Header.vue?vue&type=style&index=1&lang.postcss (x2)  
Error: Cannot apply unknown utility class `bg-neutral-0`. Are you using CSS modules or similar and missing `@reference`? https://tailwindcss.com/docs/functions-and-directives#reference-directive

Solution

  • In fact, the primary recommendation from the creator of TailwindCSS is not to use @apply. Instead, use native CSS and achieve the required color codes or values through variables. The main goal of TailwindCSS is to provide styling through inline classes. I only mentioned this because if you don't force local formatting on the header, and instead simply apply bg-neutral-0 to the header element, it will work without issues.

    Now, let's deal with @apply. If you use @reference "tailwindcss";, you only have access to the default values, not the ones you defined yourself. To access your own values, such as --color-neutral-0, you need to reference your main CSS file, just like you did in the first line, and this has to be done with a relative reference.

    ./assets/styles/scss/main.scss

    @use "./tailwind.css";
    

    ./assets/styles/scss/tailwind.css

    @import "tailwindcss";
    
    @theme {
      --color-neutral-0: #111;
    }
    

    Header.vue

    <style lang="postcss">
    @reference "./../../assets/styles/scss/tailwind.css";
    
    header {
      @apply bg-neutral-0;
    }
    </style>
    

    I fully agree with Wongjn's explanations. If you set it up so that you can reference a CSS file, since TailwindCSS does not officially support Sass, Less, or Stylus preprocessors, the relative reference will solve your problem. However, instead of using a relative reference, I would create a reference to tailwind.css in package.json and use that in @reference. This way, the result will be much cleaner.

    package.json

    // package.json
    {
      "imports": {
        "#tailwind.css": "./assets/styles/scss/tailwind.css"
      },
    } 
    

    Header.vue

    <style lang="postcss">
    @reference "#tailwind.css";
    
    header {
      @apply bg-neutral-0;
    }
    </style>