Browser support & limits
Honest about what works where. Every component declares its platform support and how much JavaScript it needs.
What "js" means
none = zero JS · trigger = one native one-liner (
showModal()/showPopover()) · consumer = you write real JS for full behavior (or add an optional @russfranky/shadcss-js helper).Platform support
baseline— All evergreen browsers.popover-api— Popover API — Chrome 114+, Safari 17+, Firefox 125+.has-selector— CSS :has() — Chrome 105+, Safari 15.4+, Firefox 121+.dialog— Native <dialog> showModal() — Chrome 37+, Safari 15.4+, Firefox 98+.details— Native <details>/<summary> — all evergreen browsers.
Limitations (8 components need JS or are visual-only)
These are intentionally not "fake-accessible" CSS shells. They style the component; the interactive/keyboard layer is yours (or an optional helper).
- calendar visual-only — Visual month grid; month nav + date logic need JS; add role=grid/row/gridcell for an interactive picker
- carousel partial — Scroll-snap works with no JS; arrows/dots need JS; viewport is keyboard-focusable
- command visual-only — Styled shell; fuzzy search + arrow-key nav + listbox/option roles need JS
- context-menu partial — Right-click positioning needs oncontextmenu + showPopover(); add menu roles
- input-otp partial — Visual boxes; auto-advance needs JS; per-input aria-label + group label
- resizable visual-only — Visual layout; drag needs JS; handle: tabindex=0 role=separator aria-valuenow
- slider stable — Native <input type=range>; fill-track tracking needs a one-line oninput; label it
- toggle partial — Standalone needs JS to flip aria-pressed; use toggle-group for zero-JS
Full matrix
| Component | Status | JS | Support |
|---|---|---|---|
| accordion | stable | none | details |
| alert | stable | none | baseline |
| alert-dialog | stable | trigger | dialog |
| aspect-ratio | stable | none | baseline |
| avatar | stable | none | baseline |
| badge | stable | none | baseline |
| breadcrumb | stable | none | baseline |
| button | stable | none | baseline |
| calendar | visual-only | consumer | baseline |
| card | stable | none | baseline |
| carousel | partial | consumer | baseline |
| checkbox | stable | none | baseline |
| collapsible | stable | none | details |
| command | visual-only | consumer | popover-api |
| container | stable | none | baseline |
| context-menu | partial | consumer | popover-api |
| dialog | stable | trigger | dialog |
| drawer | stable | trigger | dialog |
| dropdown | stable | trigger | popover-api |
| empty | stable | none | baseline |
| field | stable | none | baseline |
| hover-card | stable | none | baseline |
| input | stable | none | baseline |
| input-otp | partial | consumer | baseline |
| kbd | stable | none | baseline |
| label | stable | none | baseline |
| menubar | stable | trigger | popover-api |
| navigation-menu | stable | none | baseline |
| pagination | stable | none | baseline |
| popover | stable | trigger | popover-api |
| progress | stable | none | baseline |
| radio | stable | none | baseline |
| radio-group | stable | none | has-selector |
| resizable | visual-only | consumer | baseline |
| scroll-area | stable | none | baseline |
| select | stable | none | baseline |
| separator | stable | none | baseline |
| sheet | stable | trigger | dialog |
| sidebar | stable | none | baseline |
| skeleton | stable | none | baseline |
| slider | stable | consumer | baseline |
| sonner | stable | trigger | popover-api |
| spinner | stable | none | baseline |
| switch | stable | none | baseline |
| table | stable | none | baseline |
| tabs | stable | none | has-selector |
| textarea | stable | none | baseline |
| toast | stable | trigger | popover-api |
| toggle | partial | consumer | baseline |
| toggle-group | stable | none | has-selector |
| tooltip | stable | none | baseline |
| typography | stable | none | baseline |