← Reference Target for Cross-root ARIA
v152 · web components · idl member
ShadowRoot.referenceTarget
The JavaScript surface for Reference Target: a settable DOMString? on ShadowRoot holding the ID of the element in the shadow tree that IDREFs to the host should resolve to — settable at creation time via the ShadowRootInit.referenceTarget dictionary member, or declaratively via the shadowrootreferencetarget template attribute and its HTMLTemplateElement.shadowRootReferenceTarget reflection.
#enable-experimental-web-platform-features; Firefox 144+ dom.shadowdom.referenceTarget.enabled; Safari 26+ referenceTarget) and BCD has not yet recorded Chrome 152's enabled-by-default milestone. Feature-detect: "referenceTarget" in ShadowRoot.prototype.
syntax
Verbatim from Chromium's shadow_root.idl (the comment is part of the source):
// The referenceTarget attribute is the ID of an element in the shadow tree.
// When the host element is the target of an IDREF attribute like
// aria-activedescendant, the reference resolves to the referenceTarget.
// See https://crbug.com/346835896
[RuntimeEnabled=ShadowRootReferenceTarget] attribute DOMString? referenceTarget;
The ShadowRootInit dictionary member, verbatim from shadow_root_init.idl:
dictionary ShadowRootInit {
required ShadowRootMode mode;
boolean delegatesFocus;
SlotAssignmentMode slotAssignment;
[RuntimeEnabled=ScopedCustomElementRegistry] CustomElementRegistry? customElementRegistry;
boolean serializable;
boolean clonable;
[RuntimeEnabled=ShadowRootReferenceTarget] DOMString? referenceTarget;
// Note: if you add a parameter here, be sure to add it to the list of checks
// in Element::attachShadow() for existing declarative shadow roots.
};
And the declarative-shadow-DOM reflection, verbatim from html_template_element.idl:
[CEReactions, Reflect, RuntimeEnabled=ShadowRootReferenceTarget]
attribute DOMString? shadowRootReferenceTarget;
Source: shadow_root.idl; shadow_root_init.idl; html_template_element.idl — all fetched 2026-07-28
inputs (setting)
shadowRoot.referenceTarget = value | Any DOMString or null. The value is the id of an element in the shadow tree; it is stored as given (no validation at set time — resolution happens live, at reference-lookup time) |
|---|---|
attachShadow({ referenceTarget }) | Same value space via the ShadowRootInit dictionary; sets the initial reference target at creation, for both open and closed roots (the explainer's sp-checkbox uses a closed root) |
<template shadowrootreferencetarget> | Content attribute taking the target ID; parsed when the declarative shadow root attaches. Reflected by HTMLTemplateElement.shadowRootReferenceTarget (DOMString?, [CEReactions, Reflect]) — reading the reflection on a still-present template returns the attribute value |
| Missing/unknown ID | Not an error. Resolution is by ID lookup in the shadow tree at reference-lookup time; if nothing matches, forwarding simply has no target until a matching element exists (see lifecycle — references are live) |
DOMString?, no RaisesException); WICG explainer — Phase 1, Live references
outputs (getting)
The getter returns the current value as a DOMString? — the ID string last set (via IDL, ShadowRootInit, or the declarative attribute), or null when no reference target is set. It returns the ID string, not the element: resolving the string to an element is the engine's job at IDREF-lookup time; script that wants the element does its own shadowRoot.getElementById(value). On a closed root the property exists on the ShadowRoot object but is only reachable where script retained a reference to that root — it does not leak through the host.
attribute DOMString?); WICG explainer — sp-checkbox (closed root)
errors and edge cases
| Setter exceptions | None — the IDL carries no RaisesException on this attribute; any string (or null) is accepted |
|---|---|
attachShadow exceptions | attachShadow() itself can throw for unrelated reasons (e.g. a second attach on the same host, or a declarative-shadow-root mismatch — the dictionary comment notes new members are added to the existing-DSD checks in Element::attachShadow()); none of these are specific to referenceTarget |
| Duplicate IDs | The explainer defines resolution as an ID lookup in the shadow tree; normal getElementById-style first-match rules apply. Not separately specified in the sources read — treat duplicate IDs in the shadow tree as an authoring error |
aria-owns forwarding | Requires the separate ShadowRootReferenceTargetAriaOwns flag, which has no status field in runtime_enabled_features.json5 (not enabled anywhere by default; WICG/webcomponents #1091) — do not rely on aria-owns forwarding in Chrome 152 |
context and exposure
ShadowRoot.referenceTarget and the ShadowRootInit member are exposed in Window (the interface is [Exposed=Window]) and gated by the ShadowRootReferenceTarget runtime feature (status: "stable" at trunk; origin_trial_feature_name: "ShadowRootReferenceTarget" for the concluded 133–135 origin trial). The template reflection is likewise [RuntimeEnabled=ShadowRootReferenceTarget]. Feature-detect:
const supported = "referenceTarget" in ShadowRoot.prototype;
Source: runtime_enabled_features.json5; shadow_root.idl
lifecycle and live updates
The reference target is a live reference: the engine re-resolves it whenever the relevant state changes. From the explainer (verbatim list):
- The host changes its
referenceTargetto refer to a different ID. - An element with an
idthat matches its host's referenceTarget is added to or removed from the host's shadow tree. - The
idattribute of an element inside the host's shadow tree is changed to or from the referenceTarget ID. - The host is added or removed from the DOM.
- The host's
idattribute is changed.
Declarative roots serialize the setting: getHTML({ serializableShadowRoots: true }) emits shadowrootreferencetarget (WPT gethtml-serialization.html), and the dictionary comment in shadow_root_init.idl records that new ShadowRootInit members join the existing-declarative-root equality checks in Element::attachShadow() — an imperative re-attach over a declarative root must match the declarative referenceTarget value.
examples
// Set at creation (open or closed root):
const root = host.attachShadow({ mode: "open", referenceTarget: "real-input" });
root.innerHTML = `<input id="real-input">`;
// Or later, via the IDL attribute:
root.referenceTarget = "other-input";
// Read back — an ID string or null:
console.log(root.referenceTarget); // "other-input"
console.log(root.getElementById(root.referenceTarget)); // the element
// Declarative equivalent + reflection:
// <template shadowrootmode="open" shadowrootreferencetarget="real-checkbox">…</template>
console.log(templateEl.shadowRootReferenceTarget); // "real-checkbox"
Live-update behavior (from the explainer's guarantee): after root.referenceTarget = "other-input", an existing <label for="host-id"> immediately labels #other-input — no observer or re-registration needed.
compatibility
| Engine | ShadowRoot.referenceTarget | shadowrootreferencetarget attribute |
|---|---|---|
| Chrome / Edge | 133 (flag) → 152 enabled by default (listing) | Same (both BCD keys move together) |
| Firefox | 144 behind dom.shadowdom.referenceTarget.enabled | Same |
| Safari | 26 behind referenceTarget (+ referenceTarget support for aria-owns) | Same |
BCD marks both entries experimental: true and does not yet record Chrome 152's default-on (checked 2026-07-28 — freshness gap; the milestone listing is authoritative for Chrome).
security and privacy
Reference Target is designed to preserve shadow encapsulation rather than weaken it: the only new information an outside page gains is that IDREFs to the host resolve to some internal element — the internal structure (which ID, what markup) is not exposed. Element-reflecting JavaScript getters deliberately return the host, never the internal target (interaction contract), so script cannot launder shadow-internal element references out through ariaControlsElements or HTMLLabelElement.control. CSS selectors and event retargeting are unaffected (WPT event-path.html). No new storage, network, or fingerprinting surface is introduced in the sources read.
see also
- gendn — Reference Target for Cross-root ARIA (overview: mechanism, supported attributes, interactions)
- Chromium shadow_root.idl · shadow_root_init.idl · html_template_element.idl
- whatwg/dom PR #1353 (ShadowRoot-side normative change, OPEN) · whatwg/html PR #10995 (OPEN)
- WPT shadow-dom/reference-target/tentative/: WPT shadowrootreferencetarget-idl-reflection.html · property-reflection.html
- chromestatus.com/feature/5188237101891584