Styling
The headless collapsible contract is mostly slot and state driven. You style the owner markup around three stable hooks: root, trigger, and content.
Slot and state hooks
| Selector | When it appears | Typical use |
|---|---|---|
[data-slot="collapsible"] | Always on the root directive. | Outer border, radius, and shell spacing. |
[data-slot="collapsible-trigger"] | Always on the trigger button. | Header layout, text alignment, and icon placement. |
[data-slot="collapsible-content"] | Always on the content region. | Panel padding, background, and inner layout. |
[data-state="open"] / [data-state="closed"] | On root, trigger, and content. | Chevron rotation, border emphasis, and motion classes. |
[data-disabled] | On root and trigger when disabled. | Lower emphasis and pointer affordance changes. |
CSS starter
Headless collapsible starter CSS
css
[data-slot="collapsible"] {
border: 1px solid var(--tng-semantic-border-subtle);
border-radius: 1rem;
overflow: hidden;
}
[data-slot="collapsible-trigger"] {
width: 100%;
border: 0;
background: var(--tng-semantic-background-surface);
padding: 0.9rem 1rem;
text-align: left;
}
[data-slot="collapsible-content"] {
border-top: 1px solid var(--tng-semantic-border-subtle);
padding: 1rem;
background: var(--tng-semantic-background-muted);
}
[data-slot='collapsible-trigger'][data-state='open'] {
color: var(--tng-semantic-foreground-primary);
}
Practical guidance
- Style your inner content structure separately from the disclosure shell.
- Use owner-authored classes for step states like complete, current, or error.
- Prefer animating inner wrappers rather than the
hiddencontent element directly. - Keep iconography inside the trigger markup so you can rotate or swap it from
data-state.