Start · Sprachen · JavaScript · Referenz · ElementInternals.ariaSelected

ElementInternals.ariaSelected

Eigenschaft

Liest oder setzt den Standard-ARIA-Zustand <code>aria-selected</code> eines Custom Elements über dessen <code>ElementInternals</code>, ohne ein sichtbares Attribut zu erzeugen.

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

Signatur

ElementInternals.ariaSelected

Beschreibung

Die Eigenschaft ariaSelected der Schnittstelle ElementInternals entspricht dem ARIA-Zustand aria-selected. Er gibt an, ob ein Element, das ausgewählt werden kann, gerade ausgewählt ist. Typische Rollen dafür sind option, tab, row, gridcell und treeitem.

Anders als Element.ariaSelected oder das HTML-Attribut aria-selected legt der Wert über ElementInternals nur die Standard-Semantik eines autonomen Custom Elements fest. Im DOM erscheint dabei kein Attribut („sprouting“ wird vermieden). Setzt ein Autor selbst aria-selected auf das Element, hat dieser Wert Vorrang vor dem internen Standardwert.

Die Eigenschaft eignet sich für Web Components wie eigene Listboxen, Tab-Leisten oder Auswahlraster. Die Komponente verwaltet ihren Auswahlzustand dann selbst und teilt ihn Screenreadern mit. Man erhält die ElementInternals über this.attachInternals() im Konstruktor des Custom Elements.

Der Wert ist ein String und kein Boolean. Zulässig sind "true", "false" und "undefined". Mit null entfernt man den Standardwert.

Parameter

Name Typ Default Beschreibung
$value string | null null Neuer Wert beim Setzen: "true" (ausgewählt), "false" (auswählbar, aber nicht ausgewählt), "undefined" (nicht auswählbar) oder null (Standardwert entfernen).

Rückgabewert

Typ
string | null
Beschreibung
Der aktuell gesetzte Standardwert als String ("true", "false", "undefined") oder null, wenn keiner gesetzt ist. Ein vom Autor gesetztes aria-selected-Attribut wird hier nicht zurückgegeben.

Beispiele

Eigene Listbox-Option mit Auswahlzustand

class MyOption extends HTMLElement {
  #internals;

  constructor() {
    super();
    this.#internals = this.attachInternals();
    this.#internals.role = 'option';
    this.#internals.ariaSelected = 'false';
  }

  get selected() {
    return this.#internals.ariaSelected === 'true';
  }

  set selected(value) {
    this.#internals.ariaSelected = value ? 'true' : 'false';
    // Zusätzlich für CSS: :state(selected)
    value ? this.#internals.states.add('selected')
          : this.#internals.states.delete('selected');
  }
}

customElements.define('my-option', MyOption);

const opt = document.createElement('my-option');
opt.selected = true;
console.log(opt.selected);
console.log(opt.hasAttribute('aria-selected'));
true false

Tab-Leiste: nur ein Tab ausgewählt

class MyTab extends HTMLElement {
  constructor() {
    super();
    this.internals = this.attachInternals();
    this.internals.role = 'tab';
    this.internals.ariaSelected = 'false';
    this.tabIndex = -1;
  }
}
customElements.define('my-tab', MyTab);

const selectTab = (tabs, active) => {
  for (const tab of tabs) {
    const isActive = tab === active;
    tab.internals.ariaSelected = String(isActive);
    tab.tabIndex = isActive ? 0 : -1;
  }
};

const list = document.createElement('div');
list.setAttribute('role', 'tablist');
const tabs = ['Allgemein', 'Konto', 'Sicherheit'].map((label) => {
  const t = document.createElement('my-tab');
  t.textContent = label;
  list.append(t);
  return t;
});
document.body.append(list);

selectTab(tabs, tabs[1]);
console.log(tabs.map((t) => t.internals.ariaSelected));
["false", "true", "false"]

Standardwert zurücksetzen und Autor-Vorrang

class MyCell extends HTMLElement {
  constructor() {
    super();
    this.internals = this.attachInternals();
    this.internals.role = 'gridcell';
    this.internals.ariaSelected = 'true';
  }
}
customElements.define('my-cell', MyCell);

const cell = document.createElement('my-cell');
// Autor-Attribut überschreibt den internen Standardwert für Hilfstechnologien
cell.setAttribute('aria-selected', 'false');
console.log(cell.internals.ariaSelected); // interner Wert bleibt

cell.internals.ariaSelected = null; // Standardwert entfernen
console.log(cell.internals.ariaSelected);
true null

// Wichtig · Fallstricke

  • String statt Boolean: Der Ausdruck internals.ariaSelected = true wird zwar in "true" umgewandelt, beim Lesen erhält man aber immer einen String zurück. Die Prüfung if (internals.ariaSelected) ist deshalb auch bei "false" wahr. Vergleichen Sie stattdessen mit === 'true'.
  • Passende Rolle nötig: aria-selected hat nur bei Rollen wie option, tab, row, gridcell, columnheader, rowheader oder treeitem eine Bedeutung. Setzen Sie daher zusätzlich internals.role.
  • Nicht mit aria-checked oder aria-pressed verwechseln: Für Kontrollkästchen und Umschaltflächen sind jeweils diese Zustände gedacht.
  • Autor-Vorrang: Ein im Markup gesetztes aria-selected-Attribut überschreibt den internen Wert. Die Eigenschaft liest diesen Autor-Wert nicht mit aus.
  • Nur für autonome Custom Elements: attachInternals() funktioniert nicht bei eingebauten Elementen oder bei angepassten eingebauten Elementen (is="…"). Ein zweiter Aufruf löst einen NotSupportedError aus.
  • Kompatibilität: Die ARIA-Spiegelung auf ElementInternals gibt es in Chromium seit Version 77 und in Safari seit 16.4. Firefox unterstützt sie erst seit Version 119. Für ältere Browser prüft man 'ariaSelected' in ElementInternals.prototype und setzt als Ersatz das Attribut.