Start · Sprachen · JavaScript · Referenz · ElementInternals.ariaDetailsElements

ElementInternals.ariaDetailsElements

Eigenschaft

Array der Elemente, die zugängliche Detailinformationen für ein Custom Element liefern – das Standard-Gegenstück zu <code>aria-details</code> über <code>ElementInternals</code>.

seit JavaScript Chrome/Edge 135+, Safari 16.4+ (Firefox: in Entwic Kategorie: webapi

Signatur

ElementInternals.ariaDetailsElements

Beschreibung

Die Eigenschaft ariaDetailsElements des ElementInternals-Interfaces legt fest, welche Elemente ausführliche, zugängliche Details zu einem autonomen Custom Element liefern. Sie entspricht semantisch dem ARIA-Attribut aria-details, arbeitet aber mit direkten Elementreferenzen statt mit ID-Listen.

Der entscheidende Unterschied zum gleichnamigen Attribut: Über ElementInternals gesetzte Werte sind Standard-Semantik des Elements. Sie erscheinen nicht als sichtbares Attribut im DOM und werden überschrieben, sobald der Autor des Elements selbst aria-details bzw. element.ariaDetailsElements setzt. So kann eine Komponente sinnvolle Vorgaben machen, ohne das Markup der Nutzer zu verschmutzen.

Typische Anwendungsfälle sind Komponenten mit umfangreichen Zusatzinformationen: Diagramme mit Datentabelle, Formularfelder mit ausführlicher Hilfe oder Bilder mit Langbeschreibung. Anders als ariaDescribedByElements (kurze, vorgelesene Beschreibung) verweist ariaDetailsElements auf strukturierte Inhalte, zu denen Screenreader-Nutzer gezielt navigieren können.

Beim Lesen wird ein neues, eingefrorenes Array zurückgegeben; Änderungen erfolgen deshalb immer durch Zuweisung eines neuen Arrays. Referenzierte Elemente müssen im selben Dokument liegen und – je nach Scope-Regeln – aus Sicht des Hosts erreichbar sein (z. B. im eigenen Shadow Root oder im Light DOM bzw. einem übergeordneten Scope).

Parameter

Name Typ Default Beschreibung
$value Array<Element> | null null Beim Setzen: Array von Elementen, die Details bereitstellen. null entfernt die Standard-Semantik wieder.

Rückgabewert

Typ
Array<Element> | null
Beschreibung
Ein eingefrorenes Array der referenzierten Elemente oder null, wenn keine gesetzt sind. Nicht mehr verbundene oder nicht erreichbare Elemente werden beim Lesen herausgefiltert.

Beispiele

Diagramm-Komponente verweist auf Datentabelle im Shadow DOM

class DataChart extends HTMLElement {
  #internals;

  constructor() {
    super();
    this.#internals = this.attachInternals();
    const root = this.attachShadow({ mode: 'open' });
    root.innerHTML = `
      <canvas width="300" height="150"></canvas>
      <details>
        <summary>Daten als Tabelle</summary>
        <table id="daten"><tr><th>Monat</th><th>Umsatz</th></tr>
          <tr><td>Jan</td><td>1200</td></tr></table>
      </details>`;

    this.#internals.role = 'img';
    this.#internals.ariaLabel = 'Umsatzdiagramm';
    // Standard-Semantik: Tabelle liefert die Details
    this.#internals.ariaDetailsElements = [root.querySelector('#daten')];
  }

  get detailElements() {
    return this.#internals.ariaDetailsElements;
  }
}

customElements.define('data-chart', DataChart);

const chart = document.createElement('data-chart');
document.body.append(chart);
console.log(chart.detailElements.map((el) => el.id));
["daten"]

Details dynamisch austauschen und entfernen

class HelpField extends HTMLElement {
  static observedAttributes = ['help-for'];
  #internals = this.attachInternals();

  attributeChangedCallback(name, oldValue, newValue) {
    const help = newValue ? document.getElementById(newValue) : null;
    // Neues Array zuweisen – das gelesene Array ist eingefroren
    this.#internals.ariaDetailsElements = help ? [help] : null;
  }
}

customElements.define('help-field', HelpField);

document.body.insertAdjacentHTML('beforeend', `
  <section id="hilfe-passwort">Mindestens 12 Zeichen, eine Ziffer …</section>
  <help-field help-for="hilfe-passwort"></help-field>`);

const field = document.querySelector('help-field');
field.removeAttribute('help-for'); // setzt wieder auf null

Feature-Erkennung mit Fallback

class InfoBox extends HTMLElement {
  connectedCallback() {
    const internals = this.attachInternals();
    const details = document.querySelector('#info-details');
    if (!details) return;

    if ('ariaDetailsElements' in ElementInternals.prototype) {
      internals.ariaDetailsElements = [details];
    } else if (!this.hasAttribute('aria-details')) {
      // Fallback: ID-basiertes Attribut (funktioniert nicht über Shadow-Grenzen)
      this.setAttribute('aria-details', details.id);
    }
  }
}

customElements.define('info-box', InfoBox);

// Wichtig · Fallstricke

  • Browser-Unterstützung: Die Element-Reflection-Eigenschaften (ariaDetailsElements u. a.) sind noch nicht in allen Browsern verfügbar. Immer per 'ariaDetailsElements' in ElementInternals.prototype prüfen.
  • Kein Direkt-Mutieren: Das zurückgegebene Array ist eingefroren; push() wirft im Strict Mode einen TypeError. Stattdessen ein neues Array zuweisen.
  • Vorrang: Setzt der Nutzer der Komponente aria-details oder element.ariaDetailsElements, überschreibt das den Wert aus ElementInternals.
  • Scope-Regeln: Elemente in einem tieferen Shadow Root (z. B. im Shadow DOM eines anderen Elements) sind nicht gültig und werden beim Lesen ignoriert.
  • attachInternals() darf pro Element nur einmal aufgerufen werden und funktioniert nur bei autonomen Custom Elements.
  • Die Screenreader-Unterstützung für aria-details ist uneinheitlich – wichtige Informationen zusätzlich sichtbar bzw. über ariaDescribedByElements zugänglich machen.