Interaktion ohne JavaScript
Das lernst du in dieser Lektion
- Du baust Akkordeons mit details/summary – inklusive exklusiver Gruppen ganz ohne Skript.
- Du kennst das dialog-Element und weißt, was der Browser dir dabei schenkt.
- Du erstellst Popovers rein deklarativ mit popover und popovertarget.
- Du unterscheidest progress und meter sicher und setzt low, high und optimum korrekt ein.
- Du kennst output, hidden, autofocus und contenteditable – und ihre Grenzen.
Für ein Akkordeon laden viele Seiten heute noch ein 80-Kilobyte-Skriptpaket – dabei kann der Browser das längst von allein. Aufklappbare Bereiche, modale Dialoge, Tooltips und Popovers, Fortschrittsbalken: All das steckt inzwischen direkt in HTML, mit eingebauter Tastaturbedienung und Barrierefreiheit frei Haus. Jede Zeile JavaScript, die du nicht schreibst, kann nicht kaputtgehen, nicht langsam laden und niemanden aussperren. In dieser Lektion lernst du die interaktiven Elemente kennen, die aus HTML mehr machen als ein statisches Dokument – und du wirst überrascht sein, wie weit du ohne eine einzige Zeile Skript kommst.
Die Philosophie: Der Browser kann mehr, als viele denken
Warum überhaupt ohne JavaScript, wo es doch funktioniert? Aus drei handfesten Gründen. Robustheit: Native Elemente funktionieren auch, wenn das Skript noch lädt, fehlschlägt oder von einem strengen Firmennetz blockiert wird. Geschwindigkeit: Kein Download, kein Parsen, keine Ausführung – die Interaktion ist da, sobald das HTML da ist. Barrierefreiheit: Die Browser-Hersteller haben Fokus-Verhalten, Tastaturbedienung und die Anbindung an Screenreader bereits gelöst – und zwar besser getestet, als es ein einzelnes Projekt je könnte. Selbst gebaute Widgets müssen all das mühsam nachbauen und scheitern erstaunlich oft daran.
Dieses Denken hat einen Namen: Progressive Enhancement. Die Grundfunktion steht in robustem HTML, und Skripte veredeln sie nur dort, wo es echten Mehrwert gibt. Fällt die Veredelung aus, bleibt die Seite benutzbar – fällt dagegen ein Skript aus, das die Grundfunktion selbst trägt, bleibt nichts. Die Faustregel dieser Lektion lautet deshalb: Erst prüfen, was HTML mitbringt – JavaScript ist die Ergänzung, nicht der Ausgangspunkt.
details und summary: das eingebaute Akkordeon
Das Paar <details>/<summary> erzeugt einen auf- und zuklappbaren Bereich: <summary> ist die stets sichtbare Überschrift, der Rest des <details>-Inhalts erscheint erst beim Aufklappen. Der Browser liefert alles mit: den Klick-Handler, die Bedienung per Tastatur (Enter und Leertaste), den aufgeklappt/zugeklappt-Zustand für Screenreader – sogar die Suchfunktion der Seite (Strg+F) findet in modernen Browsern Text in zugeklappten Bereichen und klappt sie automatisch auf.
Zwei Attribute solltest du kennen. Mit open startet ein Bereich aufgeklappt – sinnvoll für die wichtigste Frage einer FAQ-Liste. Und seit die Funktion 2024 in allen großen Browsern angekommen ist (Baseline), macht das name-Attribut aus mehreren <details>-Elementen eine exklusive Gruppe: Tragen sie denselben Namen, schließt das Öffnen eines Bereichs automatisch alle anderen – das klassische Akkordeon-Verhalten, für das jahrelang JavaScript nötig war. Probiere beides aus:
dialog: Modale mit eingebautem Fokus-Management
Das <dialog>-Element gibt Dialogfenstern endlich eine Semantik: Es ist ein Dialog, statt nur wie einer auszusehen. Geöffnet als modaler Dialog legt es sich über die Seite, macht den Rest der Seite unbedienbar und für Screenreader unsichtbar (inert), fängt den Fokus im Dialog ein und schließt sich mit der Escape-Taste – alles ohne dass du eine dieser Verhaltensweisen programmieren müsstest. Der abgedunkelte Hintergrund ist über das CSS-Pseudoelement ::backdrop gestaltbar. Wer so etwas je von Hand gebaut hat, weiß, wie viele Fehlerquellen hier auf einen Schlag verschwinden.
Ein ehrliches Wort gehört dazu: Zum Öffnen als modaler Dialog braucht es genau eine Zeile JavaScript – den Aufruf von showModal(). Das Schließen dagegen geht rein deklarativ: Ein Button mit method="dialog" in einem Formular innerhalb des Dialogs schließt ihn ohne jedes Skript. Die Bilanz bleibt spektakulär: eine Zeile Code, und Fokus-Falle, Escape-Verhalten, Inert-Schaltung und Semantik gibt es geschenkt.
<button onclick="document.getElementById('abo-dialog').showModal()">
Newsletter abonnieren
</button>
<dialog id="abo-dialog">
<h2>Newsletter abonnieren</h2>
<p>Einmal im Monat, jederzeit abbestellbar.</p>
<form method="dialog">
<!-- method="dialog": Absenden schließt den Dialog, ohne Skript -->
<button>Schließen</button>
</form>
</dialog>Die Popover-API: Overlays ganz ohne Skript
Für alles, was kein blockierender Dialog sein muss – Menüs, Hinweisblasen, Info-Overlays –, geht HTML seit 2024 noch einen Schritt weiter: Die Popover-API kommt komplett ohne JavaScript aus und ist Baseline, funktioniert also in allen großen Browsern. Das Rezept hat zwei Zutaten: Das Overlay-Element bekommt das Attribut popover (und eine id), der auslösende Button verweist mit popovertarget auf diese ID. Fertig. Der Browser übernimmt das Ein- und Ausblenden, legt das Popover in die oberste Darstellungsebene (über alles andere, unabhängig von Verschachtelung und z-index-Kämpfen) und liefert das sogenannte Light Dismiss: Ein Klick außerhalb oder die Escape-Taste schließt das Popover automatisch.
Die Abgrenzung zum Dialog merkst du dir am besten so: <dialog> (modal) unterbricht, popover ergänzt. Ein Popover blockiert die restliche Seite nicht und eignet sich damit für alles Beiläufige: das Benachrichtigungs-Menü, die Legende neben einem Diagramm, den „Teilen“-Knopf mit seinen Optionen. Übrigens lassen sich beide kombinieren – auch ein <dialog> kann als nicht-modales Popover geöffnet werden. Über popovertargetaction="show" bzw. "hide" steuerst du, ob ein Button nur öffnet oder nur schließt; ohne die Angabe schaltet er bei jedem Klick um. Und weil das Popover standardmäßig ein neutrales <div> ist, gilt die Semantik-Lehre der früheren Lektionen weiter: Ist der Inhalt eine Navigation, gehört eine <nav> hinein.
progress und meter: zwei Balken, zwei Bedeutungen
Zwei Elemente, die optisch ähnlich wirken, aber grundverschieden gemeint sind. <progress> zeigt den Fortschritt eines laufenden Vorgangs: Datei-Upload, Installationsschritt, Kursfortschritt. Mit value und max ist er determinate (bestimmter Fortschritt); lässt du value weg, zeigt der Browser eine unbestimmte Aktivitätsanimation – ehrlich für Situationen, in denen du nur weißt, dass etwas läuft, aber nicht wie lange noch.
<meter> zeigt dagegen einen Messwert in einem bekannten Wertebereich – Füllstand, Bewertung, Speicherplatz. Hier passiert nichts, es ist einfach so viel. Seine Superkraft sind die Attribute low, high und optimum: Sie teilen den Wertebereich in Zonen, und der Browser färbt den Balken je nach Lage des Wertes von sich aus grün, gelb oder rot. optimum sagt dabei, welche Zone die gute ist – bei „belegter Speicherplatz“ ist wenig optimal, bei „Akkuladung“ viel.
<!-- Laufender Vorgang: 7 von 10 Lektionen geschafft -->
<label for="kurs">Kursfortschritt:</label>
<progress id="kurs" value="7" max="10">7 von 10</progress>
<!-- Unbestimmter Vorgang: Dauer unbekannt -->
<progress>Wird geladen …</progress>
<!-- Messwert: 182 von 200 GB belegt – wenig ist hier optimal,
ab "high" färbt der Browser den Balken warnend ein -->
<label for="disk">Belegter Speicherplatz:</label>
<meter id="disk" value="182" max="200"
low="120" high="160" optimum="40">
182 von 200 GB
</meter>Kleine Helfer: output, hidden, autofocus, contenteditable
Vier Kurzporträts zum Abschluss. <output> ist der semantische Platz für Berechnungsergebnisse – etwa die Summe eines Bestellformulars. Sein stiller Vorzug: Screenreader behandeln es als Live-Region, sagen Änderungen also von selbst an. Die Werte hineinzurechnen bleibt zwar Aufgabe eines (kleinen) Skripts, aber das Element sorgt dafür, dass das Ergebnis niemandem entgeht.
hidden versteckt ein Element vollständig – visuell und vor assistiven Technologien. Es dokumentiert die Absicht („dieser Inhalt ist gerade nicht relevant“) direkt im Markup statt in einer CSS-Datei. Wichtig: Es ist das Gegenteil einer Barrierefreiheits-Technik zum „unsichtbaren Bereitstellen“ – was hidden trägt, existiert für niemanden.
autofocus setzt beim Laden der Seite den Fokus auf ein Element. Setze es äußerst sparsam ein – höchstens auf das eine zentrale Eingabefeld einer Such- oder Login-Seite. Auf inhaltsreichen Seiten springt es Screenreader- und Tastatur-Nutzern mitten ins Dokument und überspringt dabei alles davor; auf dem Smartphone reißt es ungefragt die Bildschirmtastatur auf.
Und als Kuriosität: contenteditable macht jedes Element frei editierbar – der Browser wird zum Textverarbeitungsprogramm. Im Alltag brauchst du das kaum je selbst, aber du kennst es aus der Praxis: Fast jeder Rich-Text-Editor im Web (CMS, Web-Mail, Kommentarfelder mit Formatierung) baut im Kern auf genau diesem Attribut auf.
Zusammenfassung
- Weniger JavaScript heißt robuster, schneller, barrierefreier – native Elemente bringen Tastaturbedienung und Screenreader-Anbindung fertig getestet mit.
<details>/<summary>ist das eingebaute Akkordeon; ein gemeinsamesname-Attribut macht die Gruppe exklusiv (Baseline seit 2024),openstartet aufgeklappt.<dialog>braucht eine Zeile JavaScript (showModal()) und schenkt dafür Fokus-Falle, Escape-Verhalten,::backdropund Inert-Schaltung.- Die Popover-API (
popover+popovertarget) baut Overlays komplett ohne Skript – inklusive Light Dismiss per Außenklick und Escape. <progress>= laufender Vorgang (auch unbestimmt),<meter>= Messwert im Bereich, mit Ampelzonen überlow/high/optimum.outputmeldet Ergebnisse als Live-Region,hiddenversteckt vollständig,autofocusnur äußerst sparsam einsetzen.
In der nächsten Lektion holen wir fremde Welten in deine Seite: Mit iframes, eingebettetem SVG und den zugehörigen Sicherheitsmechanismen lernst du, externe Inhalte einzubinden, ohne die Kontrolle über deine Seite aus der Hand zu geben.
Teste dein Wissen
5 kurze Fragen zu dieser Lektion – die Auswertung passiert direkt im Browser.