Master Code
On The Go

Learn. Practice. Build.

Home › How-To › Tailwind Custom Utilities

Tailwind CSS Guide

Tailwind CSS Custom Utilities

Extend Tailwind with your own utilities using the @utility directive.

Last updated: October 2026 · Tested on Tailwind v4.0

Quick answer: Use @utility my-class { property: value; } in your CSS to create a custom utility. Unlike @apply, custom utilities work with all Tailwind variants (hover:, md:, dark:) automatically. This is the modern replacement for the v3 plugin API.

1

Your First Custom Utility

@utility text-shadow-sm {
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}

@utility text-shadow-md {
    text-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
}

@utility text-shadow-lg {
    text-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}

Now use them like any Tailwind utility:

<h1 class="text-shadow-md">Heading with shadow</h1>
<p class="text-shadow-sm">Subtle text shadow</p>
2

Variants Work Automatically

This is the key difference from @apply. Custom utilities support every Tailwind variant:

<h1 class="text-shadow-sm md:text-shadow-md lg:text-shadow-lg">
    Responsive text shadow
</h1>

<button class="text-shadow-sm hover:text-shadow-none">
    Shadow disappears on hover
</button>

No extra work needed — Tailwind handles variant composition.

💡 Why this matters: In v3, custom utilities created via the plugin API needed manual variant handling. In v4, variants are free.

3

Practical Examples

Content visibility optimization:

@utility content-auto {
    content-visibility: auto;
    contain-intrinsic-size: 0 500px;
}

Custom scrollbar styling:

@utility scrollbar-thin {
    scrollbar-width: thin;
    scrollbar-color: #475569 transparent;
}

Text gradient:

@utility text-gradient {
    background: linear-gradient(90deg, #3b82f6, #8b5cf6);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

Glass morphism:

@utility glass {
    background: rgba(255, 255, 255, 0.1);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border: 1px solid rgba(255, 255, 255, 0.2);
}
4

Registering Theme Values

If your utility relies on theme tokens, register them in @theme so they appear in Tailwind's reference:

@theme {
    --text-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.1);
    --text-shadow-md: 0 2px 4px rgba(0, 0, 0, 0.15);
    --text-shadow-lg: 0 4px 8px rgba(0, 0, 0, 0.2);
}

@utility text-shadow-* {
    text-shadow: --value(--text-shadow-*);
}

The --value() function pulls the theme value into your utility. This is the modern, type-safe approach.

5

Migrating from v3 Plugins

v3 approach (JavaScript plugin):

// tailwind.config.js (v3)
const plugin = require('tailwindcss/plugin');

module.exports = {
    plugins: [
        plugin(function ({ addUtilities }) {
            addUtilities({
                '.text-shadow-sm': {
                    textShadow: '0 1px 2px rgba(0,0,0,0.1)',
                },
            });
        }),
    ],
};

v4 approach (CSS @utility):

@utility text-shadow-sm {
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}

Same result, 15 lines shorter, and it lives next to your other CSS.

6

Advanced: Multi-Property Utilities

Utilities can include many properties — they're just CSS:

@utility aspect-square {
    aspect-ratio: 1 / 1;
}

@utility card-hover {
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}

@utility card-hover:hover {
    transform: translateY(-4px);
    box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
}

Or use nesting to combine:

@utility card-hover {
    transition: all 0.2s ease;

    &:hover {
        transform: translateY(-4px);
        box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
    }
}

🎯 @utility vs @apply vs Plugin API

Feature @utility @apply v3 Plugin
Where it lives CSS file CSS file JS config
Variants support Automatic Limited Manual
Purpose New utilities Component classes Plugins
Recommended in v4 ✅ Yes For components Rarely

🛡️ Best Practices

Avoid over-engineering: If you find yourself writing 30 custom utilities, you might be working against Tailwind's philosophy. The framework already covers 95% of common cases. Only add utilities when you genuinely need something missing.

❓ Frequently Asked Questions

How do I create a custom utility in Tailwind v4?

Use the @utility directive in your CSS file: @utility my-class { property: value; }. This creates a new utility class that works with all Tailwind variants like hover: and md:.

What is the difference between @utility and @apply?

@apply combines existing Tailwind utilities into a CSS class. @utility creates a brand new utility class that doesn't exist in Tailwind. Use @apply for components and @utility for new utilities.

Do custom @utility classes support variants?

Yes. Every custom utility created with @utility supports all Tailwind variants automatically. You can use hover:my-utility, md:my-utility, dark:my-utility, etc.

How do I add custom utilities in Tailwind v3?

In v3, add them via the plugin API in tailwind.config.js: plugin(function({ addUtilities }) { addUtilities({ '.my-class': { property: 'value' } }) }). In v4, use the @utility directive in CSS.

Should I use @utility or a Tailwind plugin?

In Tailwind v4, prefer @utility. It's simpler, faster, and lives alongside your other CSS. The plugin API still exists but is mostly for third-party packages.

🎉 You've Completed the Tailwind Cluster!

You now have 12 pages covering every aspect of Tailwind CSS — from install to advanced customization. Each page links to the others, creating a powerful topical authority cluster.

← All How-To Guides