Important
This is a work in progress and still very rough around the edges, but any feedback is welcome!
TL;DR: role and aria-* as CSS properties, with tree-scoped element references.
Two tiers: first, make the CSS-driven interaction authors already build describable to AT; second, encourage more of it by also letting CSS control focusability.
- Problem statement & user needs
- Proposal
- Processing model
- Guardrails
- Alternatives considered
- Prior art
- Anticipated objections
An increasing number of common interaction patterns can be implemented via HTML and CSS alone, but making them accessible requires manual HTML boilerplate (tedious and error-prone), or flimsy JS to keep UI state in sync with ARIA attributes.
Additionally, for CSS pseudo-elements such as ::picker(), ::details-content, ::part(), ::slotted() etc., there is no way to convey their accessibility semantics to the accessibility tree.
As a result, accessibility is often skipped, buggy, pushed to "later", or deemed out of scope altogether.
Authors are often discouraged from simpler, faster to load HTML & CSS patterns on the basis of accessibility concerns, and steered into heavy markup and JS solutions as the solution. A CSS framework that shelved its tabs component for exactly this reason put it plainly:
CSS can select and present a state, but it cannot manage focus or update the corresponding ARIA attributes. Therefore, correct ARIA tabs currently require script.
Take the simplest such widget: a checkbox styled as a toggle button.
Space toggles it, :checked styles it, no script.
But AT hears a checkbox, and making it hear a toggle button means a script that copies checked into aria-pressed on load and on every change, for every instance, forever.
With this proposal, the same fact is stated once, next to the rule that already styles it:
.toggle {
role: button;
aria-pressed: false;
}
.toggle:checked {
aria-pressed: true;
}What if instead of discouraging authors from doing what feels natural (always an uphill battle), we paved the cowpaths, and made the CSS patterns actually accessible?
The benefits are quite significant, for both developers and end-users:
- Lower friction to make experiences accessible directly translates to more accessible experiences.
- Semantics move up a level of abstraction. Today the only unit that can carry ARIA once for all its uses is a JS component; a class, a CSS framework or the UA stylesheet cannot. In CSS, whoever defines a pattern specifies it once, and consumers get it automatically (e.g. by using the class).
- Co-location resists drift. The dominant scripted-ARIA failure is state desync; deriving semantics from the same selector that drives presentation makes them a single expression.
- Fault tolerance. Scripted ARIA fails whole: In JS any uncaught error breaks the entire file. CSS is fault-tolerant by design. An incorrect declaration is dropped without affecting the rest of the sheet.
- Fewer wrappers. Built-in elements are often wrapped in components precisely to encapsulate accessibility logic, which today requires JS. Handling accessibility semantics in CSS lets many of these wrappers become a CSS class on a built-in element, and the decrease in complexity compounds downstream.
The full list falls into five buckets:
- Manual ARIA boilerplate: facts CSS already knows, added by hand on every instance:
aria-hidden="true"on every decorative icon,aria-current="page"on the current nav link, a unique id on every dialog heading soaria-labelledbycan point at it, etc. - JS that exists only to sync CSS state into ARIA:
aria-invalidfrom:user-invalid,aria-currentfrom:target-current,aria-pressedoraria-selectedfrom:checked(toggle buttons, tabs,<select>listboxes restyled as checkbox groups), etc. - Pseudo-elements that cannot carry ARIA at all:
::picker()laid out as a grid,::details-contentas a labelled region,::slotted()/::part()for semantics across a shadow boundary, from either side, etc. - Markup the author cannot edit: Markdown output, third-party widgets, components that did not forward labels, etc.
- Built-in browser magic, made visible: implicit roles,
::tooltip's role, thearia-hiddencorrections browsers apply silently, all as UA stylesheet rules that can be inspected.
CSS is the only web platform language built around reactive invariants: authors write rules declaring what applies to which (pseudo-)elements under which conditions, and the UA combines whatever matches and takes care of the hard bits: invalidation and state sync. There are no initialization steps, listeners, or side effect cleanup. This matters because invalidation is hard, and its difficulty grows with the number of conditions. Intent as simple as "apply X to buttons, except when hovered or focused" takes two lines of CSS, but ~50 lines of (much buggier) JS. Add media queries to the mix, and the complexity of keeping everything in sync grows even further.
Specifying logic via invariants is not a good fit for everything; some things are inherently one-shot.
But accessible semantics are exactly this kind of invariant, and the few one-shot cases are already JS APIs (e.g. ariaNotify()).
The use cases demonstrate this very clearly.
Additionally:
- Pseudo-elements have no HTML counterpart, and often nesting (e.g. a
<div>wrapping the contents of::picker()or::details-content) produces incorrect accessibility semantics. - CSS is often applied to markup that cannot be modified directly, such as third-party Web UI, components, CMS-generated content, content rendered from Markdown, etc. This means ARIA via CSS could even be used to fix broken accessibility semantics in otherwise uneditable content.
ARIA relationships are IDREFs, and IDREFs do not cross shadow boundaries, in either direction. Both sides of a component are stuck today, for different reasons.
Inside the component. ElementInternals lets a component put a role and ARIA state on its own host, and nothing else.
The light-DOM children a consumer slots in are off limits, short of writing attributes into markup the consumer owns.
It is also imperative, so every code path that changes state must remember to update it, and it does not compose: a checked attribute, a custom state and a consumer override each need their own plumbing into the mixin.
Outside the component. Every existing path across the boundary (form-associated custom elements, element reflection, Reference Target) requires the component's cooperation. A consumer cannot fix a component that did not describe its parts, even when a selector can reach both ends of the relation.
Selectors already cross the boundary in both directions (::slotted(), ::part(), :host), so a stylesheet is the one place where both sides can be described.
See Cross-root references for how.
- CSS properties mirroring ARIA attributes that feed only the accessibility tree computation, never reflected to the DOM.
- Properties named after the attribute (
role, notaria-role), but value space designed to fit CSS syntax and semantics. - Relationship properties take ids (for compatibility) but also tree-scoped
<dashed-ident>references (theanchor-namemodel), also mitigating the IDREF DX problem without attempting to solve it completely. - The initial value is
auto, which defers to the corresponding ARIA attribute, or to implicit semantics if the attribute is not present. - An explicit absence value makes the state/property absent even if the attribute is present. Issue:
noneis the natural CSS spelling, but is also a valid value ofrole,aria-sortandaria-autocomplete. See ARIA properties. - Attributes are assumed to behave like presentational hints: beaten by any author declaration, winning over the UA stylesheet. See Precedence.
- ARIA/host-language conflict resolution, unknown-token fallback, and ARIA-in-HTML constraints all apply at used-value time. CSS changes where values come from, not which combinations are conformant, with one deliberate exception (see Guardrails).
The proposal comes in two tiers. Tier 1 describes interaction CSS can already build, so that widgets which work for keyboard users today stop misreporting to AT users. Tier 2 extends CSS's control over focusability, so that more such widgets can be built in the first place. Tier 1 stands on its own; Tier 2 is sketched here because the two should be evaluated together (see Tier 2).
This is the general form of the pseudo-element-only aria-* properties proposed in CSSWG in September 2026, which it contains as a subset.
Later:
- CQ/
if()condition to match on computedrole(since:role()cannot match these)
All properties: initial auto, not inherited, not animatable, excluded from all, apply to elements and pseudo-elements.
role: auto | none | <ident>+- Token states/properties, each mirroring its attribute's grammar as
auto | none | <tokens>:aria-expanded,aria-pressed,aria-checked,aria-selected,aria-current,aria-hidden,aria-disabled,aria-invalid,aria-busy,aria-sort,aria-orientation,aria-haspopup,aria-modal,aria-readonly,aria-required,aria-multiselectable,aria-live,aria-atomic. - Numeric/string:
aria-level,aria-posinset,aria-setsize,aria-value{min,max,now,text},aria-label,aria-description,aria-roledescription,aria-keyshortcuts,aria-placeholder. - Relationships:
aria-labelledby,aria-describedby,aria-details,aria-controls,aria-errormessage,aria-flowtotake<dashed-ident>+;aria-activedescendanttakes one. (aria-ownsdeferred: interacts withreading-flowfocus scopes.)
Open question, the absence keyword: none above means "no value, even if the attribute has one", but role="none" (a synonym of presentation), aria-sort="none" and aria-autocomplete="none" are valid attribute values, so role: none is ambiguous.
Options: a distinct keyword for absence (e.g. omit), or keep none as absence and require the presentation spelling for the role, since the other colliding values are equivalent to absence anyway.
IDREF attributes (e.g. aria-labelledby) take two types of references:
<string>which corresponds to an ID ref, just like an attribute would<dashed-ident>which are tree-scoped references modeled onanchor-name/anchor-scope.
Strawman:
ref-name: auto | none | <dashed-ident>#
ref-scope: auto | none | all | <dashed-ident>#
Multi-valued properties resolve each ident to all in-scope elements exposing it, in tree order; singular ones to the last in tree order (anchor precedent).
.card {
ref-scope: --title;
role: group;
aria-labelledby: --title;
}
.card > h3 {
ref-name: --title;
}Every instance labels itself by its own heading; no IDs, no uniqueness discipline.
Open questions:
- Bare
<dashed-ident>vs aref()function resolving to a new<element>type that all IDREF properties take; the Typed OM could then resolve it to actual element references. Relationships whose scope does not follow the tree could useident()to generate refs. Either way,iditself should not become CSS-settable (security). ref-*vs unifying withanchor-name/anchor-scope- name visibility across shadow boundaries.
The cross-root problem has two sides, and the same properties serve both.
Inside the component, the component stylesheet declares semantics once, for the host and for slotted content alike:
:host {
role: tablist;
}
::slotted([slot="tab"]) {
role: tab;
}
::slotted([slot="tab"][selected]) {
aria-selected: true;
}Outside the component, where a selector reaches both ends of the relation, a consumer can fix a component that did not:
label:has(> fancy-input) {
ref-name: --label;
ref-scope: --label;
}
label > fancy-input::part(input) {
aria-labelledby: --label;
}Note that ::part() is an opt-in to styling, not to semantics; whether exposing a part should also expose its semantics to the consumer is an open question.
Relation to Reference Target. Reference Target lets a shadow host nominate an element inside its shadow root as the target of any IDREF pointing at the host, so <label for>, aria-labelledby, popovertarget and the rest work across the boundary with no change on the referencing side.
That fixes the reference primitive itself, for every IDREF in HTML, and this proposal builds on it rather than duplicating it: <string> references in ARIA properties resolve exactly as the attribute would, retargeting included.
The two address different gaps.
Reference Target is declared by the component, so it is the right fix wherever the component author is in the loop, and nothing here touches non-ARIA references at all.
ARIA properties cover what remains: components that never adopted it, slotted content the component must describe but does not own, and relations that exist only in some states.
Tier 1 makes CSS widgets that are already operable describable to AT. Tier 2 is about operability itself: if we want to encourage accessible CSS widgets (for all the performance and robustness benefits above), CSS also needs to control focusability. Candidates:
- A property to make elements focusable, such as
interactivity: focusable(#13040, liketabindex="0"with more specific keywords for the type of focusability), or atab-index: 0 | -1property mirroring the HTML concept (suboptimal design, but compatible). - A
focusgroupproperty, for the same reason.
This document only sketches Tier 2, and nothing in Tier 1 depends on it. But the two should be evaluated as one program. When focusability was previously proposed on its own, pushback centered on focusability not being enough for accessible interactions, and that is correct: focusable ≠ accessible. Tier 1 is the missing half of that contract, and its operability guardrail enforces the converse. With both, the half-done state is not expressible.
Do these properties override the corresponding ARIA attributes for the purpose of accessibility tree computation? There are two conflicting precedents:
- Like SVG geometry properties, HTML presentational attributes and
dir, the CSS properties would override the corresponding ARIA attribute values. - Like inline styles, the CSS properties would have lower precedence than the corresponding attributes.
This document assumes 1: the attribute behaves like a presentational hint, exactly as dir does for direction. It beats the UA stylesheet and loses to any author declaration, and auto (the initial value) defers to it.
This is what the use cases need:
- UA-stylesheet defaults such as
::tooltip { role: tooltip }orh1 { role: heading }stay overridable by markup. - Author CSS can repair markup it cannot edit.
- The absence value works without
!important. - A UA
!importantrule (e.g.html, body { aria-hidden: false !important }) can still shut down known abuse.
The argument for 2 is locality: the attribute sits on the element, like style does.
But under 2, repair of uneditable markup, framework-level defaults and the absence value all require !important, which turns the escape hatch into the common path.
Either way, selectors keep matching the markup attribute, so no cycles.
Note: A propdef column stating whether a corresponding attribute exists and whether the property defaults or overrides it could make SVG geometry and presentational attributes first-class platform concepts rather than legacy warts.
- Write-only, downstream. Inputs to the a11y tree computation only. No DOM reflection: attributes are unchanged,
el.role/el.ariaExpandedkeep reflecting attributes, MutationObservers see nothing;Element.computedRoleand AT see the result. - No circularity by construction. Selectors match source semantics only; nothing matches this computation's output. Requires retracting the unimplemented
:role()resolution (#3596, minuted as the price of the opposite choice: "we can't do both"). The identical trade was made in #13040 re:focusable(#7269), and it is how:dir()already relates todirection. - Updates propagate like attribute mutation; AT already handles dynamic semantics.
- Widget roles require operability.
button,tab,checkbox, etc. don't take effect on elements that are neither focusable by some mechanism (native,tabindex,interactivity: focusable) nor managed by a focusable composite (tablist,listboxwitharia-activedescendant, afocusgroup). No announcing controls nobody can operate. Structural/landmark roles are exempt. This is the one place where the CSS property is deliberately stricter than the attribute: the attribute predates any way to enforce it, and the property's purpose is to make the accessible version the one-declaration version, not to make the broken one cheaper. - Existing ARIA validity machinery applies unchanged, at used-value time.
- Implementations should surface rule provenance for CSS-originated semantics in a11y inspectors.
CAS (Cascading Attribute Sheets) were first proposed by Tab Atkins in 2012 as a way to extend the cascading nature of CSS to HTML attributes. Brian Kardell also wrote a polyfill in 2013. See also: Dave Rupert: A Use Case for CAS (2022)
The proposal was updated in 2025 to a pared down version, which removes reactivity and makes the syntax essentially a syntax abstraction over the equivalent JS. However, restricted invalidation kills the reactivity that is the point for these use cases.
Additionally, a new platform language, with a new MIME type, new inclusion mechanisms, etc., is a lift no individual use case can justify, which makes shipping unlikely.
Piggybacking on CSS is less pure, but purity ranks last, and it allows incremental expansion (start from the pressing use cases, not every attribute; most CAS problems like security-sensitive attributes and collisions vanish once we stop importing wholesale), lets each property grow CSS-native syntax beyond its attribute grammar, and inherits all existing and future CSS machinery: CSSOM, Typed OM, inline styles, animations, transitions, @supports, media queries, etc.
The ARIA mixin on ElementInternals is the platform's designated path for component semantics, and it is imperative, host-only and component-only.
It cannot describe slotted content, cannot be used by a consumer, cannot follow a CSS condition, and every state change must remember to update it.
The custom element use cases show the resulting double write at scale.
Extending it would not reach the other four use-case buckets.
Reference Target fixes IDREFs across the shadow boundary for every attribute, and this proposal builds on it. But it must be declared by the component, so it cannot help a consumer repair a component that did not adopt it, cannot describe slotted content, and does not express relations that exist only in some states. See Relation to Reference Target.
#14534 restricts the same properties to pseudo-elements, on the grounds that the layering and AT-interaction objections to the general version do not apply there.
It is a strict subset of this proposal, with the same processing model and the same cascade cost.
Stopping there leaves the four other use-case buckets unaddressed, and leaves the cross-root cases half-solved: ::slotted() and ::part() select real elements, so a pseudo-element-only rule already sets ARIA on elements, just not on the ones the author owns.
:target-current now maps to aria-current by ARIA WG resolution, and CSS-AAM is the home for such mappings.
Each one is a WG resolution and an implementation per feature, covering only the pattern the UA anticipated.
This proposal is the general form: the same processing model, with authors able to declare the mapping for their own patterns.
The two are complementary, and UA-level mappings can be expressed as UA stylesheet rules in these properties.
Platform precedent for CSS properties mirroring markup attributes:
dir/directionis the closest precedent on every axis.diris semantic (bidi), not visual. HTML maps it through UA stylesheet rules ([dir]:dir(rtl) { direction: rtl }), so any author declaration wins, which is the precedence model assumed here. And:dir()matches the markup-derived directionality, never the computeddirection, which is the no-circularity split this proposal makes.- SVG geometry attributes: presentation attributes, beaten by any author declaration.
- HTML presentational attributes, now defined as presentational hints: author-origin declarations of zero specificity.
aria-*properties for pseudo-elements only (Tab Atkins, September 2026): properties matching everyaria-*attribute's name and value space, restricted to pseudo-elements. Notes that the general version has been "discussed a few times" and rejected over layering and AT interaction, and argues those objections do not apply to pseudo-elements. Brought to the ARIA WG as aria#2921 for TPAC 2026.:target-currentimpliesaria-current: the ARIA WG resolved in January 2026 that the active scroll marker maps toaria-current="true"in the platform tree, with no attribute injection, and an author-setaria-currentwinning. A per-feature instance of this proposal's processing model: computed semantics, no DOM reflection, markup wins over the UA mapping.- CSS-AAM, newly created, is the home for "this CSS state maps to this platform semantics";
:target-currentis its first entry, and the resolutions this proposal needs would live there. aria-busyby default during view transitions (#8447, closed) and a pseudo-class for a range input's current value (#6354): smaller requests for the a11y tree to follow CSS state.
CSS already affects the a11y tree, often destructively and by accident:
display: contents(#3040)list-style: nonein WebKit (stripslist/listitemroles from unstyled<ul>/<ol>, WebKit bug 170179, write-up).
CSS already controls focusability, as a side effect of other features:
overflow: auto/scrollmakes a scroll container focusable, and only while there is something to scroll (demo).image-animation: controlledmakes an image focusable so its UA play/pause control can be operated, and only when the image is actually animated; the explainer adds that "screen readers should announce the element distinctly".
CSS already creates interaction that is not keyboard accessible, which is the real footgun (collected in #13040):
resizeadds interactive UI that manipulates CSS properties, with no keyboard path.:hovermakes interactive UI trivial to build and impossible to make keyboard accessible without HTML changes or JS. Authors should not have to choose between DX and accessibility.img:hover, img:focus { image-animation: running }is the spec's own example, and the spec concedes that "it is not possible to directly make an element focusable in CSS, proper keyboard navigation will require element attributes to be set as well."- Content that is interactive only under some conditions (a breakpoint, an overflow) has no attribute that can follow the condition.
Similarly, HTML creates inaccessible tooltips via the title attribute, that authors are actively encouraged to avoid, in favor of much more markup-heavy interest invokers.
Where deliberate:
reading-flow/reading-order(exposure order, with ARIA WG review in aria#2241),content: url() / "alt",::scroll-marker/::scroll-button()and theimage-animation: controlledcontrol: CSS-generated interactive UI with UA-assigned semantics,interactivity(shipped, though over sustained a11y objections in #10711, cited as fact, not endorsement), andinteractivity: focusable(#13040). That proposal already anticipated this one: making generated content focusable "would obliterate a lot of specialized pseudo-elements being proposed (especially if down the line we can control ARIA roles too)", and it named the false-sense-of-security risk of focusability without semantics, concluding that "the way to solve this is to provide control over those as well, not to make it harder to make a UI keyboard accessible." It also floated expressing a UA default as a UA stylesheet rule ([tabindex=0] { interactivity: focusable !important }), the same move this proposal makes for::tooltip { role: tooltip }. The objection on #13040, that focusability alone amplifies the "focusable = accessible" author mistake, is an argument for completing the contract; this proposal is that completion, and the two should be evaluated as one program.
Many of these were raised against interactivity: inert (#10711, shipped in Chrome 135) and interactivity: focusable (#13040, its 2018 precursor #3379, the APA WG review, and a threat model post), and transfer to any CSS that touches the accessibility tree.
Objections specific to focusability or inertness (focusable ≠ accessible, focus order, un-inerting, set size with inert items) belong to Tier 2 and are omitted here.
- Wrong layer: CSS is for styling (#10711 (comment), #10711 (comment), #13040 (comment), #13040 (comment)). Semantics, inertness and focusability are content and behavior, not presentation, and CSS's association with presentation makes semantics-blind use more likely. A response on #10711 rejects the "CSS already affects the a11y tree" argument:
display: noneaffects it because it changes presentation; the a11y tree mirrors the visible experience, and a property that changes semantics without changing visuals is a different category. Also raised: CSS may be easier at authoring time but is more fragile and harder to debug. CSS has not been only about styling for a very long time: SVG geometry properties, aural properties,user-select,touch-action,interactivity,resize,pointer-events,scroll-behavior/overscroll-behavior,content/quotes,direction/unicode-bidi,reading-flow/reading-order, Opera's oldnav-*. That ship has sailed, andreading-flowis the direct counterexample to that line: it changes exposure order without changing a pixel, and went through ARIA WG review (aria#2241). The actual user need was never "separation of concerns"; it is local (one-off) vs global (rule-based): O(1) author effort, a single source of truth, and no side effects or invalidation to manage. That is exactly why reactive frameworks are popular, and CSS is the platform's only fully reactive language. Theoretical purity sits at the bottom of the priority of constituencies; this has very clear benefits for both end users and developers, who sit at the top.
- Fix HTML instead.
focusgroup, invoker commands, Reference Target and<input switch>are closing the same gaps declaratively, in the layer that owns semantics. They are complementary, and this proposal depends on them for behavior. What HTML cannot do is follow a condition: a breakpoint, an overflow, a:checked, a:popover-open. Every synced attribute in the use cases is HTML that was already declared correctly for one state and is wrong in the other. HTML also has no way to reach pseudo-elements at all.
- No visual impact, so misuse is invisible (#10711 (comment), #10711 (comment), #10711 (comment), the APA WG review). Authors assume content stays as perceivable to everyone as it is to them; rules setting the property drift out of sync with the rules that change appearance; copy-pasted CSS leaves subtrees inert unnoticed.
user-select: noneandpointer-events: noneshow how such properties get abused. Non-interactive ≠ non-critical.inertdoes affect non-AT users, so that objection was overstated even forinteractivity. More to the point, applying ARIA via HTML or JS has exactly the same property: ARIA attributes have no visual impact either, and that is the baseline being compared against. The "CSS applies it in aggregate" worry does not hold: a JS loop also applies it in aggregate, with less visibility. At least CSS keeps the semantics next to the styling they describe, and the Guardrails ask inspectors to surface rule provenance, which makes a CSS-originated role more traceable than asetAttributeburied in a handler. - "The
aria-hiddenof CSS" (#10711 (comment)). Browsers had to whittlearia-hiddendown (ignored onhtml/body, undone when focus enters) because of pervasive misuse. No mitigation for author error was designed here, and once shipped it cannot be scoped down without "breaking the web". These properties are inputs to the same computation, so every mitigation that exists or is later added to the attribute applies to the property unchanged. And the syntax lends itself to a very simple, very visible mitigation in the UA stylesheet:html, body { aria-hidden: false !important }
- No guardrails; nothing encourages correct use (#10711 (comment), #10711 (comment), the threat model post). HTML
inertgot normative guidance on inappropriate use after the same concerns; a note in a CSS spec will be ignored. Authors learn by trial and error, and their trials don't include AT or keyboard testing. Consider careless authors and AI-generated code, not just well-intentioned ones. True of ARIA attributes and a11y-touching JS today too. But under neglect, the easiest version is what ships, and today the accessible version of CSS-driven UI costs a JS subsystem while the inaccessible one costs nothing. This feature's purpose is making the accessible version the one-declaration version. The Guardrails section is the correct-use encouragement whose absence was the core complaint aboutinteractivity, and unlike a spec note, the operability guardrail is enforced by the UA. - Cascade/third-party CSS deciding what things are. Third-party CSS can already destroy semantics wholesale (
display: none/contents,interactivity: inert); it just can't repair anything. Auditing moves to the computed tree, which is what AT users actually get, and what inspectors and axe-style runners already evaluate. - Semantics churn. State driven by
:hover,:focus-withinor a scroll-state query flips as often as the condition does, so AT users get a stream of announcements, andaria-livefrom a stylesheet could create announcement storms. A JS mirror of the same condition produces the same stream; the churn is a property of the condition, not of the language expressing it. The properties are not animatable and do not transition, so there is no CSS-specific amplification. Which conditions make sense as sources of which states is exactly the guidance CSS-AAM exists to give, and it can give it once rather than per framework.
- Everything that reasons about ARIA reads the DOM. Validators (ARIA in HTML conformance), linters, axe-style runners in CI, and
getByRolein Testing Library and Playwright compute roles from attributes, so CSS-set semantics are invisible to them, or worse, flagged as missing. Already true forElementInternalsroles, UA mappings like:target-current, and every implicit role of a pseudo-element, which is whyElement.computedRole/computedLabel, the DevTools accessibility protocol and Playwright's a11y snapshots exist. The computed tree is the right source of truth because it is what AT users get. This is a real migration cost for the testing ecosystem, and the provenance guardrail is what makes it tractable: a CSS-originated role must be attributable to a rule. - Strings in stylesheets resist localization (
aria-label: "Close"). Translation pipelines process markup and message catalogs, not CSS. The same holds forcontent: "…"andcontent: … / "alt", which the WG accepted with the same caveat. Most of the property set is tokens and relationships, not strings; the string cases in the use cases come fromattr(), counters, oraria-labelledby, which keep the text in markup. Guidance: preferattr()and relationships over literal strings. - Which rule won? Specificity,
!importantand origin make the resulting role harder to reason about than an attribute on the element. This is the same question as for any property, and inspectors already answer it: the winning rule, its source, and the overridden ones. The Guardrails ask for the same view in the accessibility pane. An attribute set by one of several JS code paths has no equivalent.
- Semantics without behavior. This objection only bites for widget roles; most of the property set is pure state, where no behavioral contract exists to be missing:
aria-currentfrom:target/scroll-state(snapped)(scrollspy, active carousel slide — CSS is the only layer that knows),aria-expandedmirroring:popover-open/[open]/:checked/:focus-within,aria-orientationwhenflex-directionflips at a breakpoint (orientation's source of truth is the stylesheet),aria-hiddenon off-canvas or clamped content,aria-busyon skeletons. Where roles are involved, the dominant cases relabel fully working native behavior within ARIA in HTML's existing allowances: checkbox-backed toggles already toggle on Space (role: button; aria-pressedorrole: switchfrom:checked— allowed on checkbox inputs since html-aria#6, though Chrome maps native checkedness ontoswitch, whose state is stillaria-checked, and not ontobutton'saria-pressed, which is precisely the gap these properties fill), popovers already dismiss and manage focus (role: tooltip;aria-haspopupon the invoker). Radio-hack tabs have arrow-key traversal natively buttabis not currently an allowed role on radio inputs — a relabel this proposal makes worth permitting via a companion ARIA-in-HTML change, the same loosening path checkbox→button/switchtook. These widgets work for keyboard users today and misreport to AT users — the interaction contract is complete, the description is wrong. The residue (role: buttonon a deaddiv) is what the operability guardrail refuses, and invoker commands supply declarative behavior to compose with. - Conditional semantics. When the UI is conditional on MQs, semantics that can't follow are wrong, not stable; the failure exists today with reversed polarity.
auto+ markup remain for anything that shouldn't vary. - Non-CSS consumers / failed loads.
autokeeps markup semantics as the baseline, so a missing stylesheet degrades to today's behavior, where a missing or broken script leaves every synced attribute stale. Before stylesheets load, the tree is the markup's, exactly as before a script runs; and since the a11y tree already depends on style resolution fordisplay,visibilityandcontent, there is no new moment at which it could be computed without CSS. Consumers that discard CSS already discardreading-flowand every layout-dependent aspect of meaning. - Which pseudo-elements need author ARIA at all? (#14534 (comment)). Interactive pseudo-elements like the interest invoker touch button would not benefit from customization, so interactivity alone does not imply a need for custom ARIA in CSS.
Agreed that it does not imply it; the use cases show where the need is concrete:
::picker()as a grid,::details-contentas a labelled region,::tooltipcarrying its role, and the carousel pseudo-elements' labels. And the element half of this proposal does not depend on the pseudo-element half. - Exclude roles; specify each pseudo-element's semantics in its own module (#14534 (comment)). Most pseudo-elements should be
none, the few meaningful roles belong in the CSS module that defines the pseudo-element, not in author stylesheets. Both, not either: per-module UA defaults are exactly what a UA stylesheet rule like::tooltip { role: tooltip }expresses, and an author override through the same property is what the::picker()case needs. Author-overridable UA defaults are how every other property works. - Many of these attributes only apply to certain elements. So do the SVG geometry properties,
object-fit/object-position,appearance,field-sizingandframe-sizing, and nothing broke. None of these inherit. - Performance. Every style recalc can now dirty the accessibility tree, and the tree depends on full style resolution for every element.
It already does:
display,visibility,content,reading-flowandinteractivityare all style inputs to the tree, and engines already recompute it on style change. The new properties are not inherited and are excluded fromall, so a change invalidates one node, not a subtree.