The component reference has capability tables now: for buttons, tabs, tables, cards, dialogs and navigation, what each one does sits beside what it deliberately does not, with the reason. It is an odd thing to publish. It is also the first thing I want to read before adopting somebody else's component.
The second column is the useful one. A card with a stretched link cannot hold a second clickable link — the stretched link covers it. Tabs cannot deep-link, because a radio input has no URL. Navigation does one level, because nested hover menus are unusable on touch. And dialogs are the single component that genuinely requires JavaScript, which the table says outright rather than leaving you to discover when one fails to open.
This release also added a live markup sandbox. It was removed in rc.5; the post on that release explains why.
Why the second column is the one that matters
Capability tables are unusual in framework documentation, and the reason they are unusual is that they are unflattering. A feature list is an argument for adoption; a limits list is an argument against it, written by the people who want you to adopt. We publish it anyway, because the alternative is that you discover the limit at the point where it costs most: after the component is in your page, styled, reviewed and shipped.
Every entry in that column is a constraint with a cause, not a missing feature waiting for a release. A stretched link covers its card, so a second link inside the card is unreachable — that is what "stretched" means, not an oversight. Radio-driven tabs have no URL because a radio input is not an address, so deep-linking to a tab needs a different mechanism, not a patch. These are the shape of the technique, and naming them is cheaper for everyone than an issue thread six months from now.
Update: one of those limits has since gone
The table said dialogs were the single component that genuinely required JavaScript. That is no longer true, and it is worth saying why it changed rather than quietly editing the row.
It required a script because opening a modal meant calling showModal(); there was
no markup that could do it. The platform closed that gap: invoker commands let a button open a
dialog declaratively, closedby handles dismissal, and the popover API covers menus.
A dialog now opens from HTML alone, and the optional script has shrunk to the one thing markup
still cannot express — turning radio tabs into a full ARIA tablist.
That rewrite had its own lesson. Our first attempt put role="tablist" on the tabs
container, whose children are radios and panels, which ARIA forbids; the second inserted a
<div> to hold the role and silently renumbered every
div:nth-of-type() in the panel rules, so the wrong panel showed. The working version
is an empty <span> that claims the labels with aria-owns. A
capability table is only honest if the capabilities are retested when the platform moves.
What this post does not cover
- Components the framework does not ship at all, such as a carousel.
- The full ARIA authoring practices — the capability tables point at them rather than restating them.
Checked against popover API, invoker commands, ARIA forbids. Figures are measured from the build they describe.
What this doesn’t cover
A capability table is only as honest as its last review. This one described the platform as it stood at the time, and one of its limits has since gone. It says nothing about performance, nothing about what these components cost to render, and nothing about whether a screen reader finds them comprehensible — only whether the ARIA is correct.
Sources: MDN on the Popover API and the ARIA Authoring Practices tabs pattern. The capability table is reproduced from the component reference on this site.