Start · Sprachen · JavaScript · Referenz · ElementInternals.ariaLabel

ElementInternals.ariaLabel

Eigenschaft

Liest oder setzt den standardmäßigen barrierefreien Namen (<code>aria-label</code>) eines Custom Elements über dessen <code>ElementInternals</code>, ohne ein sichtbares Attribut zu setzen.

seit JavaScript Baseline 2023: Chrome/Edge 90+, Safari 16.4+, Fire Kategorie: webapi

Signatur

ElementInternals.ariaLabel

Beschreibung

Die Eigenschaft ariaLabel des ElementInternals-Interfaces entspricht dem ARIA-Attribut aria-label. Sie enthält einen String, der das Element für Hilfstechnologien wie Screenreader beschreibt. Sinnvoll ist das vor allem dann, wenn das Element keinen sichtbaren Text hat, etwa bei einem Button, der nur ein Symbol zeigt.

Anders als Element.ariaLabel wird dabei kein Attribut auf dem Host-Element angelegt. Der Wert gilt als Standard-Semantik des Custom Elements. Er steckt intern in der Komponente und taucht im DOM nicht auf. Setzt jemand, der die Komponente verwendet, selbst ein aria-label-Attribut auf das Element, gilt dieses Attribut und nicht der interne Wert. So kann eine Komponente sinnvolle Vorgaben machen, die man trotzdem überschreiben kann.

Das ElementInternals-Objekt bekommt man einmalig über this.attachInternals(), meist im Konstruktor des Custom Elements. Meist kombiniert man ariaLabel mit internals.role, damit Hilfstechnologien sowohl die Rolle als auch den Namen des Elements kennen.

Parameter

Name Typ Default Beschreibung
$value string | null null Beim Schreiben: der barrierefreie Name als String. Mit null wird der interne Standardwert wieder entfernt.

Rückgabewert

Typ
string | null
Beschreibung
Der aktuell gesetzte interne aria-label-Wert oder null, wenn keiner gesetzt ist. Ein aria-label-Attribut, das jemand direkt auf das Host-Element geschrieben hat, wird hier nicht zurückgegeben.

Beispiele

Symbol-Button mit Standard-Label

class CloseButton extends HTMLElement {
  #internals;
  constructor() {
    super();
    this.#internals = this.attachInternals();
    this.#internals.role = 'button';
    this.#internals.ariaLabel = 'Dialog schließen';
    this.attachShadow({ mode: 'open' }).innerHTML = '<span aria-hidden="true">✕</span>';
    this.tabIndex = 0;
  }
  get label() {
    return this.#internals.ariaLabel;
  }
}
customElements.define('close-button', CloseButton);

const btn = document.createElement('close-button');
document.body.append(btn);
console.log(btn.label);
console.log(btn.hasAttribute('aria-label'));
Dialog schließen false

Label abhängig vom Zustand aktualisieren

class PlayToggle extends HTMLElement {
  #internals = this.attachInternals();
  #playing = false;
  constructor() {
    super();
    this.#internals.role = 'button';
    this.#update();
    this.addEventListener('click', () => {
      this.#playing = !this.#playing;
      this.#update();
    });
  }
  #update() {
    this.#internals.ariaLabel = this.#playing ? 'Pause' : 'Abspielen';
    this.textContent = this.#playing ? '⏸' : '▶';
  }
  get currentLabel() { return this.#internals.ariaLabel; }
}
customElements.define('play-toggle', PlayToggle);

const toggle = document.createElement('play-toggle');
document.body.append(toggle);
console.log(toggle.currentLabel);
toggle.click();
console.log(toggle.currentLabel);
Abspielen Pause

Attribut auf dem Host überschreibt den internen Wert

class SearchIcon extends HTMLElement {
  internals = this.attachInternals();
  constructor() {
    super();
    this.internals.role = 'img';
    this.internals.ariaLabel = 'Suche';
  }
}
customElements.define('search-icon', SearchIcon);

const icon = document.createElement('search-icon');
// Wer die Komponente nutzt, überschreibt das Label:
icon.setAttribute('aria-label', 'Produkte durchsuchen');
document.body.append(icon);

console.log(icon.internals.ariaLabel); // interner Standardwert
console.log(icon.ariaLabel);           // Attribut des Hosts, gilt für Screenreader
Suche Produkte durchsuchen

// Wichtig · Fallstricke

  • Nur für autonome Custom Elements: attachInternals() lässt sich nur einmal pro Element aufrufen. Bei eingebauten Elementen und bei angepassten eingebauten Elementen (is="...") wirft der Aufruf einen NotSupportedError.
  • Kein Attribut im DOM: Der Wert erscheint nicht als aria-label-Attribut. CSS-Selektoren wie [aria-label] und Tests, die Attribute abfragen, finden ihn deshalb nicht. Prüfe den Wert mit den Entwicklerwerkzeugen für Barrierefreiheit.
  • Vorrang: Ein aria-label, das auf dem Host gesetzt ist, überschreibt den internen Wert. Das gleiche gilt für aria-labelledby, das bei der Berechnung des barrierefreien Namens grundsätzlich Vorrang vor aria-label hat.
  • Nicht für jede Rolle sinnvoll: Bei Rollen wie generic, presentation oder none wird kein Name vergeben, sodass das Label ignoriert wird. Setze deshalb eine passende Rolle über internals.role.
  • Browser-Unterstützung: Chrome/Edge ab Version 90, Safari ab 16.4, Firefox erst ab 119. Für ältere Browser prüfst du mit 'ariaLabel' in ElementInternals.prototype und setzt ersatzweise das Attribut aria-label auf dem Host.
  • Sichtbarer Text ist meist die bessere Lösung als ein aria-label. Das Label wird außerdem von manchen automatischen Übersetzungswerkzeugen nicht übersetzt.