demo · v135

ARIA across shadow boundaries

The web components use case the AOM explainer was designed for: a custom element's internal input needs to be labelled by a paragraph in the light DOM. IDs don't cross shadow boundaries, so the old aria-labelledby="some-id" pattern was broken by design. Element reflection lets the component pass a real element reference through — shadow walls become transparent for accessibility wiring.

aria*Elements: ?

light DOM (your page)

"Enter your full legal name as it appears on your passport."

"Required for ticket issuance — cannot be changed later."

inside the shadow root


      

  

the code

customElements.define("my-text-field", class extends HTMLElement {
  connectedCallback() {
    this.attachShadow({ mode: "open", delegatesFocus: true })
      .innerHTML = `<label>Passenger<br><input></label>`;
    this._input = this.shadowRoot.querySelector("input");
  }
  set labelledBy(elements)  { this._input.ariaLabelledByElements  = elements; }
  set describedBy(elements) { this._input.ariaDescribedByElements = elements; }
});

// In page code — pass references across the shadow boundary.
field.labelledBy  = [helpOne];
field.describedBy = [helpOne, helpTwo];

see also