Docs Start
Browser support
Support is explicit and versioned: every native path names the platform features it depends on, their Baseline status as documented in the contract, and what happens where a feature is missing. The default package is never a polyfill bundle.
On this page
Policy
A native primitive uses a platform feature directly, so the browser target is the feature's support, not a version list chosen by the package. Each contract records the features it relies on and their Baseline status; the compatibility document turns that into one table and, from release stage 4 on, into a versioned promise. Until then the statements on this page describe what is tested, not what is guaranteed.
- Native paths depend on Baseline features and stay native; no fallback logic is mixed in.
- Compatibility code is opt-in or target-selected and never silently bundled into a native path (shipping invariant E of ADR 0005). No compatibility module exists today.
- Feature detection comes before user-agent detection. The packages contain no browser-name branching and, today, no feature detection either: the native paths use the feature and the stylesheet relies on CSS fallback behavior.
- No
targetoption exists in the Vite plugin; the blueprint names one as a future direction, and it is not built.
Feature table
One row per capability: the native path, the compatibility path and the fallback. The Baseline column repeats what each contract documents as of 2026-09-27; the sections further down quote the contracts themselves.
| Feature (native path) | Used by | Baseline status, documented in the contract as of 2026-09-27 | Compatibility path | Without support |
|---|---|---|---|---|
<dialog>, showModal(), the top layer, ::backdrop, page inertness | Dialog | Widely available (newly available in 2022) | none exists; the package does not polyfill | No fallback is documented; the element is the base of the primitive |
Invoker commands (command, commandfor) | Dialog and Popover invokers, Button | Newly available, not yet widely: Chrome 135, Safari 26, Firefox 144, shipped during 2025 | None exists; an opt-in module is named as an option in ADR 0005 | Two calls in application code (showModal(), close()); without them the dialog stays closed |
Popover API (popover, popovertarget, popovertargetaction, :popover-open, ToggleEvent) | Popover, Menu, Menubar, Combobox, Tooltip, Hover card, Toast, Context menu, Date picker, the mobile navigation of this site | Newly available since April 2024: Chrome 114, Safari 17, Firefox 125 | none exists; the package does not polyfill | The attribute is ignored and the content renders inline; a menu loses its top layer and light dismiss; a combobox uses a hidden-toggled popup instead |
showPopover({ source }) | Combobox popup (the input as the implicit anchor and invoker), Tooltip | Not Baseline: Chrome 133, Safari 26 | none exists; the package does not polyfill | Passed as an option that browsers without it ignore; popover="manual" needs no invoker relationship |
CSS anchor positioning (position-area, position-try-fallbacks) | Popover, Menu and Tooltip placement in the stylesheet | Not Baseline: Chrome 125, Safari 26 | None exists; an optional positioning module is a named possibility, not a plan | The platform default placement: centered in the top layer |
CSS anchor positioning (anchor-name, anchor-scope, position-anchor, position-area, anchor-size()) | Combobox popup placement in the stylesheet | Not Baseline: Chrome 125 (anchor-scope 131), Safari 26 | none exists; the package does not polyfill | A hidden-toggled popup is positioned under the root with absolute positioning; a popover popup is centered in the top layer |
KeyboardEvent.isComposing | Combobox (keys during an IME composition are ignored) | Widely available; keyCode 229 covers browsers that report the state late | none exists; the package does not polyfill | No fallback is documented |
AbortSignal on addEventListener, Element.isConnected | Combobox session listener (Tier 2 scoped controller) | Widely available | none exists; the package does not polyfill | No fallback is documented |
<details>, <summary>, the toggle event | Disclosure | Widely available | none exists; the package does not polyfill | No fallback is documented; the element is the base of the primitive |
name on <details> for exclusive groups | Disclosure accordions | Newly available since September 2024: Chrome 120, Safari 17.2, Firefox 130 | none exists; the package does not polyfill | Siblings stay open independently |
::details-content, interpolate-size | Disclosure open transition in the stylesheet | Used only where supported; nothing depends on them | none exists; the package does not polyfill | No transition |
appearance: none on checkboxes, :checked, :indeterminate | Checkbox, Switch | Widely available | none exists; the package does not polyfill | No fallback is documented |
:user-invalid | Validation styles of Checkbox, Input, Date field, One-time code and File field | Baseline 2023 | none exists; the package does not polyfill | Native validation still works; the invalid styling does not apply |
role="switch" on a checkbox (ARIA 1.2) | Switch | Mapped by current screen readers | none exists; the package does not polyfill | Announced as a checkbox where the role is not mapped |
<button>, :focus-visible | Button | Widely available | none exists; the package does not polyfill | No fallback is documented |
<fieldset>, <legend>, <input type="radio"> | Radio group | Widely available | none exists; the package does not polyfill | No fallback is documented |
:dir(rtl), read only to resolve dir="auto" | Tabs, Listbox, Tree, Toggle group, Toolbar, Calendar, Splitter and every behavior with horizontal arrow keys | Guarded in packages/primitives/src/internal/direction.ts | none exists; the package does not polyfill | dir="auto" resolves to left-to-right; an explicit dir attribute always works |
ES2022 JavaScript, composedPath() | Every Tier 1 and Tier 2 behavior (the shared router) | The output target of every package; no transpilation to an older target | Run the packages through your own bundler for an older target | Without the runtime every primitive keeps its server-rendered state and native parts: tabs cannot switch, a menu opens as a plain popover, a combobox is a plain text field; each contract states its own case |
popover="hint" | Tooltip, Hover card | Not Baseline: Chrome 133 | none exists; the package does not polyfill | The value falls back to a manual popover, which the behavior hides itself |
Customizable select (appearance: base-select, ::picker(select), ::checkmark, <selectedcontent>) | Select | Not Baseline: Chrome 135, Safari 27; not in Firefox | none exists; the package does not polyfill | The styled closed box with the platform picker |
closedby on <dialog> | Alert dialog, Drawer | Not Baseline: Chrome 134, Firefox 141; not in Safari 27 | none exists; the package does not polyfill | Escape still cancels an alert dialog; a click on the backdrop does not close a drawer |
transition of overlay (with transition-behavior: allow-discrete) | Exit transitions of Alert dialog and Drawer | Not Baseline: Chrome 117; not in Safari 27 | none exists; the package does not polyfill | The exit transition runs after the dialog has left the top layer |
field-sizing: content | Input (textarea) | Newly available since June 2026: Chrome 123, Safari 26.2, Firefox 152 | none exists; the package does not polyfill | The textarea keeps the height of its rows and scrolls |
:has() | Segmented control, Rating, Steps, Field, Number field, Range slider, Context menu styles | Baseline 2023 | none exists; the package does not polyfill | The state drawn from a descendant is not drawn (the checked segment, the filled stars, a complete step); the native controls keep working |
Vertical form controls (writing-mode on <input type="range">) | Slider, vertical | Baseline 2024: Chrome 124, Firefox 120, Safari 17.4 | none exists; the package does not polyfill | The slider is drawn horizontally |
Form control pseudo-elements (range thumb and track, progress value, meter regions) | Slider, Range slider, Progress, Meter | Not standardized: -webkit- and -moz- pseudo-elements | none exists; the package does not polyfill | The platform draws the control |
<datalist> suggestions | Autocomplete | Not Baseline as a feature; the list attribute is widely available | The Combobox primitive renders and styles its own options | A plain text field; the typed value is still submitted |
The contextmenu event | Context menu | Widely available; Safari on iOS does not dispatch it for a long press | none exists; the package does not polyfill | Touch-only iPhone and iPad users cannot open the menu; offer the actions elsewhere |
Dropping files on <input type="file">; dragenter, dragleave, drop | File drop | Widely available; accept does not filter dropped files | none exists; the package does not polyfill | Without JavaScript the input is shown as it is and still accepts a drop |
Pointer events, pointer capture, touch-action | Splitter | Widely available | none exists; the package does not polyfill | No fallback is documented |
@media (scripting) | Date picker, Number field | Baseline 2023 | none exists; the package does not polyfill | The trigger and step buttons stay visible without JavaScript and do nothing |
round() | Range slider (which thumb is on top where both meet) | Baseline 2024 | none exists; the package does not polyfill | The end thumb stays on top |
color-mix() | Alert, Spinner, Pagination | Baseline 2023 | none exists; the package does not polyfill | The tinted border or track takes a neutral token |
Alternative text in content (content: counter() / "") | Steps | Baseline 2024 | none exists; the package does not polyfill | A screen reader may read the step number with the step |
accent-color | Slider with data-variant="native" | Not Baseline: Chrome 93, Firefox 92, Safari 26.2 | none exists; the package does not polyfill | The platform slider in its default color |
position: sticky | Table sticky header | Widely available | none exists; the package does not polyfill | A normal header |
This browser
Feature detection in the browser you are using, for the features the native paths depend on. The detection runs after the page loads and requires JavaScript; the proof page shows the same table next to the runtime it reads.
| Feature | Used by | This browser |
|---|---|---|
| Detection runs in the browser after load. | ||
Outside the target
A missing feature degrades the way the contract describes, never into a JavaScript replacement
pulled in without being asked. The one case that matters most today is invoker commands, which
are newer than the other features: where command and commandfor are missing,
a dialog needs two calls in application code, and nothing from the package.
<script lang="ts">
// Where invoker commands are missing: two calls in application code, no package involved.
let dialog: HTMLDialogElement;
</script>
<button type="button" onclick={() => dialog.showModal()}>Settings</button>
<dialog bind:this={dialog} id="settings" data-slean="dialog" aria-labelledby="settings-title">
<h2 id="settings-title" data-slean-part="title">Settings</h2>
<button type="button" onclick={() => dialog.close()}>Close</button>
</dialog>Application code that must branch on support should test the feature, not the browser name.
// Feature detection before user-agent detection: what application code may branch on.
const commands = 'commandForElement' in HTMLButtonElement.prototype;
const popover = 'popover' in HTMLElement.prototype;
const anchors = CSS.supports('position-area: bottom');Tier 1 behaviors need the runtime: without JavaScript, tabs keep the state the server rendered
(the selected panel visible, the others hidden) and cannot switch; pages that must work without
script can render every panel without hidden and accept a stacked layout. A menu
opens and closes as a plain popover, link items work, and movement inside is Tab-based. A
listbox keeps its authored selection and cannot change it. The combobox, Tier 2, is a plain text
field whose popup never opens; a form still submits what was typed, and a <datalist> is the native alternative for suggestions without script.
Compatibility modules
None exists. ADR 0005 names an opt-in module for invoker commands and the blueprint names an optional positioning module; both are possibilities, not plans. When one is built it will be a separate entry point selected by the application or by a build target, and a consumer fixture will assert that the native path does not include it (shipping invariant E). Until then the fallbacks in the table are the whole story.
Testing
Browser tests run in Chromium only: the locally installed Google Chrome, whose version is recorded in the audit and the benchmark file, and Playwright's Chromium in CI. The native contracts are exercised with page JavaScript disabled in native.spec.ts. Firefox and WebKit projects are declared in the playground's Playwright configuration; pull-request CI installs Chromium only and skips them, the nightly workflow runs both and fails when a project is skipped, and no run is recorded in this repository yet. A recorded run is a stage 2 requirement in docs/release.md; when it exists it will assert the documented fallback, not the native path, in a browser that lacks a feature. No cross-browser claim is made until then.
Contract excerpts
The "Platform features and Baseline" section of every contract, read from the contract file when this site is built. The contracts are the source; this page cannot drift from them.
accordion
<details>,<summary>and thetoggleevent: Baseline widely available.namefor exclusive groups: Baseline newly available since September 2024 (Chrome 120, Safari 17.2, Firefox 130). Elsewhere every item opens on its own.- Find-in-page opens a closed item that contains the match: Chrome 97, Firefox 139, Safari 26.2. In an exclusive group this closes the item that was open.
::details-content: Baseline newly available since September 2025 (Chrome 131, Safari 18.4, Firefox 143).interpolate-size: allow-keywords, which lets the styles animate the height toauto, is in Chrome 129 and not in Firefox or Safari; there the content appears without a transition.
alert
role="status"androle="alert"are ARIA 1.1 live region roles, exposed by every current browser. When and how a message is spoken differs between screen readers; the rules above are the ones that hold across them.color-mix()mixes the tone borders; it is Baseline 2023. Without it the border keeps the neutral--slean-border.:empty(the empty root and the drawn icon) is widely available.
alert-dialog
<dialog>,showModal(), the top layer,::backdropand page inertness: Baseline widely available (newly available in 2022).- Invoker commands (
command,commandfor): shipped in Chrome 135, Safari 26 and Firefox 144 during 2025; Baseline newly available, not yet widely available. Where they are missing, a two-line inline script (showModal()/close()) is the fallback; the package does not polyfill it. A<form method="dialog">closes the dialog in every browser that has<dialog>. closedby: Chrome 134 and Firefox 141 implement it; Safari 27 does not (checked with the system WebKit of macOS 27). There, Escape still cancels the dialog as described under Keyboard interaction; an application that must block it adds acancellistener that callspreventDefault(), which is script and outside this contract.- The entrance transition uses
@starting-styleand the exit usesallow-discretetransitions ofdisplay(transition-behavior), both Baseline 2024. The exit also transitionsoverlay, which Chrome 117 and later implement and Safari 27 does not; there the exit transition runs after the dialog has left the top layer.
autocomplete
- The
listattribute of<input>is Baseline 2019 (widely available). <datalist>as a feature is not Baseline: how options are matched (anywhere in the text or at the start), whetherlabelis shown and whether the list appears at all differ between browsers. Where no list is shown, the field is a plain text input and the typed value is still submitted.- The list's appearance cannot be changed from CSS. For options rendered and styled by the page, use the
comboboxprimitive (Tier 2).
avatar
<img>withalt,width,heightandloading="lazy": Baseline widely available.- CSS grid, which stacks the image and the initials in one cell: Baseline widely available.
badge
<span> and text: Baseline widely available. Nothing else is used.
breadcrumb
<nav>,<ol>andaria-currentare widely available.- The chevrons turn with the
rotateproperty, Baseline 2022; without it a separator is an unturned corner. :dir()is Baseline 2023; without it the chevrons point to the right under RTL as well.
button
<button> and :focus-visible are Baseline widely available. Invoker commands (command/commandfor) are covered by the dialog and popover contracts.
button-group
role="group", buttons and flex layout: Baseline widely available.- Logical corner radii (
border-start-start-radiusand the others): Baseline 2021, widely available. - The dividers between filled buttons use
color-mix(): Baseline 2023, widely available. Without it, two filled buttons meet without a line. :focus-visible, which raises the focused button: Baseline 2022, widely available.- A split button uses the popover and menu contracts:
popoverandpopovertargetare Baseline 2024, newly available since April 2024.
calendar
Nothing beyond buttons, a table with ARIA grid roles, Intl.DateTimeFormat (Baseline since 2017) and, for the chevrons, :dir() (Baseline 2023). Inside a date picker, the popover features of the popover contract.
card
<article>, headings, links: Baseline widely available.:has(): Baseline 2023 (Chrome 105, Safari 15.4, Firefox 121), widely available since June 2026. The styles use it to lift other controls above a stretched link and to move its focus ring; without it the link covers them and keeps its own ring.
carousel
- Scroll snap (
scroll-snap-type,scroll-snap-align): Baseline 2020, widely available. ::scroll-button(),::scroll-marker,::scroll-marker-groupand:target-current: Chrome 135; not in Firefox or Safari at the time of writing. Elsewhere there are no buttons and no markers; the viewport keeps its scrollbar.- The
tabsmode ofscroll-marker-group: parsed by Chrome 151 (the oldest Chromium the tests have run), which exposes the markers as tabs in either mode; Chrome 154 exposes the defaultlinksmode as a navigation of links. An engine without the keyword drops the declaration and keepsscroll-marker-group: after. - Container scroll-state queries: Chrome 133; used by the styles only for the states of the buttons and markers above.
:dir(): Baseline 2023, widely available.
checkbox
appearance: none on checkboxes, :indeterminate and :checked are Baseline widely available; :user-invalid is Baseline 2023.
color-field
<input type="color">is widely available; the picker's appearance and keyboard differ between browsers.- The swatch pseudo-elements are prefixed and non-standard. Where none applies, the browser's default swatch is drawn inside the styled box.
- The HTML standard adds
alpha(a transparency channel) andcolorspace(limited-srgbordisplay-p3). Safari 27 implements both, and with either one the value becomes a CSS color such ascolor(srgb 1 0 0)instead of hex; Chrome 153 implements neither. The contract does not use them: without them every browser keeps the#rrggbbvalue.
combobox
- Popover API (
popover,showPopover(),hidePopover(),:popover-open,ToggleEvent): Baseline newly available since April 2024 (Chrome 114, Safari 17, Firefox 125). Where it is unsupported the attribute is ignored and the popup renders inline; use ahiddenpopup for those browsers. showPopover({ source }): Chrome 133 and Safari 26; not Baseline. Passed as an option, so browsers without it ignore the argument.- CSS anchor positioning (
anchor-name,anchor-scope,position-anchor,position-area,anchor-size(), fromcombobox.css): Chrome 125 (anchor-scope131) and Safari 26; not Baseline at the time of writing. Without it a hidden-toggled popup is positioned under the root with plain absolute positioning and a popover popup is centered in the top layer. AbortSignalonaddEventListener,Element.isConnected,scrollIntoView({ block }): Baseline widely available.- ARIA combobox roles and properties (
combobox,aria-activedescendant,aria-autocomplete,aria-expanded,aria-controls,listbox,option,aria-selected): ARIA 1.2, widely supported by assistive technology. KeyboardEvent.isComposing: Baseline widely available;keyCode === 229covers browsers that report the composition state late.- The shared router:
Event.composedPath(),getAttributeand ES2022 output: Baseline widely available. No transpilation to an older target is provided.
context-menu
- The
contextmenuevent: Baseline widely available. Safari on iOS does not dispatch it for a long press, so a touch-only iPhone or iPad user cannot open the menu: offer the same actions elsewhere. - Popover API (
showPopover()): Baseline newly available since April 2024 (Chrome 114, Safari 17, Firefox 125).
date-field
<input type="date">, time and datetime-local are Baseline 2021 (widely available); month and week are not in Firefox or Safari desktop, where they fall back to a text input: validate on the server. :user-invalid is Baseline 2023.
date-picker
<input type="date">withmin,maxand form submission: Baseline 2021. It holds the value and is the JavaScript-free path with the platform picker.Intl.DateTimeFormatandformatToParts()(the display format and the calendar's labels): Baseline widely available.- Popover API (
popover="manual",ToggleEvent): Baseline newly available since April 2024. - CSS anchor positioning (in
control.css): Chrome 125 (anchor-scope131) and Safari 26; not Baseline. Without it the popup is centered in the top layer. :has()(the clear button, the range bar, the calendar's range band): Baseline 2023.@media (scripting): Baseline 2023. Where it is unsupported the native and the text inputs both show.- ARIA 1.2 combobox with
aria-haspopup="dialog"and the calendar'srole="grid": widely supported by assistive technology.
descriptions
<dl>,<dt>and<dd>: widely available.<div>groups inside<dl>are valid HTML and are ignored by the accessibility tree.- CSS grid with
repeat(auto-fill, minmax(…)), andmin()andmax()in the track sizes: Baseline 2020, widely available.
dialog
<dialog>,showModal(), the top layer,::backdropand page inertness: Baseline widely available (newly available in 2022).- Invoker commands (
command,commandfor): shipped in Chrome 135, Safari 26 and Firefox 144 during 2025. Baseline newly available at the time of writing, not yet widely available. Where it is missing, a two-line inline script (showModal()/close()) or an opt-in compatibility module (ADR 0005) is the fallback; the package does not polyfill it. closedbyandrequestClose()are newer than the two commands above; the contract does not depend on them.
disclosure
<details>and<summary>, thetoggleevent: Baseline widely available.namefor exclusive groups: Baseline newly available since September 2024 (Chrome 120, Safari 17.2, Firefox 130).::details-contentandinterpolate-sizeare used by the styles for animation only where supported; nothing depends on them.
drawer
<dialog>,showModal(), the top layer,::backdropand page inertness: Baseline widely available (newly available in 2022).- Invoker commands (
command,commandfor): shipped in Chrome 135, Safari 26 and Firefox 144 during 2025; Baseline newly available, not yet widely available. Where they are missing, a two-line inline script (showModal()/close()) is the fallback; the package does not polyfill it. closedby: Chrome 134 and Firefox 141 implement it; Safari 27 does not (checked with the system WebKit of macOS 27). There, a click on the backdrop does not close the drawer; Escape and the close action do.- The slide uses
translate(Baseline 2022),@starting-stylefor the entrance andtransition-behavior: allow-discretefor the exit (both Baseline 2024). The exit also transitionsoverlay, which Chrome 117 and later implement and Safari 27 does not; there the drawer leaves the top layer as soon as it closes, so the backdrop disappears at once and the exit slide is drawn in the page's stacking order. Underprefers-reduced-motion: reducethe duration tokens are zero and the drawer appears and disappears in place. env(safe-area-inset-*)pads the edges that touch the screen; the insets are zero unless the page's viewport meta tag hasviewport-fit=cover.
empty
- Headings, paragraphs, links, buttons and flex layout: Baseline widely available.
- The drawn tray uses generated content on an
:emptyelement: Baseline widely available.
field
<label for>,aria-describedby,aria-invalid, CSS grid: Baseline widely available.:has(), used to mute the label of a disabled control: Baseline 2023 (Chrome 105, Safari 15.4, Firefox 121). Where it is missing the label keeps its color.
file-drop
- Dropping files on
<input type="file">, which setsfilesand dispatcheschange: Baseline widely available.acceptfilters the picker, not a drop: a dropped file of another type is accepted by the input, so validate the type on the server (and in achangelistener if the page should refuse it early). - Drag and drop events (
dragenter,dragleave,drop): Baseline widely available. Intl.ListFormatfor the list of names: Baseline 2021.@media (scripting), which keeps the input visible without JavaScript: Baseline 2023.
file-field
<input type="file">,multipleandacceptare widely available.::file-selector-buttonis Baseline 2021 (widely available). Where it is missing, the browser's default button is shown inside the styled box.captureis honored by mobile browsers; desktop browsers ignore it and open the file chooser.:user-invalid(arequiredfield left empty after an interaction) is Baseline 2023.
hover-card
- Popover API (
popover,showPopover(),hidePopover()): Baseline newly available since April 2024 (Chrome 114, Safari 17, Firefox 125). popover="hint": Chrome 133; not Baseline at the time of writing. Where the value is unknown the attribute falls back to its manual state, and the behavior hides the card itself.showPopover({ source }): Chrome 133 and Safari 26; not Baseline. Without it the card still follows the trigger in the DOM order.- CSS anchor positioning (
position-area): Chrome 125 and Safari 26; not Baseline at the time of writing. Where it is unsupported the card keeps the platform's default placement. - Pointer events: Baseline widely available. Touch pointers are ignored; a tap follows the link.
input
- Text-like
<input>types,<textarea>,::placeholder,:read-only: Baseline widely available. :user-invalid: Baseline 2023 (Chrome 119, Firefox 88, Safari 16.5). Where it is missing the field keeps its normal border after an invalid edit.field-sizing: content, which makes a textarea grow with its content: Baseline newly available since June 2026 (Chrome 123, Safari 26.2, Firefox 152). Where it is missing, the textarea has the height of itsrowsattribute (at least three lines) and scrolls.- The
lhunit of the three-line minimum: Baseline 2023 (Chrome 109, Safari 16.4, Firefox 120).
kbd
<kbd>: Baseline widely available.:has(): Baseline 2023 (Chrome 105, Safari 15.4, Firefox 121), widely available since June 2026. Without it a combination is drawn as one box around its keys.
listbox
- ARIA listbox roles and states (
listbox,option,group,aria-selected,aria-multiselectable,aria-orientation,aria-disabled): ARIA 1.2, widely supported by assistive technology. - The shared router:
Event.composedPath(),getAttributeand ES2022 output (the packages' TypeScript target): Baseline widely available. No transpilation to an older target is provided; a consumer that needs one runs the packages through its own bundler. :dir(rtl), used only to resolvedir="auto": Baseline newly available since December 2023 (Chrome 120, Safari 16.4, Firefox 49). The call is guarded inpackages/primitives/src/internal/direction.ts: where the pseudo-class is unsupported,dir="auto"resolves to left-to-right and explicitdirattributes work everywhere.
menu
- Popover API (
popover,popovertarget,:popover-open,ToggleEvent,hidePopover()): Baseline newly available since April 2024 (Chrome 114, Safari 17, Firefox 125). Where it is unsupported the attribute is ignored and the menu renders inline. - CSS anchor positioning (
position-area, frompopover.css, whichmenu.cssrequires): Chrome 125 and Safari 26; not Baseline at the time of writing. Where it is unsupported the menu keeps the platform's default placement (centered in the top layer). - ARIA menu roles and states (
menu,menuitem,menuitemcheckbox,menuitemradio,group,separator,aria-checked): ARIA 1.2, widely supported by assistive technology. - The shared router:
Event.composedPath(),getAttributeand ES2022 output (the packages' TypeScript target): Baseline widely available. No transpilation to an older target is provided; a consumer that needs one runs the packages through its own bundler.
menubar
- Popover API (
popovertarget,showPopover(),hidePopover(),:popover-open): Baseline newly available since April 2024 (Chrome 114, Safari 17, Firefox 125). :has()for the open item's style: Baseline 2023.- The ARIA menubar pattern (
menubar,menuitem,none): ARIA 1.2, widely supported by assistive technology.
meter
<meter>withlow,highandoptimumis widely available.appearance: none, which lets the stylesheet draw the track and the value, is Baseline 2022.- The regions are styled through pseudo-elements that are not standardized:
::-webkit-meter-bar,::-webkit-meter-optimum-value,::-webkit-meter-suboptimum-valueand::-webkit-meter-even-less-good-valuein Chromium and WebKit;::-moz-meter-barwith the:-moz-meter-sub-optimumand:-moz-meter-sub-sub-optimumpseudo-classes in Firefox. - In Chromium a percentage height on the inner pseudo-elements does not fill the element; the stylesheet gives them
block-size: inherit, so the sizes reach them.
number-field
<input type="number">,stepUp()andstepDown(): Baseline widely available.step="any"cannot be stepped (the platform throws); the buttons then do nothing.@media (scripting)to show the buttons only where they work: Baseline newly available since December 2023.:has()for the focus ring and the invalid state on the root: Baseline newly available since December 2023.
otp-field
inputmodeis Baseline 2021 (widely available). Where it is missing, the default keyboard is shown.autocomplete="one-time-code"is a token of the HTML autofill standard. Safari on iOS and macOS offers a code received by SMS as a suggestion; elsewhere the suggestion depends on the browser and the keyboard, and without one the field is a plain text input. The WebOTP API (navigator.credentials.get()withotp) is a script API and not part of this contract.maxlength,pattern,requiredand thechunit are widely available.:user-invalid, which the stylesheet uses for the invalid border, is Baseline 2023.
pagination
- Links,
<nav>andaria-currentare widely available. - The chevrons turn with the
rotateproperty, Baseline 2022; without it a chevron is an unturned corner. :dir()is Baseline 2023; without it the chevrons are not mirrored under RTL.color-mix()tints the current page's border, Baseline 2023; without it the border stays transparent and the soft fill marks the page.
popover
- Popover API (
popover,popovertarget,popovertargetaction,:popover-open,ToggleEvent,showPopover()/hidePopover()): Baseline newly available since April 2024 (Chrome 114, Safari 17, Firefox 125). - CSS anchor positioning (
position-area,position-try-fallbacks): Chrome 125 and Safari 26; not Baseline at the time of writing. Where it is unsupported the popover keeps the platform's default placement (centered in the top layer).
progress
<progress>and:indeterminateare widely available.appearance: none, which lets the stylesheet draw the track and the value, is Baseline 2022.- The value is styled through pseudo-elements that are not standardized:
::-webkit-progress-barand::-webkit-progress-valuein Chromium and WebKit,::-moz-progress-barin Firefox. Each engine in the support range has one of the two; the value transition is declared on::-webkit-progress-valueonly. - The indeterminate state is a striped background moved by a keyframe animation whose duration comes from the duration tokens. Under
prefers-reduced-motion: reducethose tokens are zero and the stripes stay drawn, so the state still reads as busy. :dir()is Baseline 2023; without it the stripes move toward the right under RTL as well.
radio-group
All features are Baseline widely available.
range-slider
<input type="range">,<output>,appearance: noneand the thumb pseudo-elements (::-webkit-slider-thumb,::-moz-range-thumb): Baseline widely available.:has()for the disabled state: Baseline newly available since December 2023.round()to put the start thumb on top when both meet past the middle: Baseline newly available since May 2024. Where it is unsupported the end thumb stays on top.- The shared router:
Event.composedPath()and ES2022 output: Baseline widely available.
rating
- Radios,
<fieldset>,<legend>, inline SVG withfillandstrokefrom CSS: Baseline widely available. :has(), which fills the checked star and the stars before it (label:has(~ label input:checked)) and draws the hover preview: Baseline 2023 (Chrome 105, Safari 15.4, Firefox 121). Where it is missing no star is filled; the radios keep working.clip-path: inset(50%)of the visually hidden text: Baseline widely available.
scroll-area
overflow: auto,tabindexandrole="region": Baseline widely available.scrollbar-width: thin: Baseline 2024 (Chrome 121, Firefox 64, Safari 18.2), newly available since December 2024. Safari before 18.2 draws its default scrollbar.scrollbar-color: Baseline 2025 (Chrome 121, Firefox 64, Safari 26.2), newly available since December 2025. Safari before 26.2 keeps the system colors.scrollbar-gutter: stable: Baseline 2024 (Chrome 94, Firefox 97, Safari 18.2). With overlay scrollbars (the macOS default, iOS, Android) there is no gutter to reserve and nothing changes.overscroll-behavior-blockand-inline: contain: supported on containers with scrollable overflow since Chrome 63, Firefox 59 and Safari 16. web-features does not list the property as Baseline, because browsers differ on containers without scrollable overflow (Chrome 144 and Firefox 150 changed it; Safari has not).- Scroll-driven animations (
animation-timeline: scroll()), which draw the edge shadows: not Baseline. Chrome 115 and Safari 26 support them, Firefox does not. The stylesheet applies them under@supports (animation-timeline: scroll()); elsewhere the area scrolls without shadows. :dir(), for the right-to-left shadows: Baseline 2023, widely available.
segmented
- Radios,
<fieldset>,<legend>: Baseline widely available. :has(), which marks the checked, focused and disabled segments: Baseline 2023 (Chrome 105, Safari 15.4, Firefox 121). Where it is missing the segments do not show the checked state; the radios keep working.
select
<select>,<option>,<optgroup>,selectedOptions,inputandchangeevents: Baseline widely available. They carry the value and the JavaScript-free path.- Popover API (
popover="manual",showPopover(),hidePopover(),ToggleEvent): Baseline newly available since April 2024 (Chrome 114, Safari 17, Firefox 125). Without it use ahiddenpopup. showPopover({ source }): Chrome 133 and Safari 26; not Baseline, ignored where unsupported.- CSS anchor positioning (
anchor-name,anchor-scope,position-area,anchor-size(), incontrol.css): Chrome 125 (anchor-scope131) and Safari 26; not Baseline. Without it a hidden popup sits under the field and a popover popup is centered in the top layer. :has()(the placeholder, the clear button and the disabled field in the stylesheet): Baseline 2023.@media (scripting): Baseline 2023. Where it is unsupported the native select and the owned trigger both show.- ARIA 1.2 select-only combobox (
combobox,aria-activedescendant,listbox,option,aria-multiselectable): widely supported by assistive technology.
separator
<hr>, role="separator" and aria-orientation: Baseline widely available.
skeleton
aria-hiddenandaria-busyare ARIA 1.1 states, exposed by every current browser.- The shimmer is a band in the background moved by a keyframe animation whose duration comes from the duration tokens. At rest, and under
prefers-reduced-motion: reducewhere those tokens are zero, the band sits outside the box and the placeholder is a flat tint. :dir()is Baseline 2023; without it the shimmer moves from left to right under RTL as well.
slider
<input type="range">,min,max,step: Baseline widely available.- Vertical form controls through
writing-mode: Baseline 2024 (Chrome 124, Firefox 120, Safari 17.4). Where it is missing the vertical slider is drawn horizontally. - The track and thumb pseudo-elements are not standard:
::-webkit-slider-runnable-trackand::-webkit-slider-thumbin Chrome and Safari,::-moz-range-track,::-moz-range-thumband::-moz-range-progressin Firefox. Only Firefox draws the filled part of the track (::-moz-range-progress); Chrome and Safari show the thumb on an unfilled track, because filling it would need script to read the value. accent-color: Chrome 93, Firefox 92, Safari 26.2; not Baseline. Withdata-variant="native"the platform's own slider is drawn in the accent color where it is supported; Chrome and Firefox draw that slider with the track filled up to the thumb.- Tick marks from a
<datalist>named bylist: drawn by Chrome, Firefox 109 and Safari 12.1 on their own slider only. The styled track replaces that drawing (Chrome then draws no tick marks), so tick marks needdata-variant="native".
spinner
role="status"is an ARIA 1.1 live region role, exposed by every current browser; when and how it is spoken differs between screen readers.- The ring turns with a keyframe animation of the
rotateproperty, Baseline 2022; without it the ring stands still. The duration comes from the duration tokens: underprefers-reduced-motion: reducethey are zero and the ring is drawn, still, while the role and the label are unchanged. - The track is a
color-mix()tint ofcurrentColor, Baseline 2023; without it the track is--slean-border-strong.
splitter
- Pointer events and pointer capture (
setPointerCapture,lostpointercapture): Baseline widely available. - CSS grid with
calc()on a custom property: Baseline widely available. touch-action: noneon the handle, so a touch drag resizes instead of scrolling: Baseline widely available.
steps
aria-current="step"(ARIA 1.1) and CSS counters are widely available.:has()draws the complete state and is Baseline 2023. Without it a complete step looks like an upcoming one; its text is still read.- The number uses alternative text for generated content (
content: counter(…) / ""), Baseline 2024. A browser without it keeps the plain counter declared before it, and a screen reader may read the number with the step. - The check is two gradients in the indicator turned with the
rotateproperty, Baseline 2022.
switch
role="switch" on a checkbox is defined by ARIA 1.2 and mapped by current screen readers. Nothing beyond the checkbox platform features is required.
tabs
- ARIA tabs roles and states (
tablist,tab,tabpanel,aria-selected,aria-controls,aria-labelledby): ARIA 1.2, widely supported by assistive technology. - The shared router:
Event.composedPath(),getAttributeand ES2022 output (the packages' TypeScript target): Baseline widely available. No transpilation to an older target is provided; a consumer that needs one runs the packages through its own bundler. :dir(rtl), used only to resolvedir="auto": Baseline newly available since December 2023 (Chrome 120, Safari 16.4, Firefox 49). The call is guarded inpackages/primitives/src/internal/direction.ts: where the pseudo-class is unsupported,dir="auto"resolves to left-to-right and explicitdirattributes work everywhere.
tag
<button>: Baseline widely available.:has(): Baseline 2023 (Chrome 105, Safari 15.4, Firefox 121), widely available since June 2026. The styles use it only to tighten the padding beside a remove button.
timeline
<ol>,<li>,<time datetime>and generated content: Baseline widely available.:has()draws the pending state: Baseline 2023 (Chrome 105, Safari 15.4, Firefox 121), widely available. Without it a pending event looks like a past one; its text is still read.
toast
- Popover API (
popover="manual",showPopover(),hidePopover(),:popover-open): Baseline newly available since April 2024 (Chrome 114, Safari 17, Firefox 125). Where it is unsupported the region renders in place and toasts are still added and announced. - ARIA live regions (
aria-live="polite"): widely supported by assistive technology. The region is shown one frame before the first toast is added, so the live list exists before its content changes.
toggle
<button>with Enter and Space activation: Baseline widely available.aria-pressed(the ARIA 1.2 toggle button): announced as a toggle button with its state by screen readers on every desktop and mobile platform.- The shared router:
Event.composedPath()and ES2022 output: Baseline widely available.
toggle-group
<button>with Enter and Space activation: Baseline widely available.aria-pressed(the ARIA 1.2 toggle button) androle="group": announced by screen readers on every desktop and mobile platform.- The shared router:
Event.composedPath()and ES2022 output: Baseline widely available. :dir(rtl), used only to resolvedir="auto": Baseline newly available since December 2023 (Chrome 120, Safari 16.4, Firefox 49). Where it is unsupported,dir="auto"resolves to left-to-right; explicitdirattributes work everywhere.
toolbar
role="toolbar"andaria-orientation: ARIA 1.2, announced by screen readers on every desktop and mobile platform.focusin: Baseline widely available.- The shared router:
Event.composedPath()and ES2022 output: Baseline widely available. :dir(rtl), used only to resolvedir="auto": Baseline newly available since December 2023 (Chrome 120, Safari 16.4, Firefox 49). Where it is unsupported,dir="auto"resolves to left-to-right; explicitdirattributes work everywhere.
tooltip
- Popover API (
popover,showPopover(),hidePopover()): Baseline newly available since April 2024 (Chrome 114, Safari 17, Firefox 125). popover="hint": Chrome 133; not Baseline at the time of writing. Where the value is unknown the attribute falls back to its manual state, and the behavior hides the content itself.showPopover({ source })for the implicit anchor: Chrome 133 and Safari 26; not Baseline. The styles also set ananchor-nameon the trigger, scoped to the root withanchor-scope.- CSS anchor positioning (
position-area): Chrome 125 and Safari 26; not Baseline at the time of writing. Where it is unsupported the content keeps the platform's default placement. - Pointer events (
pointerover,pointerout,pointerType): Baseline widely available. Touch pointers are ignored; a long press does not show a tooltip.
tree
- ARIA tree roles and states (
tree,treeitem,group,aria-expanded,aria-selected): ARIA 1.2, widely supported by assistive technology. :dir(rtl)for the chevron and fordir="auto": Baseline newly available since December 2023 (Chrome 120, Safari 16.4, Firefox 49).- The shared router:
Event.composedPath(),getAttributeand ES2022 output: Baseline widely available.