Start · Sprachen · JavaScript · Referenz · ElementInternals.ariaValueText

ElementInternals.ariaValueText

Eigenschaft

Legt für ein benutzerdefiniertes Element über <code>ElementInternals</code> den lesbaren Alternativtext zu <code>aria-valuenow</code> fest (Standard-Semantik ohne sichtbares Attribut).

seit JavaScript Baseline 2023: Chrome 77+, Edge 79+, Safari 16.4+, Kategorie: webapi

Signatur

ElementInternals.ariaValueText

Beschreibung

Die Eigenschaft ariaValueText des ElementInternals-Interfaces entspricht dem ARIA-Attribut aria-valuetext. Sie enthält eine für Menschen lesbare Darstellung des aktuellen Werts eines Bereichs-Widgets, z. B. eines Schiebereglers (role="slider"), einer Fortschrittsanzeige (progressbar), eines Zahlenfelds (spinbutton) oder einer Bildlaufleiste (scrollbar).

Gebraucht wird sie immer dann, wenn der reine Zahlenwert aus ariaValueNow für Nutzer von Screenreadern nichts aussagt. Ein Schieberegler mit dem Wert 3 kann so als „Mittwoch“ angesagt werden, eine Temperaturregelung als „21 Grad Celsius“ oder eine Bewertung als „4 von 5 Sternen“.

Anders als element.setAttribute("aria-valuetext", …) legt ElementInternals die Standard-Semantik eines Custom Elements fest, ohne ein Attribut ins DOM zu schreiben. Das Markup bleibt dadurch sauber. Setzt ein Nutzer der Komponente selbst ein aria-valuetext-Attribut auf den Host, hat dieses Vorrang vor dem Wert aus den Internals.

Auf das Objekt greift man über this.attachInternals() im Konstruktor der Komponente zu. Sinnvoll ist der Wert nur zusammen mit einer passenden role (über internals.role) sowie meist mit ariaValueNow, ariaValueMin und ariaValueMax.

Rückgabewert

Typ
string | null
Beschreibung
Den lesbaren Werttext als Zeichenkette oder null, wenn nichts gesetzt ist. Weist man null zu, wird der Wert entfernt.

Beispiele

Wochentag-Schieberegler als Custom Element

const TAGE = ['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag', 'Sonntag'];

class DaySlider extends HTMLElement {
  #internals;
  #value = 1;

  constructor() {
    super();
    this.#internals = this.attachInternals();
    this.#internals.role = 'slider';
    this.#internals.ariaLabel = 'Wochentag';
    this.#internals.ariaValueMin = '1';
    this.#internals.ariaValueMax = '7';
    this.tabIndex = 0;
    this.addEventListener('keydown', (e) => {
      if (e.key === 'ArrowRight') this.value = this.#value + 1;
      if (e.key === 'ArrowLeft') this.value = this.#value - 1;
    });
    this.value = 1;
  }

  set value(v) {
    this.#value = Math.min(7, Math.max(1, v));
    this.#internals.ariaValueNow = String(this.#value);
    // Screenreader sagt "Mittwoch" statt "3"
    this.#internals.ariaValueText = TAGE[this.#value - 1];
    this.textContent = TAGE[this.#value - 1];
  }

  get value() { return this.#value; }
}

customElements.define('day-slider', DaySlider);

const slider = document.createElement('day-slider');
document.body.append(slider);
slider.value = 3;
Die Barrierefreiheits-API meldet: Schieberegler "Wochentag", Wert "Mittwoch"

Fortschrittsanzeige mit sprechendem Status

class UploadProgress extends HTMLElement {
  #internals = this.attachInternals();

  connectedCallback() {
    this.#internals.role = 'progressbar';
    this.#internals.ariaValueMin = '0';
    this.#internals.ariaValueMax = '100';
    this.update(0, 12);
  }

  update(percent, filesTotal) {
    const done = Math.round((percent / 100) * filesTotal);
    this.#internals.ariaValueNow = String(percent);
    this.#internals.ariaValueText = `${done} von ${filesTotal} Dateien hochgeladen`;
  }

  get statusText() {
    return this.#internals.ariaValueText;
  }
}

customElements.define('upload-progress', UploadProgress);

const bar = document.body.appendChild(document.createElement('upload-progress'));
bar.update(50, 12);
console.log(bar.statusText);
6 von 12 Dateien hochgeladen

Wert zurücksetzen und Vorrang des Attributs

class TempDial extends HTMLElement {
  internals = this.attachInternals();
  constructor() {
    super();
    this.internals.role = 'spinbutton';
    this.internals.ariaValueNow = '21';
    this.internals.ariaValueText = '21 Grad Celsius';
  }
}
customElements.define('temp-dial', TempDial);

const dial = document.createElement('temp-dial');
console.log(dial.internals.ariaValueText);

// Das Attribut des Nutzers überschreibt die Standard-Semantik
dial.setAttribute('aria-valuetext', 'angenehm warm');
console.log(dial.getAttribute('aria-valuetext'));

// Standardwert entfernen
dial.internals.ariaValueText = null;
console.log(dial.internals.ariaValueText);
21 Grad Celsius angenehm warm null

// Wichtig · Fallstricke

  • Nur für Custom Elements: attachInternals() gibt es nur für autonome benutzerdefinierte Elemente, und es darf pro Element nur einmal aufgerufen werden. Ein zweiter Aufruf löst eine NotSupportedError-DOMException aus.
  • Kein Attribut im DOM: Der Wert erscheint nicht als aria-valuetext im Markup und ist auch mit getAttribute() nicht lesbar. Zum Testen den Barrierefreiheitsbaum in den DevTools nutzen.
  • Vorrang: Ein vom Nutzer gesetztes aria-valuetext-Attribut auf dem Host-Element hat Vorrang vor dem Wert aus den Internals.
  • Rolle erforderlich: Ohne passende Rolle (slider, progressbar, spinbutton, scrollbar, meter) ignorieren Screenreader den Wert. ariaValueNow sollte trotzdem gesetzt bleiben.
  • Synchron halten: Bei jeder Wertänderung ariaValueNow und ariaValueText gemeinsam aktualisieren, sonst werden veraltete Texte angesagt.
  • Kompatibilität: Die ARIA-Spiegelung auf ElementInternals gibt es in Chromium seit Version 77 (bzw. 79 für Edge), in Safari seit 16.4 und in Firefox seit 119. Für ältere Browser mit 'ariaValueText' in ElementInternals.prototype prüfen und notfalls auf setAttribute() ausweichen.