Custom Utilities with @utility

Author First-Class Utilities

Custom Utilities with @utility

The @utility directive registers your own utilities that participate in variants and sorting exactly like the built-in ones.

4 min read Level 3/5 #tailwind#utility#customization
What you'll learn
  • Define a static utility with @utility
  • Define a functional, parameterized utility
  • Understand why @utility beats a plain hand-written class

When no built-in utility expresses what you need, @utility lets you register your own. It is not a plain class — it joins Tailwind’s utility layer and behaves like a native utility.

Static Utilities

Declare a name and its declarations. The result is a class you can use anywhere:

@import "tailwindcss";

@utility content-auto {
  content-visibility: auto;
}

Now content-auto exists, and so does lg:content-auto, hover:content-auto, and [&>*]:content-auto — variants come for free.

Functional Utilities

Use a -* suffix and the --value() function to accept a parameter:

@utility tab-* {
  tab-size: --value(integer);
}

That generates tab-2, tab-4, tab-8, and so on. You can also pull from theme tokens, for example --value(--spacing-*), so the utility respects your scale.

Why Not Just a Class

A hand-written .content-auto { content-visibility: auto } looks equivalent but is not:

<div class="content-auto md:content-auto hover:content-auto">
  Only works because content-auto is a real utility
</div>

A plain class cannot be prefixed with md: or hover:, and it lands in an unpredictable place in the cascade. A @utility is sorted into the utilities layer and works with the entire variant system — which is exactly why you should reach for it instead of a one-off class.

@variant & @custom-variant →