Interaction
Set cursor, pointer, selection, resizing, and accent-color behavior.
Adjust the small browser behaviors around native controls: accent color, pointer targeting, cursor feedback, resizing, and text selection. These classes complement semantic HTML; they do not replace control behavior or labels.
Quick reference
| Example class | Expected declarations |
|---|---|
accent-brand | accent-color: var(--zw-color-brand); |
cursor-pointer | cursor: pointer; |
pointer-events-none | pointer-events: none; |
resize-y | resize: vertical; |
select-all | user-select: all; |
appearance-auto | appearance: auto; |
appearance-none | appearance: none; |
Example setup
Every preview explicitly uses spec: 1, reset: "none", strict mode, spacingUnit: "0.25rem", no breakpoints, and defaultTransitionTimingFunction: "ease". The settings example configures tokens.colors.brand for the checkbox accent. Checkboxes, buttons, a search input, code text, and a textarea keep their native keyboard and pointer behavior.
Examples in use
Style a real settings form
The labeled checkbox uses accent-brand, and two native buttons show pointer and not-allowed cursor feedback; the disabled button remains semantically disabled.
<fieldset class="wind-demo-form"><legend>Preferences</legend><label><input type="checkbox" checked class="accent-brand"> Enable email updates</label><button type="button" class="wind-demo-button cursor-pointer">Save preferences</button><button type="button" disabled class="wind-demo-button cursor-not-allowed">Unavailable while saving</button></fieldset>@layer zw-reset, zw-tokens, zfb-hi, base, components;
@layer zw-tokens {
:root {
--zw-color-brand: #0f766e;
--zw-spacing-unit: .25rem;
}
}
.wind-demo-form {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: .8rem 1.2rem;
max-width: 35rem;
padding: 1rem;
border: 1px solid #a7bacd;
color: #24364b;
font: 15px / 1.5 system-ui, sans-serif;
}
.wind-demo-form legend {
padding: 0 .35rem;
font-weight: 650;
}
.wind-demo-form label {
display: inline-flex;
align-items: center;
gap: .45rem;
}
.wind-demo-button {
border: 1px solid #526477;
border-radius: .35rem;
background: #eef3f8;
padding: .55rem .75rem;
color: inherit;
font: inherit;
}
.wind-demo-button:focus-visible {
outline: 3px solid #1670b8;
outline-offset: 3px;
}
.accent-brand {
accent-color: var(--zw-color-brand);
}
.cursor-not-allowed {
cursor: not-allowed;
}
.cursor-pointer {
cursor: pointer;
}Configuration for this example
{
"wind": {
"spec": 1,
"reset": "none",
"strict": true,
"tokens": {
"spacingUnit": "0.25rem",
"colors": {
"brand": "#0f766e"
}
},
"breakpoints": {},
"defaultTransitionTimingFunction": "ease",
"authoredClasses": {
"wind-demo-form": true,
"wind-demo-button": true
},
"safelist": {
"docs-preview": [
"accent-brand",
"cursor-pointer",
"cursor-not-allowed"
]
}
}
}Authored demonstration CSS
.wind-demo-form { display: flex; flex-wrap: wrap; align-items: center; gap: 0.8rem 1.2rem; max-width: 35rem; padding: 1rem; border: 1px solid #a7bacd; color: #24364b; font: 15px/1.5 system-ui, sans-serif; }
.wind-demo-form legend { padding: 0 0.35rem; font-weight: 650; }
.wind-demo-form label { display: inline-flex; align-items: center; gap: 0.45rem; }
.wind-demo-button { border: 1px solid #526477; border-radius: 0.35rem; background: #eef3f8; padding: 0.55rem 0.75rem; color: inherit; font: inherit; }
.wind-demo-button:focus-visible { outline: 3px solid #1670b8; outline-offset: 3px; }Let clicks pass through decoration
pointer-events-none prevents the decorative search glyph from intercepting a click intended for the labeled search input.
<label class="wind-demo-search"><span class="wind-demo-label">Search</span><span class="wind-demo-searchbox"><span class="wind-demo-search-icon pointer-events-none" aria-hidden="true">⌕</span><input type="search" value="motion utilities" class="wind-demo-search-input"></span></label>@layer zw-reset, zw-tokens, zfb-hi, base, components;
@layer zw-tokens {
:root {
--zw-spacing-unit: .25rem;
}
}
.wind-demo-search {
display: grid;
gap: .35rem;
width: min(24rem, 100%);
color: #24364b;
font: 15px / 1.5 system-ui, sans-serif;
}
.wind-demo-searchbox {
position: relative;
}
.wind-demo-search-icon {
position: absolute;
left: .7rem;
top: .35rem;
color: #526477;
font-size: 1.5rem;
line-height: 1;
}
.wind-demo-search-input {
box-sizing: border-box;
width: 100%;
border: 1px solid #849bb3;
border-radius: .35rem;
padding: .55rem .75rem .55rem 2.3rem;
color: inherit;
font: inherit;
}
.wind-demo-search-input:focus-visible {
outline: 3px solid #1670b8;
outline-offset: 2px;
}
.pointer-events-none {
pointer-events: none;
}Configuration for this example
{
"wind": {
"spec": 1,
"reset": "none",
"strict": true,
"tokens": {
"spacingUnit": "0.25rem"
},
"breakpoints": {},
"defaultTransitionTimingFunction": "ease",
"authoredClasses": {
"wind-demo-search": true,
"wind-demo-label": true,
"wind-demo-searchbox": true,
"wind-demo-search-icon": true,
"wind-demo-search-input": true
},
"safelist": {
"docs-preview": [
"pointer-events-none"
]
}
}
}Authored demonstration CSS
.wind-demo-search { display: grid; gap: 0.35rem; width: min(24rem, 100%); color: #24364b; font: 15px/1.5 system-ui, sans-serif; }
.wind-demo-searchbox { position: relative; }
.wind-demo-search-icon { position: absolute; left: 0.7rem; top: 0.35rem; color: #526477; font-size: 1.5rem; line-height: 1; }
.wind-demo-search-input { box-sizing: border-box; width: 100%; border: 1px solid #849bb3; border-radius: 0.35rem; padding: 0.55rem 0.75rem 0.55rem 2.3rem; color: inherit; font: inherit; }
.wind-demo-search-input:focus-visible { outline: 3px solid #1670b8; outline-offset: 2px; }Select a command and resize notes
select-all lets a click select the full command, while resize-y gives a native textarea a vertical resize handle.
<div class="wind-demo-tools"><p>Click the command to select it in full: <code class="wind-demo-code select-all">pnpm --filter docs check</code></p><label class="wind-demo-note">Scratch notes<textarea class="wind-demo-textarea resize-y">You can resize this field vertically.</textarea></label></div>@layer zw-reset, zw-tokens, zfb-hi, base, components;
@layer zw-tokens {
:root {
--zw-spacing-unit: .25rem;
}
}
.wind-demo-tools {
display: grid;
gap: .8rem;
max-width: 34rem;
color: #24364b;
font: 15px / 1.5 system-ui, sans-serif;
}
.wind-demo-tools p {
margin: 0;
}
.wind-demo-code {
display: inline-block;
border: 1px solid #a7bacd;
border-radius: .25rem;
background: #f2f6fa;
padding: .2rem .45rem;
font: .9em / 1.5 ui-monospace, monospace;
}
.wind-demo-note {
display: grid;
gap: .3rem;
}
.wind-demo-textarea {
box-sizing: border-box;
width: 100%;
min-height: 4rem;
border: 1px solid #849bb3;
border-radius: .35rem;
padding: .55rem;
color: inherit;
font: inherit;
}
.wind-demo-textarea:focus-visible {
outline: 3px solid #1670b8;
outline-offset: 2px;
}
.resize-y {
resize: vertical;
}
.select-all {
user-select: all;
}Configuration for this example
{
"wind": {
"spec": 1,
"reset": "none",
"strict": true,
"tokens": {
"spacingUnit": "0.25rem"
},
"breakpoints": {},
"defaultTransitionTimingFunction": "ease",
"authoredClasses": {
"wind-demo-tools": true,
"wind-demo-code": true,
"wind-demo-note": true,
"wind-demo-textarea": true
},
"safelist": {
"docs-preview": [
"select-all",
"resize-y"
]
}
}
}Authored demonstration CSS
.wind-demo-tools { display: grid; gap: 0.8rem; max-width: 34rem; color: #24364b; font: 15px/1.5 system-ui, sans-serif; }
.wind-demo-tools p { margin: 0; }
.wind-demo-code { display: inline-block; border: 1px solid #a7bacd; border-radius: 0.25rem; background: #f2f6fa; padding: 0.2rem 0.45rem; font: 0.9em/1.5 ui-monospace, monospace; }
.wind-demo-note { display: grid; gap: 0.3rem; }
.wind-demo-textarea { box-sizing: border-box; width: 100%; min-height: 4rem; border: 1px solid #849bb3; border-radius: 0.35rem; padding: 0.55rem; color: inherit; font: inherit; }
.wind-demo-textarea:focus-visible { outline: 3px solid #1670b8; outline-offset: 2px; }Native appearance
appearance uses exact supported Wind utility classes.
<div class="wind-demo-new"><input class="appearance-auto" type="checkbox" checked aria-label="Native checkbox"><input class="appearance-none" type="checkbox" aria-label="Unstyled checkbox"></div>@layer zw-reset, zw-tokens, zfb-hi, base, components;
@layer zw-tokens {
:root {
--zw-spacing-unit: .25rem;
}
}
.wind-demo-new {
color: #203046;
font: 14px / 1.5 system-ui, sans-serif;
}
.appearance-auto {
appearance: auto;
}
.appearance-none {
appearance: none;
}Configuration for this example
{
"wind": {
"spec": 1,
"reset": "none",
"strict": true,
"tokens": {
"spacingUnit": "0.25rem"
},
"breakpoints": {},
"defaultTransitionTimingFunction": "ease",
"authoredClasses": {
"wind-demo-new": true
},
"safelist": {
"docs-preview": [
"appearance-auto",
"appearance-none"
]
}
}
}Authored demonstration CSS
.wind-demo-new { color: #203046; font: 14px/1.5 system-ui, sans-serif; }Custom and named values
The accent utility accepts a configured colors token such as accent-brand, the fixed values transparent and current, or a valid arbitrary color. Cursor, pointer-events, resize, and select use finite catalog keywords; they have no inherited named theme values. pointer-events-none on the decorative search glyph lets the pointer reach the underlying input. Use disabled on an actually unavailable button as well as a not-allowed cursor.
Related guides: Utility grammar · Variants
Catalog details
accent
| Field | Value |
|---|---|
| Catalog identifier | v1.accent |
| Class pattern | accent-<suffix> |
| Grammar | {"acceptedKinds":["keyword","token","arbitrary"],"arbitraryProperty":"accent-color","allowsFractionSlash":false,"allowsColorOpacity":true} |
| Accepted values | 2 |
| Token categories | colors |
| Negative-value policy | forbidden |
| Conflict group and rank | interaction (40) |
| Order rank | 0 |
| Selector shape | ownElement |
| Spec version | 1 |
| Emitter properties | accent-color |
Accepted values
| Kind | Suffix | Emitted value |
|---|---|---|
keyword | "transparent" | "transparent" |
keyword | "current" | "currentColor" |
Declaration templates
| Property | Value kind | Fixed value |
|---|---|---|
accent-color | resolved | null |
Catalog examples
| Example class | Expected declarations |
|---|---|
accent-[red]/40 | accent-color: color-mix(in oklab, red 40%, transparent) |
appearance-auto
| Field | Value |
|---|---|
| Catalog identifier | v1.appearance-auto |
| Class pattern | appearance-auto |
| Grammar | {"acceptedKinds":["exact"],"arbitraryProperty":null,"allowsFractionSlash":false,"allowsColorOpacity":false} |
| Accepted values | 1 |
| Token categories | No token category |
| Negative-value policy | forbidden |
| Conflict group and rank | interaction (40) |
| Order rank | 0 |
| Selector shape | ownElement |
| Spec version | 1 |
| Emitter properties | appearance |
Accepted values
| Kind | Suffix | Emitted value |
|---|---|---|
exact | null | "auto" |
Declaration templates
| Property | Value kind | Fixed value |
|---|---|---|
appearance | resolved | null |
Catalog examples
| Example class | Expected declarations |
|---|---|
appearance-auto | appearance: auto |
appearance-none
| Field | Value |
|---|---|
| Catalog identifier | v1.appearance-none |
| Class pattern | appearance-none |
| Grammar | {"acceptedKinds":["exact"],"arbitraryProperty":null,"allowsFractionSlash":false,"allowsColorOpacity":false} |
| Accepted values | 1 |
| Token categories | No token category |
| Negative-value policy | forbidden |
| Conflict group and rank | interaction (40) |
| Order rank | 0 |
| Selector shape | ownElement |
| Spec version | 1 |
| Emitter properties | appearance |
Accepted values
| Kind | Suffix | Emitted value |
|---|---|---|
exact | null | "none" |
Declaration templates
| Property | Value kind | Fixed value |
|---|---|---|
appearance | resolved | null |
Catalog examples
| Example class | Expected declarations |
|---|---|
appearance-none | appearance: none |
cursor
| Field | Value |
|---|---|
| Catalog identifier | v1.cursor |
| Class pattern | cursor-<suffix> |
| Grammar | {"acceptedKinds":["keyword"],"arbitraryProperty":null,"allowsFractionSlash":false,"allowsColorOpacity":false} |
| Accepted values | 36 |
| Token categories | No token category |
| Negative-value policy | forbidden |
| Conflict group and rank | interaction (40) |
| Order rank | 0 |
| Selector shape | ownElement |
| Spec version | 1 |
| Emitter properties | cursor |
Accepted values
| Kind | Suffix | Emitted value |
|---|---|---|
keyword | "auto" | "auto" |
keyword | "default" | "default" |
keyword | "pointer" | "pointer" |
keyword | "not-allowed" | "not-allowed" |
keyword | "text" | "text" |
keyword | "move" | "move" |
keyword | "grab" | "grab" |
keyword | "grabbing" | "grabbing" |
keyword | "wait" | "wait" |
keyword | "help" | "help" |
keyword | "none" | "none" |
keyword | "progress" | "progress" |
keyword | "crosshair" | "crosshair" |
keyword | "cell" | "cell" |
keyword | "copy" | "copy" |
keyword | "alias" | "alias" |
keyword | "no-drop" | "no-drop" |
keyword | "context-menu" | "context-menu" |
keyword | "vertical-text" | "vertical-text" |
keyword | "all-scroll" | "all-scroll" |
keyword | "zoom-in" | "zoom-in" |
keyword | "zoom-out" | "zoom-out" |
keyword | "n-resize" | "n-resize" |
keyword | "s-resize" | "s-resize" |
keyword | "e-resize" | "e-resize" |
keyword | "w-resize" | "w-resize" |
keyword | "ne-resize" | "ne-resize" |
keyword | "nw-resize" | "nw-resize" |
keyword | "se-resize" | "se-resize" |
keyword | "sw-resize" | "sw-resize" |
keyword | "ew-resize" | "ew-resize" |
keyword | "ns-resize" | "ns-resize" |
keyword | "nesw-resize" | "nesw-resize" |
keyword | "nwse-resize" | "nwse-resize" |
keyword | "col-resize" | "col-resize" |
keyword | "row-resize" | "row-resize" |
Declaration templates
| Property | Value kind | Fixed value |
|---|---|---|
cursor | resolved | null |
Catalog examples
| Example class | Expected declarations |
|---|---|
cursor-pointer | cursor: pointer |
pointer-events
| Field | Value |
|---|---|
| Catalog identifier | v1.pointer-events |
| Class pattern | pointer-events-<suffix> |
| Grammar | {"acceptedKinds":["keyword"],"arbitraryProperty":null,"allowsFractionSlash":false,"allowsColorOpacity":false} |
| Accepted values | 2 |
| Token categories | No token category |
| Negative-value policy | forbidden |
| Conflict group and rank | interaction (40) |
| Order rank | 0 |
| Selector shape | ownElement |
| Spec version | 1 |
| Emitter properties | pointer-events |
Accepted values
| Kind | Suffix | Emitted value |
|---|---|---|
keyword | "auto" | "auto" |
keyword | "none" | "none" |
Declaration templates
| Property | Value kind | Fixed value |
|---|---|---|
pointer-events | resolved | null |
Catalog examples
| Example class | Expected declarations |
|---|---|
pointer-events-none | pointer-events: none |
resize
| Field | Value |
|---|---|
| Catalog identifier | v1.resize |
| Class pattern | resize or resize-<suffix> |
| Grammar | {"acceptedKinds":["keyword"],"arbitraryProperty":null,"allowsFractionSlash":false,"allowsColorOpacity":false} |
| Accepted values | 4 |
| Token categories | No token category |
| Negative-value policy | forbidden |
| Conflict group and rank | interaction (40) |
| Order rank | 0 |
| Selector shape | ownElement |
| Spec version | 1 |
| Emitter properties | resize |
Accepted values
| Kind | Suffix | Emitted value |
|---|---|---|
keyword | null | "both" |
keyword | "x" | "horizontal" |
keyword | "y" | "vertical" |
keyword | "none" | "none" |
Declaration templates
| Property | Value kind | Fixed value |
|---|---|---|
resize | resolved | null |
Catalog examples
| Example class | Expected declarations |
|---|---|
resize-x | resize: horizontal |
select
| Field | Value |
|---|---|
| Catalog identifier | v1.select |
| Class pattern | select-<suffix> |
| Grammar | {"acceptedKinds":["keyword"],"arbitraryProperty":null,"allowsFractionSlash":false,"allowsColorOpacity":false} |
| Accepted values | 4 |
| Token categories | No token category |
| Negative-value policy | forbidden |
| Conflict group and rank | interaction (40) |
| Order rank | 0 |
| Selector shape | ownElement |
| Spec version | 1 |
| Emitter properties | user-select |
Accepted values
| Kind | Suffix | Emitted value |
|---|---|---|
keyword | "none" | "none" |
keyword | "text" | "text" |
keyword | "all" | "all" |
keyword | "auto" | "auto" |
Declaration templates
| Property | Value kind | Fixed value |
|---|---|---|
user-select | resolved | null |
Catalog examples
| Example class | Expected declarations |
|---|---|
select-none | user-select: none |