CSS contracts
Styling should be driven by slot markers and state attributes. Avoid tag selectors and avoid assuming the overlay stays inside the root tree.
| Selector | Details |
|---|---|
[data-slot="autocomplete"] | Root state owner. Use for state-driven styling only, not layout assumptions. |
[data-slot="autocomplete-trigger-container"] | Primary input shell. Usually the main border, background, and focus-ring surface. |
[data-slot="autocomplete-trigger"] | Native input. Keep it visually quiet so the shell owns the focus treatment. |
[data-slot="autocomplete-icon"] | Optional icon or affordance slot beside the trigger. |
[data-slot="autocomplete-overlay"] | Portaled overlay surface. Style it directly because it moves to document.body. |
[data-slot="autocomplete-listbox"] | Listbox stack inside the overlay. |
[data-slot="autocomplete-option"] | Interactive option rows. Read active/selected/disabled state attributes here. |
[data-slot="autocomplete-empty"] | Reserved empty-state slot for no results. |
State selectors
The root exposes open, disabled, loading, and invalid state. Options expose active, selected, and disabled state. Those markers are enough for most product skins.
State selector starter
css
[data-slot='autocomplete'][data-state='open'] { ... }
[data-slot='autocomplete'][data-invalid] [data-slot='autocomplete-trigger-container'] { ... }
[data-slot='autocomplete-option'][data-active] { ... }
[data-slot='autocomplete-option'][data-selected] { ... }
[data-slot='autocomplete-option'][data-disabled] { ... }
User scenario style examples
The primitive stays the same while the trigger shell and overlay surface carry the visual language.
Release owner shell (Plain-CSS)
Release owner
Assign a shipping owner before the release branch opens.
Release owner shell (Tailwind CSS)
Release owner
Assign a shipping owner before the release branch opens.
- Abigail Chen
- Kiran Rao
- Lucy Martin
- Mina Lee
- Omar Aziz