@utility name { ... }
@utility name-* { ... }
@utility name (implementation) { ... }@utility defines a utility for style(), @apply, and the other places that
accept utilities. Write it at the top level of the stylesheet.
Static and functional utilities
A name without * defines a static utility. A name that ends in -* defines a
functional utility, and --value() reads the rest of the candidate.
Stylesheet
@utility content-auto {
content-visibility: auto;
}
@utility stack-* {
display: flex;
flex-direction: column;
gap: --spacing(--value(integer));
}Source
import { style } from "stillwind/react";
export const list = style("content-auto stack-3");Compiled code
export const list = {className:"sw_70m3s"};Generated stylesheet without preflight
/*! stillwind v0.0.0 | MIT License | https://stillwind.dev */
/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
@layer properties, theme, base, components, utilities;
@layer theme {
:root, :host {
--spacing: .25rem;
}
}
@layer utilities {
.sw_70m3s {
content-visibility: auto;
display: flex;
flex-direction: column;
gap: calc(var(--spacing) * 3);
}
}Values and modifiers
--value() lists the accepted forms of the value, and the first matching form
decides. --modifier() reads the part after / in the same way.
| Form | Accepts | Example candidate |
|---|---|---|
--tab-size-* |
A token of the namespace | tab-width-wide |
integer |
A bare value of the type | tab-width-2 |
[integer] |
An arbitrary value of the type | tab-width-[3] |
Stylesheet
@theme {
--tab-size-wide: 8;
}
@utility tab-width-* {
tab-size: --value(--tab-size-*, integer, [integer]);
}
@utility text-fluid-* {
font-size: --value(--text-*);
line-height: --modifier(--leading-*, [length]);
}Source
import { style } from "stillwind/react";
export const code = style("tab-width-wide text-fluid-lg/tight");Compiled code
export const code = {className:"sw_9jkuo"};Generated stylesheet without preflight
/*! stillwind v0.0.0 | MIT License | https://stillwind.dev */
/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
@layer properties, theme, base, components, utilities;
@layer theme {
:root, :host {
--text-lg: 1.125rem;
--leading-tight: 1.25;
--tab-size-wide: 8;
}
}
@layer utilities {
.sw_9jkuo {
tab-size: var(--tab-size-wide);
font-size: var(--text-lg);
line-height: var(--leading-tight);
}
}A declaration whose --value() matches no form is left out. A candidate that
matches no declaration produces no CSS, and
unknown-utility reports it.
Definitions with the same name
A definition with an existing name adds its declarations to the existing utility. It does not replace it. Every definition that accepts the candidate contributes, and a later definition wins in the cascade.
Stylesheet
@utility container {
padding-inline: 1rem;
}Source
import { style } from "stillwind/react";
export const page = style("container");Compiled code
export const page = {className:"sw_5yksj"};Generated stylesheet without preflight
/*! stillwind v0.0.0 | MIT License | https://stillwind.dev */
/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
@layer properties, theme, base, components, utilities;
@layer utilities {
.sw_5yksj {
width: 100%;
padding-inline: 1rem;
@media (width >= 40rem) {
max-width: 40rem;
}
@media (width >= 48rem) {
max-width: 48rem;
}
@media (width >= 64rem) {
max-width: 64rem;
}
@media (width >= 80rem) {
max-width: 80rem;
}
@media (width >= 96rem) {
max-width: 96rem;
}
}
}A static definition replaces a functional one for its exact name:
@utility shadow-lg { ... } replaces the built-in shadow-* for shadow-lg
only. To remove built-in definitions, use
@stillwind-undef-utility.
Body
A body can contain nested rules, @apply, @keyframes, and @property. A
nested selector without & selects descendants: [data-icon] means
& [data-icon]. Variants select the utility element, and the nested selector
applies inside them.
The compiler moves @keyframes and @property rules of a used utility to the
keyframes slot, because browsers ignore them inside a style rule. An unused
utility adds no such rules.
To use a registered custom property, register it with @stillwind-property and require it with @stillwind-require-properties.
The implementation descriptor
(implementation) marks the fixed declarations of the body as part of the
utility’s implementation. The checkImplementation option of a lint rule decides
whether the rule checks them:
- prefer-logical-properties and
no-restricted-length-units skip them
unless the option is
true. Theemvalues below are skipped. - no-important,
no-restricted-declarations, and
no-restricted-theme-tokens check them
unless the option is
false.
Stylesheet
@utility icon-box (implementation) {
width: 1em;
height: 1em;
}Source
import { style } from "stillwind/react";
export const icon = style("icon-box");Compiled code
export const icon = {className:"sw_smxmp"};Generated stylesheet without preflight
/*! stillwind v0.0.0 | MIT License | https://stillwind.dev */
/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
@layer properties, theme, base, components, utilities;
@layer utilities {
.sw_smxmp {
width: 1em;
height: 1em;
}
}Declarations that read the candidate through --value() or --modifier() are
still checked. The built-in sr-only and not-sr-only utilities also use this
descriptor.
Conditions
A definition inside @media or another conditional at-rule keeps its
declarations, and the compiler ignores the condition.
ignored-definition-condition
reports it. Write the condition inside the body instead, or use a variant.