Skip to content

Reference Target #10707

Open
Open
@dandclark

Description

@dandclark

What problem are you trying to solve?

Element-to-element relationships that are specified based on element IDs, like many of the aria- attributes, run into problems when they need to be created between elements on the opposite sides of a shadow DOM boundary.

The ARIAMixin IDL attributes (such as ariaLabelledbyElements and ariaActiveDescendantElement) solve this problem in one direction, allowing references to be created from inside a shadow DOM to an element outside the shadow DOM (unless the target element is in another shadow DOM).

But no solution exists for creating a reference from outside a shadow targeting an element inside a shadow. RererenceTarget allows this kind of relationship to be established. When combined with the AriaMixin attributes it can be used to create references from inside one shadow to inside another.

What solutions exist today?

The ARIAMixin IDL attributes (such as ariaLabelledbyElements and ariaActiveDescendantElement) allow references to be created from inside a shadow DOM to an element outside the shadow DOM, but not in the other direction. Nothing exists today for creating references from outside a shadow to inside a shadow.

How would you solve it?

The proposed referenceTarget property on ShadowRoot that causes all ID references pointing to the host to be forwarded to an element inside the shadow with the given ID.

This can be done imperatively:

<script>
  customElements.define(
    "fancy-input",
    class FancyInput extends HTMLElement {
      constructor() {
        super();
        this.shadowRoot_ = this.attachShadow({ 
          mode: "closed",
          referenceTarget: "real-input",
        });
        this.shadowRoot_.innerHTML = `<input id="real-input">`;        
        // Optionally, set referenceTarget on the ShadowRoot object.
        // Not needed in this case since it was set in attachShadow() instead.
        // this.shadowRoot_.referenceTarget = "real-input";
      }
    }
  );
</script>

<label for="fancy-input">Fancy input</label>
<fancy-input id="fancy-input"></fancy-input>

Or declaratively:

<label for="fancy-input">Fancy input</label>
<fancy-input id="fancy-input">
  <template
    shadowrootmode="closed"
    shadowrootreferencetarget="real-input"
  >
    <input id="real-input">
  </template>
</fancy-input>

This would work with any attribute that works with ID; for the full list see here.

A Phase 2 of this proposal would extend the idea with referenceTargetMap, which allows individual attributes to be redirected to separate elements in the shadow DOM.

<input
  role="combobox"
  aria-controls="fancy-listbox"
  aria-activedescendant="fancy-listbox"
/>
<fancy-listbox id="fancy-listbox">
  <template
    shadowrootmode="closed"
    shadowrootreferencetargetmap="aria-controls: real-listbox,
                                  aria-activedescendant: option-1"
  >
    <div id="real-listbox" role="listbox">
      <div id="option-1" role="option">Option 1</div>
      <div id="option-2" role="option">Option 2</div>
    </div>
  </template>
</fancy-listbox>

Anything else?

For more info and alternatives considered, see the explainer: https://github.com/WICG/webcomponents/blob/gh-pages/proposals/reference-target-explainer.md

This was discussed in a TPAC breakout session. See notes and slides.

Phase 1 is prototyped in Chromium behind --enable-experimental-web-platform-features.

Metadata

Metadata

Assignees

No one assigned

    Labels

    accessibilityAffects accessibilityaddition/proposalNew features or enhancementsneeds implementer interestMoving the issue forward requires implementers to express intereststage: 1Incubationtopic: shadowRelates to shadow trees (as defined in DOM)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions