---
name: creating-custom-utilities
description: Create custom utilities with @utility directive supporting static utilities, functional utilities with values, theme-based utilities, and multi-value utilities. Use when extending Tailwind with custom CSS properties or patterns.
allowed-tools: Read, Write, Edit, Grep, Glob
---
# Creating Custom Utilities
## Purpose
The `@utility` directive creates custom utility classes with full variant support (hover, focus, responsive, etc.). This is the proper way to extend Tailwind v4 with custom utilities.
## Static Utilities
Define utilities with fixed values:
```css
@utility content-auto {
content-visibility: auto;
}
@utility content-hidden {
content-visibility: hidden;
}
@utility text-balance {
text-wrap: balance;
}
@utility text-pretty {
text-wrap: pretty;
}
@utility bg-glass {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
}
```
**Usage:**
```html
```
Static utilities work with all variants automatically.
## Functional Utilities with Integer Values
Create utilities that accept numeric values:
```css
@utility mt-* {
margin-top: calc(0.25rem * --value(integer));
}
@utility truncate-* {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: --value(integer);
overflow: hidden;
}
@utility text-stroke-* {
-webkit-text-stroke-width: --value(integer) px;
}
```
**Usage:**
```html
```
The `--value(integer)` function extracts the numeric value from the class name.
## Theme-Based Utilities
Reference theme variables using `--value(--namespace- *)`:
```css
@theme {
--tab-size-2: 2;
--tab-size-4: 4;
--tab-size-8: 8;
--tab-size-github: 8;
}
@utility tab-* {
tab-size: --value(--tab-size- *);
}
```
**Usage:**
```html
...
...
```
**Another example:**
```css
@theme {
--aspect-square: 1 / 1;
--aspect-video: 16 / 9;
--aspect-portrait: 3 / 4;
}
@utility aspect-* {
aspect-ratio: --value(--aspect- *);
}
```
**Usage:**
```html
```
## Multi-Value Utilities
Create utilities that accept multiple value types:
```css
@utility text-stroke-* {
-webkit-text-stroke-width: --value(integer) px;
-webkit-text-stroke-color: --value(--color- *);
}
```
**Usage:**
```html
Stroked text
Stroked with theme color
```
**Another example:**
```css
@theme {
--blur-sm: 4px;
--blur-md: 8px;
--blur-lg: 16px;
}
@utility backdrop-blur-* {
backdrop-filter: blur(--value(--blur- *));
backdrop-filter: blur(--value(integer) px);
}
```
**Usage:**
```html
```
## Arbitrary Values Support
Support both theme values and arbitrary values:
```css
@utility tab-* {
tab-size: --value(integer);
tab-size: --value([integer]);
}
```
**Usage:**
```html
Theme value
Arbitrary value
```
The `--value([integer])` function enables arbitrary value syntax with square brackets.
## Complex Utility Examples
### Gradient Text
```css
@utility text-gradient-* {
background: linear-gradient(to right, --value(--color- *), --value(--color- *, 2));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
```
**Usage:**
```html
Gradient text
```
### Grid Template Columns
```css
@utility grid-cols-* {
grid-template-columns: repeat(--value(integer), minmax(0, 1fr));
}
```
**Usage:**
```html
```
### Custom Line Clamp
```css
@utility line-clamp-* {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: --value(integer);
overflow: hidden;
}
@utility line-clamp-none {
display: block;
-webkit-box-orient: horizontal;
-webkit-line-clamp: none;
overflow: visible;
}
```
**Usage:**
```html
```
### Custom Spacing Scale
```css
@theme {
--spacing-base: 0.25rem;
}
@utility gap-* {
gap: calc(var(--spacing-base) * --value(integer));
}
@utility space-x-* > * + * {
margin-left: calc(var(--spacing-base) * --value(integer));
}
```
**Usage:**
```html
```
### Glassmorphism Utilities
```css
@utility glass-* {
background: rgba(255, 255, 255, --value(integer) / 100);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
}
@utility glass-dark-* {
background: rgba(0, 0, 0, --value(integer) / 100);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.1);
}
```
**Usage:**
```html
```
## Utilities with Pseudo-Elements
```css
@utility before-content-* {
&::before {
content: --value([string]);
display: block;
}
}
@utility after-content-* {
&::after {
content: --value([string]);
display: block;
}
}
```
**Usage:**
```html
Star before
Arrow after
```
## Complete Custom Utilities Library
```css
@import 'tailwindcss';
@utility content-auto {
content-visibility: auto;
}
@utility content-hidden {
content-visibility: hidden;
}
@utility text-balance {
text-wrap: balance;
}
@utility text-pretty {
text-wrap: pretty;
}
@utility truncate-* {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: --value(integer);
overflow: hidden;
}
@utility bg-glass {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
}
@utility text-stroke-* {
-webkit-text-stroke-width: --value(integer) px;
-webkit-text-stroke-color: --value(--color- *);
}
@theme {
--aspect-square: 1 / 1;
--aspect-video: 16 / 9;
--aspect-portrait: 3 / 4;
--aspect-ultrawide: 21 / 9;
}
@utility aspect-* {
aspect-ratio: --value(--aspect- *);
aspect-ratio: --value([number]);
}
@theme {
--tab-size-2: 2;
--tab-size-4: 4;
--tab-size-8: 8;
}
@utility tab-* {
tab-size: --value(--tab-size- *);
tab-size: --value(integer);
tab-size: --value([integer]);
}
```
## Why Use @utility Instead of @layer utilities
**Don't do this:**
```css
@layer utilities {
.my-button {
padding: 1rem;
}
}
```
Won't work with variants like `hover:my-button`.
**Do this:**
```css
@utility my-button {
padding: 1rem;
}
```
Works with all variants: `hover:my-button`, `focus:my-button`, `lg:my-button`.
## Best Practices
1. **Use @utility for variant support** - Always use `@utility` instead of `@layer utilities`
2. **Support arbitrary values** - Include `--value([type])` for flexibility
3. **Use theme variables** - Reference theme with `--value(--namespace- *)`
4. **Name utilities semantically** - Use clear, descriptive names
5. **Group related utilities** - Keep similar utilities together
## Common Use Cases
- Custom CSS properties not in Tailwind
- Browser-specific prefixed properties
- Complex multi-property patterns
- Domain-specific utilities (e.g., print styles)
- Experimental CSS features
## See Also
- RESEARCH.md section: "Advanced Patterns" → "Custom Utilities with @utility"