JavaScript Styles und Klassen
Erscheinungsbild von Elementen mit JavaScript steuern: className und classList (add, remove, toggle, contains, replace), die style-Eigenschaft, cssText und getComputedStyle zum Auslesen berechneter Werte.
Einführung
Es gibt zwei Möglichkeiten, das Aussehen eines Elements über JavaScript zu verändern:
- Eine CSS-Klasse hinzufügen oder entfernen — das Styling liegt im Stylesheet, und JavaScript schaltet die Klasse lediglich ein oder aus. Dies ist der bevorzugte Ansatz.
- Einen Inline-Style direkt am Element über die
style-Eigenschaft setzen — nützlich, wenn der Wert zur Laufzeit berechnet wird (zum Beispiel eine Position, die von der Maus abhängt).
Dieses Kapitel behandelt beides: die className- und classList-APIs für die Arbeit mit Klassen, die style-Eigenschaft und cssText für Inline-Styles sowie getComputedStyle zum Auslesen der endgültigen Styles, die der Browser tatsächlich angewendet hat. Einen umfassenderen Überblick über CSS und das DOM bietet Working with Styles in the DOM.
Die style-Eigenschaft
Direkte Style-Manipulation
Die style-Eigenschaft ist ein object, dessen Schlüssel die Inline-CSS-Eigenschaften des Elements sind. Um den Style eines Elements direkt über JavaScript zu ändern, weist man einem dieser Schlüssel einen Wert zu. Hier ein Beispiel, das die Hintergrundfarbe und Schriftgröße eines Absatzes ändert:
<!-- snippet: html-result -->
<style>
#myParagraph {
color: white; /* Ensures text is readable on a blue background */
}
</style>
<div id="myParagraph">This is a paragraph.</div>
<script>
document.getElementById("myParagraph").style.backgroundColor = "blue";
document.getElementById("myParagraph").style.fontSize = "16px";
</script>Zu beachten sind die Eigenschaftsnamen: CSS verwendet Bindestriche (background-color, font-size), das style-object hingegen camelCase (backgroundColor, fontSize). Mehrwortige Eigenschaften folgen immer dieser Regel, und Eigenschaften mit Präfix behalten den führenden Bindestrich als Großbuchstaben (-moz-border-radius wird zu MozBorderRadius). Werte sind immer strings, und numerische CSS-Werte müssen ihre Einheit enthalten — el.style.fontSize = "16px", nicht 16.
Das Setzen von el.style.backgroundColor schreibt in das style="..."-Attribut des Elements, betrifft also nur dieses eine Element und überschreibt Stylesheet-Regeln (es hat dasselbe Gewicht wie ein autorisierter Inline-Style). Um einen Inline-Wert zu entfernen, weist man einen leeren string zu: el.style.fontSize = "".
Diese Methode bietet direkte Kontrolle, kann aber bei mehreren Style-Änderungen umständlich sein.
style.cssText verwenden
Um mehrere Style-Änderungen effizient anzuwenden, nutzt man style.cssText:
<!-- snippet: html-result -->
<style>
#myParagraph {
padding: 5px;
width: 200px;
text-align: center;
}
</style>
<div id="myParagraph">Another paragraph.</div>
<script>
document.getElementById("myParagraph").style.cssText = "background-color: blue; font-size: 16px; border: 1px solid black";
</script>Dieser Ansatz fasst Style-Änderungen in einer einzigen Operation zusammen. Dabei ist zu beachten, dass cssText den gesamten Inline-Style ersetzt und alle bereits am Element gesetzten Eigenschaften löscht. Verwende es, wenn man einen sauberen Neuanfang möchte; verwende individuelle style.*-Zuweisungen, wenn man eine einzelne Eigenschaft ändern und den Rest unberührt lassen möchte.
Styles mit getComputedStyle auslesen
Die style-Eigenschaft spiegelt nur Inline-Styles wider — Werte, die im style-Attribut oder über JavaScript gesetzt wurden. Für alles, was aus einem Stylesheet stammt, gibt sie einen leeren string zurück. Um den endgültigen, aufgelösten Wert zu lesen, den der Browser tatsächlich gerendert hat (aus jedem Stylesheet, jeder Inline-Regel und jedem geerbten Wert), verwendet man getComputedStyle:
<!-- snippet: html-result -->
<style>
#box { width: 10em; padding: 5px; }
</style>
<div id="box">Measure me</div>
<script>
const box = document.getElementById("box");
const styles = getComputedStyle(box);
// Computed values are resolved to absolute units (px), not the "10em" we wrote:
console.log(styles.width); // "160px" (10em at the default 16px font size)
console.log(styles.padding); // "5px"
</script>Einige Regeln, die man im Kopf behalten sollte:
- Das zurückgegebene object ist schreibgeschützt — eine Zuweisung dazu hat keine Wirkung; zum Ändern von Styles verwendet man
element.style. - Werte sind aufgelöst: Längen werden in Pixeln zurückgegeben, Farben in der Form
rgb(...). - Immer eine spezifische Eigenschaft lesen (
getComputedStyle(el).marginTop) und den Langform-Namen bevorzugen — einige Kurzform-Eigenschaften (margin,padding) werden browserübergreifend inkonsistent zurückgegeben.
className vs. classList
Es gibt zwei Möglichkeiten, die Klassen eines Elements zu lesen und zu schreiben:
element.classNameist ein einzelner string, der das gesamteclass-Attribut enthält. Eine Zuweisung dazu ersetzt alle Klassen auf einmal:el.className = "active warning". Praktisch zum Setzen aller Klassen von Grund auf, aber umständlich, wenn man nur eine einzelne ändern möchte.element.classListist ein spezielles object mit Methoden für die Arbeit mit einzelnen Klassen —add,remove,toggle,containsundreplace. Dies ist die bevorzugte Wahl, weil man damit eine Klasse ändern kann, ohne die anderen zu beeinflussen.
Die Methoden sind:
| Methode | Was sie tut |
|---|---|
classList.add("a", "b") | Fügt eine oder mehrere Klassen hinzu (keine Aktion, wenn bereits vorhanden) |
classList.remove("a", "b") | Entfernt eine oder mehrere Klassen (keine Aktion, wenn nicht vorhanden) |
classList.toggle("a") | Fügt die Klasse hinzu, wenn sie fehlt; entfernt sie, wenn sie vorhanden ist |
classList.contains("a") | Gibt true/false zurück — hat das Element diese Klasse? |
classList.replace("old", "new") | Tauscht einen Klassennamen gegen einen anderen aus |
(Die Eigenschaft heißt className statt class, weil class ein reserviertes Wort in JavaScript ist — siehe Attributes and Properties.)
Klassen hinzufügen und entfernen
Die Verwendung der classList-API erleichtert die Klassenmanipulation erheblich.
Eine Klasse hinzufügen
<!-- snippet: html-result -->
<style>
.new-class {
font-weight: bold;
color: green;
}
</style>
<div id="myDiv">Class manipulation</div>
<script>
document.getElementById("myDiv").classList.add("new-class");
</script>Eine Klasse entfernen
<!-- snippet: html-result -->
<style>
.existing-class {
text-decoration: underline;
color: red;
}
</style>
<div id="myDiv" class="existing-class">Another manipulation example</div>
<script>
document.getElementById("myDiv").classList.remove("existing-class");
</script>Eine Klasse umschalten
Die Toggle-Funktion eignet sich gut zum Wechseln von Styles wie Themes:
<!-- snippet: html-result -->
<style>
.dark-mode {
background-color: black;
color: white;
}
</style>
<button id="toggleButton">Toggle Dark Mode</button>
<script>
document.getElementById("toggleButton").addEventListener("click", function() {
document.body.classList.toggle("dark-mode");
});
</script>Mehrere Klassen verwalten
Mehrere Klassen gleichzeitig verwalten:
<!-- snippet: html-result -->
<style>
.first-class { background-color: yellow; }
.second-class { border: 2px dashed blue; }
.third-class { display: none; }
.fourth-class { font-size: 14px; }
</style>
<div id="myDiv">Multiple class handling</div>
<script>
document.getElementById("myDiv").classList.add("first-class", "second-class");
document.getElementById("myDiv").classList.remove("third-class", "fourth-class");
</script>Klassen prüfen und ersetzen
Mit contains kann man prüfen, ob eine Klasse vorhanden ist, und mit replace lässt sich eine Klasse in einem einzigen Aufruf gegen eine andere tauschen:
const el = document.getElementById("myDiv");
el.classList.contains("active"); // false
el.classList.add("active");
el.classList.contains("active"); // true
// Swap "active" for "disabled" (returns true if the swap happened):
el.classList.replace("active", "disabled"); // true
el.classList.contains("active"); // false
el.classList.contains("disabled"); // truetoggle akzeptiert auch ein optionales zweites Argument, das das Ergebnis erzwingt: classList.toggle("open", isOpen) fügt die Klasse hinzu, wenn isOpen true ist, und entfernt sie, wenn es false ist — praktisch, wenn der gewünschte Zustand bereits als boolean vorliegt.
Best Practices: Klassen vs. Inline-Styles
Klassen gegenüber Inline-Styles bevorzugen. Das Styling im CSS belassen und JavaScript nur einen Klassennamen umschalten lassen. So bleiben Präsentation und Verhalten getrennt: Designer können das Erscheinungsbild ändern, ohne Scripts anzufassen, dieselbe Klasse kann für viele Elemente wiederverwendet werden, und die Styles verbleiben an einem durchsuchbaren Ort.
element.style sollte man nur verwenden, wenn ein Wert tatsächlich zur Laufzeit berechnet werden muss — eine Elementposition, die der Maus folgt, eine Breite, die aus Daten abgeleitet wird, eine Farbe, die aus einer Benutzereingabe stammt. Diese können nicht in einem statischen Stylesheet stehen, daher ist ein Inline-Wert das richtige Werkzeug.
Wenn eine Klassenänderung animiert statt abrupt erfolgen soll, definiert man einen CSS-transition auf der Eigenschaft und lässt das Umschalten der Klasse die Animation steuern. Der Browser übernimmt die Animation auf seinem eigenen optimierten Pfad, was flüssiger ist als das schrittweise Ändern von Werten aus JavaScript. Details dazu finden sich unter CSS Animations.
Fazit
classList (add, remove, toggle, contains, replace) zum Verwalten von Klassen verwenden und das Stylesheet die visuelle Arbeit erledigen lassen; element.style nur für Werte nutzen, die zur Laufzeit berechnet werden müssen; und endgültige, angewendete Werte mit getComputedStyle auslesen — dabei nicht vergessen, dass es schreibgeschützt ist. Wenn das Styling in CSS verbleibt und JavaScript lediglich Klassen umschaltet, entsteht Code, der leichter zu warten und schneller zu rendern ist.