Start · Sprachen · JavaScript · Referenz · ElementInternals.ariaDisabled

ElementInternals.ariaDisabled

Eigenschaft

Setzt oder liest den Standardwert von <code>aria-disabled</code> für ein Custom Element, ohne ein sichtbares Attribut im DOM anzulegen.

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

Signatur

ElementInternals.ariaDisabled

Beschreibung

Die Eigenschaft ariaDisabled der Schnittstelle ElementInternals gehört zur ARIA-Reflexion für Custom Elements. Sie legt die Standard-Semantik für aria-disabled fest. Damit teilt das Element assistiven Technologien wie Screenreadern mit, dass es zwar wahrnehmbar, aber deaktiviert ist: Man kann es nicht bearbeiten und nicht anderweitig bedienen.

Anders als bei element.setAttribute("aria-disabled", "true") erscheint dabei kein Attribut im Markup. Die Komponente beschreibt ihre Semantik also selbst, und die Autorin bzw. der Autor der Seite kann sie weiterhin überschreiben. Setzt jemand aria-disabled direkt als Attribut auf dem Host-Element, hat dieses Attribut Vorrang vor dem Wert aus ElementInternals.

Man erhält das ElementInternals-Objekt über this.attachInternals() im Konstruktor eines Custom Elements. Typische Einsatzfälle sind eigene Buttons, Schalter oder Listeneinträge, die einen deaktivierten Zustand haben. Formularbezogene Elemente (static formAssociated = true) bekommen dagegen disabled meist nativ über das Attribut und den Callback formDisabledCallback.

Parameter

Name Typ Default Beschreibung
$value string | null null Beim Schreiben: "true" (deaktiviert) oder "false" (aktiviert, Standardverhalten). Mit null wird die Standard-Semantik entfernt.

Rückgabewert

Typ
string | null
Beschreibung
Den aktuell gesetzten Wert als Zeichenkette ("true" oder "false"). Wurde nichts gesetzt, ist der Wert null.

Beispiele

Eigener Button mit deaktiviertem Standardzustand

class FancyButton extends HTMLElement {
  #internals;
  constructor() {
    super();
    this.#internals = this.attachInternals();
    this.#internals.role = 'button';
    this.#internals.ariaDisabled = 'true';
  }
  get internals() { return this.#internals; }
}
customElements.define('fancy-button', FancyButton);

const btn = document.createElement('fancy-button');
document.body.append(btn);
console.log(btn.internals.ariaDisabled);
console.log(btn.hasAttribute('aria-disabled'));
true false

Zustand über ein beobachtetes Attribut synchronisieren

class ToggleSwitch extends HTMLElement {
  static observedAttributes = ['disabled'];
  #internals = this.attachInternals();

  constructor() {
    super();
    this.#internals.role = 'switch';
    this.tabIndex = 0;
    this.addEventListener('click', () => {
      if (this.#internals.ariaDisabled === 'true') return; // Klick ignorieren
      const on = this.#internals.ariaChecked === 'true';
      this.#internals.ariaChecked = String(!on);
    });
  }

  attributeChangedCallback(name, _old, value) {
    if (name === 'disabled') {
      const disabled = value !== null;
      this.#internals.ariaDisabled = String(disabled);
      this.tabIndex = disabled ? -1 : 0;
    }
  }
}
customElements.define('toggle-switch', ToggleSwitch);

const sw = document.createElement('toggle-switch');
sw.setAttribute('disabled', '');
document.body.append(sw);

Feature-Erkennung mit Fallback auf das Attribut

const setDisabledSemantics = (el, internals, disabled) => {
  if (internals && 'ariaDisabled' in internals) {
    internals.ariaDisabled = String(disabled);
  } else {
    // Fallback für ältere Browser
    el.setAttribute('aria-disabled', String(disabled));
  }
};

console.log('ariaDisabled' in ElementInternals.prototype);
true

// Wichtig · Fallstricke

  • Nur Semantik, kein Verhalten: ariaDisabled = "true" verhindert weder Klicks noch Fokus. Du musst Ereignisse selbst abfangen und tabIndex selbst anpassen.
  • Der Host-Wert gewinnt: Ein aria-disabled-Attribut direkt auf dem Element überschreibt den Wert aus ElementInternals.
  • CSS: Der Selektor [aria-disabled="true"] greift hier nicht, weil kein Attribut entsteht. Nutze stattdessen einen eigenen Zustand über internals.states (CustomStateSet) und :state(disabled).
  • Nur für autonome Custom Elements: attachInternals() wirft einen Fehler bei eingebauten Elementen, bei angepassten eingebauten Elementen (is="…") und bei einem zweiten Aufruf.
  • Werte: Es werden Zeichenketten erwartet. Ein Boolean wird zwar in eine Zeichenkette umgewandelt, String(bool) macht die Absicht aber deutlicher.
  • Kompatibilität: Firefox unterstützt die ARIA-Reflexion auf ElementInternals erst ab Version 119. Für ältere Browser brauchst du eine Feature-Erkennung.