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.
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.