Tailwind CSSCSSFrontend

Tailwind CSS Directives: @apply, @layer, theme, and screen

Understand Tailwind CSS directives and functions such as @apply, @layer, @config, theme(), screen(), and when not to hide every utility class inside CSS.

·Updated ·8 min read·Counting...
Tailwind CSS Directives: @apply, @layer, theme, and screen

Tailwind is known for utility classes in HTML or JSX, but it also provides CSS directives and functions for organizing custom styles. The important part is knowing when these tools improve maintainability and when they simply recreate a hard-to-track CSS abstraction layer.

@apply

@apply lets you reuse a group of utility classes inside CSS:

@layer components {
  .btn {
    @apply rounded-md bg-blue-600 px-4 py-2 font-medium text-white;
  }
}

Then use:

<button class="btn">Save</button>

Use @apply when a stable style group is repeated and truly belongs in CSS. Do not use it to hide every class name just because the markup looks long.

For interactive states, prefer clear component APIs or direct classes. Be careful with variants and framework version differences.

@layer

@layer places custom CSS into Tailwind's layering model:

@layer base {
  h1 {
    @apply text-3xl font-bold;
  }
}

@layer components {
  .card {
    @apply rounded-lg border p-6;
  }
}

@layer utilities {
  .text-shadow {
    text-shadow: 0 1px 2px rgb(0 0 0 / 0.3);
  }
}

Use layers to make custom CSS participate predictably in Tailwind's ordering. Without clear layering, you may get surprising overrides.

@config

Some setups let CSS reference a specific Tailwind config:

@config "./tailwind.config.js";

Most projects should keep configuration in the normal project setup and use @config only when they have a clear multi-config need.

theme()

theme() reads values from the Tailwind theme:

.btn {
  padding: theme("spacing.6");
  background-color: theme("colors.blue.600");
}

This keeps custom CSS aligned with your design scale. If you use custom CSS but hard-code unrelated values everywhere, Tailwind's consistency benefit weakens.

screen()

screen() can reference configured breakpoints:

@media screen(md) {
  .container {
    max-width: 768px;
  }
}

In many component cases, responsive variants in class names are simpler:

<div class="grid grid-cols-1 md:grid-cols-2">
  ...
</div>

Use CSS functions when the custom CSS itself needs to understand the theme.

When not to use these tools

Avoid directives and functions when:

  • A normal utility class is clearer at the call site.
  • A React component API would express the variation better.
  • You are hiding one-off styles behind vague class names.
  • The team no longer knows where a visual rule comes from.

Long class strings are not automatically bad. Unnamed or misleading abstraction is worse.

Subscribe to FreeMac

Weekly picks: free Mac software reviews, trusted source updates, alternatives, and low-friction guides.