| |

Tailwind CSS 42 🎨 Native CSS Cascade Layers (@layer theme, base, components, utilities)

Tailwind v4 made a structural decision that changes how every custom style is authored: it stopped hijacking the @layer at-rule and handed control back to the browser’s native CSS cascade layers. In v3, @layer base, @layer components, and @layer utilities were Tailwind-specific directives that the framework intercepted, reordered, and purged. In v4, those same at-rules are the browser’s native cascade layers, and Tailwind’s own styles are placed inside them by the @import "tailwindcss" statement. The framework no longer moves your CSS around; the layer you write is the layer the browser sees.

The shorthand @import "tailwindcss" expands to four layered imports. The first line declares the layer order: @layer theme, base, components, utilities. Then each Tailwind file is imported into its corresponding layer: theme.css into theme, preflight.css into base, and utilities.css into utilities. The components layer is declared in the order but has no Tailwind file of its own—it exists for your custom component classes. This ordering determines specificity: theme is weakest, utilities is strongest among the layered styles, and unlayered CSS is stronger than everything in a layer.

The most important behavioral change is that unlayered styles now beat layered styles. In v3, a :root block or a plain body rule could be overridden by a Tailwind utility because Tailwind’s internal ordering gave utilities precedence. In v4, any CSS you write outside a @layer block has higher priority than any CSS inside a layer—including Tailwind’s utilities. This is native CSS behavior, not a Tailwind choice. The practical consequence: if you write h1 { color: red } without a layer, it will override text-blue-500 on an <h1> element.

This chapter covers three areas. First, why native cascade layers exist in Tailwind v4—the problem of specificity management and the shift from framework interception to browser-native behavior. Second, how the four-layer system works—the theme, base, components, and utilities layers, their ordering, and the @utility directive that replaced @layer components and @layer utilities for custom classes. Third, how to author custom styles in the new model—placing base styles in @layer base, using @utility for custom utilities, handling third-party CSS with layer(), and the patterns for overriding. The chapter ends with a complete example session, a quick reference, best practices, common pitfalls, real-world examples, and diagrams showing the layer stack.

Key point: Tailwind v4 uses native CSS cascade layers. @import "tailwindcss" expands to @layer theme, base, components, utilities with each Tailwind file placed in its layer. Unlayered CSS beats layered CSS. Custom base styles go in @layer base. Custom utilities go in @utility, not @layer utilities. The @layer at-rule is no longer Tailwind-specific—it is the browser’s native cascade layer mechanism.


Why native cascade layers exist in Tailwind v4

The specificity-interception problem. In v3, Tailwind intercepted every @layer directive and moved the contained CSS to the position in the output where the corresponding @tailwind rule was. This was framework magic: the developer wrote @layer components, and Tailwind decided where the styles landed in the final CSS. It worked, but it made the output dependent on Tailwind’s internal ordering, and it meant that @layer had a different meaning in a Tailwind project than in a plain CSS project. The v4 decision removes the magic. The @layer at-rule is the browser’s native cascade layer. The developer’s layer placement is the browser’s layer placement.

The unlayered-beats-layered problem. Native CSS cascade layers have a rule: styles outside any layer beat styles inside any layer, regardless of specificity. This is not a quirk; it is how the layer mechanism is designed. A layer is a way to group styles and give the group a lower priority than the default. When Tailwind places all its utilities inside the utilities layer, those utilities become beatable by any unlayered style. A plain h1 { color: red } at the bottom of a stylesheet overrides text-blue-500 on an <h1>, because the plain rule is unlayered and the utility is layered. This is the single most surprising change for developers migrating from v3, where the opposite was true.

The @utility replacement problem. In v3, a custom utility was written inside @layer utilities and a custom component inside @layer components. Both were Tailwind-aware: the framework registered the class, generated variants, and purged unused styles. In v4, @layer utilities and @layer components are plain CSS layers. They do not register classes with Tailwind, they do not generate variants, and they are not purged. A class written in @layer utilities is just a CSS class. To create a custom utility that behaves like a Tailwind utility—with variant support, purge tracking, and @apply compatibility—the @utility directive is required. The @utility directive is the v4 replacement for both @layer components and @layer utilities for custom classes.

The third-party-CSS problem. A third-party stylesheet imported into a project is unlayered by default. Because unlayered CSS beats layered CSS, the third-party styles override Tailwind’s utilities. A button component from a library that sets background-color: blue on a .btn class will override bg-red-500 applied to the same element, because the library’s rule is unlayered and the utility is in the utilities layer. The fix is to import the third-party CSS into a layer: @import "library/style.css" layer(components). The components layer is weaker than utilities, so Tailwind’s utilities can override it.

The @apply compatibility problem. In v3, a custom class defined in @layer components could be used with @apply inside another rule. In v4, a class defined in @layer components is not registered with Tailwind, so @apply reports “Cannot apply unknown utility class.” The class must be defined with @utility to be available for @apply. This is a direct consequence of the shift from framework interception to native CSS. The @utility directive registers the class with Tailwind; the @layer directive does not.

The trade-off. Native cascade layers are more predictable than framework interception, but they are less forgiving. The developer must understand the layer order and the unlayered-beats-layered rule. A style placed in the wrong layer has the wrong priority, and there is no warning. The @utility directive is more verbose than @layer utilities, but it is the only way to get Tailwind-aware custom classes. The trade-off is between the simplicity of framework magic and the transparency of native behavior. The transparency requires more knowledge, but it produces fewer surprises once the rules are understood.


a. The four-layer system and its order

The @import "tailwindcss" statement is a shorthand for a layered import sequence. The first line declares the layer order, and the subsequent lines import Tailwind’s files into the corresponding layers.

@layer theme, base, components, utilities;

@import "tailwindcss/theme.css" layer(theme);
@import "tailwindcss/preflight.css" layer(base);
@import "tailwindcss/utilities.css" layer(utilities);

The theme layer contains the design token variables—colors, spacing, fonts, breakpoints—that Tailwind generates from the @theme block. The base layer contains Preflight, Tailwind’s CSS reset, plus any custom base styles you add. The components layer is declared in the order but has no Tailwind file of its own. It exists for your reusable component classes. The utilities layer contains all of Tailwind’s utility classes.

The order determines specificity among the layers: theme is weakest, then base, then components, then utilities. A rule in utilities beats a rule in components, and a rule in components beats a rule in base. This is the intended hierarchy: base styles are defaults, components are reusable patterns that can be overridden, and utilities are the final say.

The components layer is the right place for classes like .card, .btn, or .badge—patterns that are composed of multiple properties and are meant to be used as a single class. A class in components is weaker than any utility, so class="card p-8" applies the card’s defaults and then overrides the padding with p-8. This is the same behavior as v3’s @layer components, but without the framework interception.

Unlayered CSS beats every layer. If you write h1 { color: red } outside any @layer block, it overrides any text-blue-500 on an <h1>. This is why the default base styles—:root, body, and global resets—must be placed in @layer base. A :root block outside a layer would override Tailwind’s theme variables, which is almost never what you want.


b. The @utility directive

The @utility directive is the v4 replacement for custom classes that were previously written in @layer utilities or @layer components. A class defined with @utility is registered with Tailwind: it can be used with @apply, it supports variants like hover: and md:, and it is purged when unused.

@utility scroll-snap-none {
  scroll-snap-type: none;
}

@utility scroll-snap-x {
  scroll-snap-type: x;
}

The class name is the name after @utility. The body is the CSS for the class. The class behaves like a Tailwind utility: scroll-snap-x can be used in HTML, can be prefixed with md:scroll-snap-x, and can be applied with @apply scroll-snap-x inside another rule.

A custom component class that was previously written in @layer components is written with @utility in v4. The class can use @apply internally, or it can be written with plain CSS properties.

@utility btn {
  @apply px-4 py-2 rounded font-medium;
  background-color: var(--color-primary-600);
  color: var(--color-white);
}

@utility btn-primary {
  background-color: var(--color-primary-600);
  color: var(--color-white);
}

The @utility directive can be combined with @variant for state variants. The @variant directive applies a variant inside the utility definition, which is the v4 equivalent of the @variants directive from v2 and v3.

@utility btn {
  padding: calc(var(--spacing) * 2) calc(var(--spacing) * 4);
  border-radius: var(--radius-sm);

  @variant hover {
    background-color: var(--color-primary-700);
  }

  @variant dark {
    background-color: var(--color-primary-500);
  }
}

The @utility directive is the only way to create a custom class that Tailwind recognizes as a utility. A class written in @layer utilities or @layer components is a plain CSS class: it does not support variants, it is not purged, and it cannot be used with @apply.


c. Authoring custom styles in the new model

Base styles. Custom base styles go in @layer base. The :root block, element resets, and global typography belong here. A style in base is weaker than components and utilities, so a utility can override it.

@import "tailwindcss";

@layer base {
  h1 {
    font-size: var(--text-2xl);
  }

  :root {
    --background: hsl(0 0% 100%);
  }
}

The :root block inside @layer base is correct. A :root block outside a layer would override Tailwind’s theme variables.

Component classes. A reusable component class goes in @utility, not @layer components. The class is registered with Tailwind, supports variants, and can be used with @apply.

@utility card {
  background-color: var(--color-white);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: calc(var(--spacing) * 6);
}

Third-party CSS. A third-party stylesheet is imported into a layer with layer(). The components layer is the recommended target for most third-party styles, because it is weaker than utilities and allows Tailwind utilities to override the library’s styles.

@import "tailwindcss";
@import "reactflow/dist/style.css" layer(components);

The base layer is also an option for styles that should be weaker than components. The utilities layer is the strongest, but importing third-party CSS into utilities would make it as strong as Tailwind’s own utilities, which is rarely desired.

Custom layers. A project can insert its own layer between the built-in layers by modifying the layer order declaration. The @layer theme, base, custom, components, utilities line inserts a custom layer between base and components. The @import statements remain the same, and the custom layer is available for styles that need a priority between the built-in layers.

@layer theme, base, custom, components, utilities;

@import "tailwindcss/theme.css" layer(theme);
@import "tailwindcss/preflight.css" layer(base);
@import "tailwindcss/utilities.css" layer(utilities);

@layer custom {
  .my-custom-style {
    color: var(--color-primary-500);
  }
}

Unlayered styles. Unlayered styles are stronger than every layer. They should be avoided for most styling, because they override Tailwind’s utilities and make the cascade harder to reason about. The only common use is for styles that genuinely need to be the final say—for example, a print stylesheet or a third-party integration that must not be overridden.


Complete Example Session

/* ============================================
   PART 1: THE LAYER ORDER AND IMPORTS
   ============================================ */

@import "tailwindcss";

/* The shorthand above expands to:
   @layer theme, base, components, utilities;
   @import "tailwindcss/theme.css" layer(theme);
   @import "tailwindcss/preflight.css" layer(base);
   @import "tailwindcss/utilities.css" layer(utilities);
*/

/* The components layer has no Tailwind file.
   It exists for your custom component classes. */


/* ============================================
   PART 2: CUSTOM BASE STYLES
   ============================================ */

@layer base {
  h1 {
    font-size: var(--text-2xl);
    font-weight: var(--font-weight-bold);
  }

  :root {
    --background: hsl(0 0% 100%);
    --foreground: hsl(0 0% 3.9%);
  }
}

/* Base styles are weaker than components and utilities.
   A utility can override them. */


/* ============================================
   PART 3: A CUSTOM UTILITY
   ============================================ */

@utility scroll-snap-none {
  scroll-snap-type: none;
}

@utility scroll-snap-x {
  scroll-snap-type: x;
}

/* The @utility directive registers the class with Tailwind.
   The class supports variants and can be used with @apply. */


/* ============================================
   PART 4: A CUSTOM COMPONENT CLASS
   ============================================ */

@utility card {
  background-color: var(--color-white);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: calc(var(--spacing) * 6);
}

@utility card-hover {
  transition: box-shadow 0.2s;

  @variant hover {
    box-shadow: var(--shadow-lg);
  }
}

/* The card class is a utility.
   It is weaker than Tailwind's utilities, so p-8 overrides its padding. */


/* ============================================
   PART 5: THIRD-PARTY CSS IN A LAYER
   ============================================ */

@import "reactflow/dist/style.css" layer(components);

/* The third-party CSS is placed in the components layer.
   It is weaker than Tailwind's utilities.
   Tailwind utilities can override it. */


/* ============================================
   PART 6: UNLAYERED STYLES (USE SPARINGLY)
   ============================================ */

/* This rule is unlayered.
   It beats every layer, including Tailwind's utilities. */
h1 {
  color: red;
}

/* If the h1 has class="text-blue-500", the color is red,
   because the unlayered rule beats the utilities layer. */


/* ============================================
   PART 7: A CUSTOM LAYER
   ============================================ */

@layer theme, base, custom, components, utilities;

@import "tailwindcss/theme.css" layer(theme);
@import "tailwindcss/preflight.css" layer(base);
@import "tailwindcss/utilities.css" layer(utilities);

@layer custom {
  .my-brand-style {
    color: var(--color-primary-500);
  }
}

/* The custom layer is between base and components.
   It is stronger than base but weaker than components. */


/* ============================================
   PART 8: USING @APPLY WITH @UTILITY
   ============================================ */

@utility btn {
  @apply px-4 py-2 rounded font-medium;
  background-color: var(--color-primary-600);
  color: var(--color-white);
}

/* @apply works inside @utility because the class is registered.
   It does not work inside @layer components in v4. */


/* ============================================
   PART 9: THE COMPLETE STYLESHEET
   ============================================ */

@import "tailwindcss";
@import "reactflow/dist/style.css" layer(components);

@layer base {
  :root {
    --background: hsl(0 0% 100%);
    --foreground: hsl(0 0% 3.9%);
  }

  body {
    background-color: var(--background);
    color: var(--foreground);
  }
}

@utility card {
  background-color: var(--color-white);
  border-radius: var(--radius-lg);
  padding: calc(var(--spacing) * 6);

  @variant hover {
    box-shadow: var(--shadow-lg);
  }
}

@utility btn {
  @apply px-4 py-2 rounded font-medium;
  background-color: var(--color-primary-600);
  color: var(--color-white);
}


/* ============================================
   PART 10: THE HTML USAGE
   ============================================ */

/* <div class="card p-8"> ... </div>
   The card class provides the defaults.
   The p-8 utility overrides the padding.

   <button class="btn bg-red-500"> ... </button>
   The btn class provides the base styles.
   The bg-red-500 utility overrides the background.

   <div class="sm:card"> ... </div>
   The card class works with the sm: variant,
   because it is defined with @utility.
*/

The ten parts show the layer order and imports, custom base styles, a custom utility, a custom component class, third-party CSS in a layer, unlayered styles, a custom layer, @apply with @utility, the complete stylesheet, and the HTML usage.


Quick Reference

The Layer Stack

LayerPurposeStrength
themeDesign token variablesWeakest
basePreflight and element resetsWeak
componentsReusable overridable patternsMedium
utilitiesTailwind utilities and custom utilitiesStrong
UnlayeredStyles outside any layerStrongest

Directives

DirectivePurpose
@import "tailwindcss"Imports all layers in order
@layer base { ... }Custom base styles
@utility name { ... }Custom utility (registered, variant-aware)
@variant hover { ... }State variant inside @utility
@import "..." layer(components)Third-party CSS in a layer

@layer vs @utility

Aspect@layer utilities@utility
Registered with TailwindNoYes
Supports variantsNoYes
Purged when unusedNoYes
Works with @applyNoYes
v4 recommendationAvoidUse

Layer Order Customization

DeclarationEffect
@layer theme, base, components, utilities;Default order
@layer theme, base, custom, components, utilities;Insert custom layer
Unlayered stylesBeat all layers

Best Practices

✅ Do This:

/* Place base styles in @layer base */
@layer base { :root { --background: ...; } }                             // ✅
/* Use @utility for custom utilities and components */
@utility card { padding: var(--spacing-6); }                              // ✅
/* Import third-party CSS into a layer */
@import "library/style.css" layer(components);                            // ✅
/* Use @variant inside @utility for state variants */
@utility btn { @variant hover { ... } }                                   // ✅
/* Let utilities override components */
<div class="card p-8">                                                    // ✅

❌ Don’t Do This:

/* Don't use @layer utilities for custom classes in v4 */
@layer utilities { .card { ... } } // not registered, no variants          // ❌
/* Don't leave :root unlayered */
:root { --background: ...; } // overrides Tailwind's theme                 // ❌
/* Don't import third-party CSS unlayered */
@import "library/style.css"; // beats Tailwind utilities                   // ❌
/* Don't use @layer components for custom utilities */
@layer components { .btn { @apply ...; } } // @apply fails                 // ❌
/* Don't use unlayered styles for normal styling */
h1 { color: red; } // beats every utility                                  // ❌

Common Pitfalls

PitfallWhy It HappensFix
@apply fails with @layer componentsClass not registered with TailwindUse @utility
Custom class has no variants@layer class is plain CSSUse @utility
Tailwind utility doesn’t overrideUnlayered style beats layeredMove to @layer base
Third-party CSS overrides utilitiesImported unlayered@import ... layer(components)
:root overrides themeUnlayered :rootMove to @layer base
Breakpoint prefix doesn’t work@layer components class is not a utilityUse @utility
Style priority unexpectedWrong layer placementCheck the layer stack

Real-World Examples

1. Base Styles

@layer base { :root { --background: hsl(0 0% 100%); } }

2. Custom Utility

@utility scroll-snap-none { scroll-snap-type: none; }

3. Custom Component

@utility card { padding: var(--spacing-6); border-radius: var(--radius-lg); }

4. Third-Party in a Layer

@import "reactflow/dist/style.css" layer(components);

5. State Variant

@utility btn { @variant hover { background-color: var(--color-primary-700); } }

6. Custom Layer Order

@layer theme, base, custom, components, utilities;

7. @apply in @utility

@utility btn { @apply px-4 py-2 rounded; }

8. Overriding a Component

<div class="card p-8"> <!-- p-8 overrides card padding -->

9. Theme Variables

@theme { --color-primary-500: oklch(0.6 0.2 250); }

10. Complete Stylesheet

@import "tailwindcss";
@import "library/style.css" layer(components);
@layer base { :root { ... } }
@utility card { ... }

Visual

The Layer Stack

┌──────────────────────────────────────────────────────────────┐
│  THE LAYER STACK                                             │
│                                                              │
│  ┌──────────────────────────────────────────────────────┐    │
│  │  UNLAYERED (strongest)                               │    │
│  │  Any CSS outside a @layer block                      │    │
│  │  Beats every layer                                   │    │
│  └──────────────────────────────────────────────────────┘    │
│    ▲                                                         │
│    │  stronger                                               │
│    │                                                         │
│  ┌──────────────────────────────────────────────────────┐    │
│  │  utilities                                           │    │
│  │  Tailwind utilities + @utility classes               │    │
│  └──────────────────────────────────────────────────────┘    │
│    ▲                                                         │
│  ┌──────────────────────────────────────────────────────┐    │
│  │  components                                          │    │
│  │  Reusable component classes                          │    │
│  │  (no Tailwind file by default)                       │    │
│  └──────────────────────────────────────────────────────┘    │
│    ▲                                                         │
│  ┌──────────────────────────────────────────────────────┐    │
│  │  base                                                │    │
│  │  Preflight + custom base styles                      │    │
│  └──────────────────────────────────────────────────────┘    │
│    ▲                                                         │
│  ┌──────────────────────────────────────────────────────┐    │
│  │  theme                                               │    │
│  │  Design token variables                              │    │
│  └──────────────────────────────────────────────────────┘    │
│                                                              │
│  The order is declared by @layer theme, base, components,    │
│  utilities. Unlayered styles beat everything.                │
│                                                              │
└──────────────────────────────────────────────────────────────┘

@layer vs @utility

┌──────────────────────────────────────────────────────────────┐
│  @layer vs @utility                                          │
│                                                              │
│  @layer utilities:                                           │
│  ┌──────────────────────────────────────────────────────┐    │
│  │  @layer utilities {                                  │    │
│  │    .my-class { color: red; }                         │    │
│  │  }                                                   │    │
│  │                                                       │    │
│  │  Plain CSS. Not registered with Tailwind.            │    │
│  │  No variants. No purge. No @apply.                   │    │
│  └──────────────────────────────────────────────────────┘    │
│                                                              │
│  @utility:                                                   │
│  ┌──────────────────────────────────────────────────────┐    │
│  │  @utility my-class {                                 │    │
│  │    color: red;                                       │    │
│  │  }                                                   │    │
│  │                                                       │    │
│  │  Registered with Tailwind.                           │    │
│  │  Variants work: hover:my-class, md:my-class.         │    │
│  │  Purged when unused. @apply works.                   │    │
│  └──────────────────────────────────────────────────────┘    │
│                                                              │
│  In v4, custom classes use @utility, not @layer.             │
│                                                              │
└──────────────────────────────────────────────────────────────┘

Third-Party CSS and Layers

┌──────────────────────────────────────────────────────────────┐
│  THIRD-PARTY CSS AND LAYERS                                  │
│                                                              │
│  WITHOUT layer():                                            │
│  ┌──────────────────────────────────────────────────────┐    │
│  │  @import "library/style.css";                        │    │
│  │                                                       │    │
│  │  The library's .btn { background: blue } is unlayered│    │
│  │  It beats Tailwind's bg-red-500 on the same element. │    │
│  └──────────────────────────────────────────────────────┘    │
│                                                              │
│  WITH layer(components):                                     │
│  ┌──────────────────────────────────────────────────────┐    │
│  │  @import "library/style.css" layer(components);      │    │
│  │                                                       │    │
│  │  The library's .btn is in the components layer.      │    │
│  │  Tailwind's bg-red-500 is in utilities.              │    │
│  │  utilities > components → Tailwind wins.             │    │
│  └──────────────────────────────────────────────────────┘    │
│                                                              │
│  layer(components) is the recommended target for most        │
│  third-party CSS. layer(base) is for styles that should      │
│  be weaker than components.                                  │
│                                                              │
└──────────────────────────────────────────────────────────────┘

Unlayered Styles Override Everything

┌──────────────────────────────────────────────────────────────┐
│  UNLAYERED STYLES                                            │
│                                                              │
│  @import "tailwindcss";                                      │
│                                                              │
│  /* Unlayered */                                             │
│  h1 { color: red; }                                          │
│                                                              │
│  <h1 class="text-blue-500">Hello</h1>                        │
│                                                              │
│  ┌──────────────────────────────────────────────────────┐    │
│  │  The unlayered h1 rule beats .text-blue-500.         │    │
│  │  The heading is RED, not blue.                       │    │
│  │                                                       │    │
│  │  This is native CSS behavior.                        │    │
│  │  Unlayered > any @layer.                             │    │
│  └──────────────────────────────────────────────────────┘    │
│                                                              │
│  To fix: place the h1 rule in @layer base.                   │
│  Then .text-blue-500 beats it.                               │
│                                                              │
└──────────────────────────────────────────────────────────────┘

Summary

ItemValue
Layer ordertheme, base, components, utilities
@import "tailwindcss"Shorthand for the layered imports
Unlayered stylesBeat every layer
base layerPreflight + custom base styles
components layerReusable overridable patterns
utilities layerTailwind utilities + @utility classes
@utilityRegisters a custom utility with Tailwind
@layerNative CSS cascade layer; not Tailwind-specific
Third-party CSSImport with layer(components)
@applyWorks only with @utility classes

Key takeaways:

  • Tailwind v4 uses native CSS cascade layers. The @import "tailwindcss" statement expands to @layer theme, base, components, utilities with each Tailwind file placed in its layer. The framework no longer intercepts or reorders @layer.
  • Unlayered CSS beats every layer. This is native CSS behavior. A plain h1 { color: red } overrides text-blue-500 on the same element. Place base styles in @layer base to keep them weaker than utilities.
  • The @utility directive replaces @layer components and @layer utilities for custom classes. A class defined with @utility is registered with Tailwind, supports variants, is purged when unused, and works with @apply. A class in @layer is plain CSS.
  • Third-party CSS should be imported into a layer. @import "library/style.css" layer(components) places the library’s styles in the components layer, which is weaker than utilities. Tailwind utilities can then override the library’s styles.
  • The components layer is for reusable patterns. Classes like .card and .btn go in components—or in @utility if they need Tailwind features. The layer is weaker than utilities, so a p-8 utility overrides a component’s padding.
  • Custom layers can be inserted. Modifying the layer order declaration to @layer theme, base, custom, components, utilities inserts a custom layer between base and components. This is useful for styles that need a specific priority.
  • @apply works only with @utility classes in v4. A class defined in @layer components cannot be used with @apply, because it is not registered with Tailwind. The class must be defined with @utility.
  • Breakpoint prefixes work only with @utility classes. A class in @layer components does not support sm: or md:. A class in @utility does, because it is a registered utility.

Remember: Tailwind v4’s layer system is the browser’s native cascade layer mechanism, not a framework-specific directive. The @import "tailwindcss" statement places Tailwind’s styles in the theme, base, components, and utilities layers, in that order. Unlayered styles beat every layer, so base styles belong in @layer base and third-party CSS belongs in layer(components). Custom classes use @utility, which registers the class with Tailwind and gives it variant support, purge tracking, and @apply compatibility. The old @layer utilities and @layer components patterns are plain CSS in v4—they work, but they do not behave like Tailwind utilities. The rule is simple: use @layer base for global resets, @utility for custom classes, and layer(components) for third-party CSS.



Stop using slow, ad-bloated tool sites! 🤮

🔎 Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)

⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free

🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!