JavaScript und CSS/CSS-Eigenschaften setzen

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Dieses Tutorial zeigt, wie du mit JavaScript die Darstellung des Dokuments dynamisch ändern kannst, während es im Browser angezeigt wird: Beispielsweise kannst du als Reaktion auf eine Benutzereingabe gewisse Elemente ein- oder ausblenden.

Aufden ersten Blick erreicht man dies mit der Direktformatierung des style-Objekts, die im 1. Kapitel vorgestellt wird. Heute verwendet man aber bessere Techniken, die im 2. Kapitel mit Live-Beispielen präsentiert werden.

Direktformatierung

Elemente ausblenden

Wenn Du ein Element mit JavaScript ein- oder ausblenden möchtest, ist es am einfachsten und effektivsten das hidden-Attribut zu setzen oder zu entfernen. JavaScript steuert indirekt, und damit der Trennung der Schichten von Inhalt, Layout und Verhalten folgend, das Aussehen dieses Elements – und seiner Nachfahren oder Geschwister.

  if (username && password) {
    document.getElementById("loginForm").hidden = true;
    console.log("User logged in successfully!");
  } else {
    alert.textContent = "Please enter username and password!";
  }
}

In diesem Beispiel wird bei angemeldeten Nutzern die hidden-Eigenschaft des loginForm-Anmeldeformulars gesetzt und das Anmeldeformular ausgeblendet..

Der Clou dieser Vorgehensweise ist, dass mit dem Setzen des Attributs nur eine minimale Änderung am DOM vorgenommen wird.

Inline-Styles

Um direkt einzelne HTML-Elemente mit CSS zu formatieren, existiert das style-Attribut, welches eine Liste von Eigenschafts-Wert-Zuweisungen enthält.

Ein HTML-Beispiel:

Beispiel
<p style="color: red; background-color: yellow; font-weight: bold;">Fehler</p>
Beachte: Gegenüber dem Einsatz von zentralen Formaten in Stylesheets sind diese sogenannten Inline-Styles (eingebettete Formatierungen) ineffektiv und führen zu einer Vermischung von HTML und CSS, die die Wartbarkeit des Dokuments verschlechtert. Du solltest sie daher nur in Ausnahmefällen einsetzen, auf die wir später noch zu sprechen kommen.

Das style-Objekt als Schnittstelle zu Inline-Styles

JavaScript bietet eine Schnittstelle zu diesem style-Attribut:

Mit der style-Eigenschaft von HTMLElement, SVGElement und MathMLElement kann man den inline-Style eines Elements setzen oder auslesen.[1] Die Eigenschaft liefert ein CSSStyleDeclaration-Objekt, das den Inhalt des style-Attributs des Elements repräsentiert und in dem du Eigenschaften hinzufügen, ändern und entfernen kannst.[2] Der Wert des style-Attributes ändert sich synchron dazu. Das Ergebnis kann durch die Entwicklertools als Änderung im style-Attribut des entsprechenden Elements untersucht werden.

Syntax

let wert = element.style.eigenschaft;

element.style.eigenschaft = 'wert';

  • element: HTML-, SVG- oder MathML-Element
  • eigenschaft: CSS-Eigenschaft
  • wert: Wert als Zeichenkette, die deshalb in einfachen oder doppelten Anführungszeichen gesetzt werden muss.

Das style-Objekt hat für jede mögliche CSS-Eigenschaft eine entsprechende les- und schreibbare Objekteigenschaft. Zu der CSS-Eigenschaft color existiert also eine Objekteigenschaft element.style.color vom Type String.

Setzen von Text- und Hintergrundfarbe
document.getElementById('beispielID').style.color = 'darkred';
document.getElementById('beispielID').style.backgroundColor = 'pink';

Als Werte musst du stets Strings angeben. genau in der Form, wie sie in CSS spezifiziert sind. Das gilt auch für Zahlenwerte, die eine Einheit erfordern:

CSS-Werte immer mit dazugehörenden Einheiten
element.style.marginTop = 15; // Falsch!
element.style.marginTop = '15px'; // Richtig
Beachte: CamelCase statt Bindestriche!
CSS-Eigenschaftsnamen mit Bindestrichen, wie z. B. background-color, können nicht unverändert als JavaScript-Eigenschaftsnamen übernommen werden. Deshalb werden sie im sogenannten CamelCase notiert: Der Bindestrich fällt weg, dafür wird der darauf folgende Buchstabe zu einem Großbuchstaben. Aus background-color wird also backgroundColor, aus border-left-width wird borderLeftWidth und so weiter. Die Großbuchstaben in der Wortmitte werden mit den Höckern eines Kamels verglichen.
Beachte: Abweichungen vom besagten Schema:
Wenn Du die CSS-Eigenschaft float mit JavaScript ändern willst, musst du den Begriff cssFloat verwenden, da float ein Reserviertes Wort ist.

Anwendungsbeispiele

Farbwähler

Farbauswähler ansehen …
  <h2>Vordergrund (Schriftfarbe)</h2>
  <form action="#">
    <input type="color" name="text" value="#3983ab">
  </form>
  <h2>Hintergrund</h2>
  <form action="#">
    <input type="color" name="background" value="#ffffff">
  </form>  
  
  <output>
  </output>
Der Farbwähler besteht aus zwei Eingabefeldern. Daneben gibt es ein output-Element für die Ergebnisausgabe.
document.addEventListener("DOMContentLoaded", function () {   
  	 document.querySelector('[name="text"]').addEventListener('change', changeStyle);
  	 document.querySelector('[name="background"]').addEventListener('change', changeStyle);	 

function changeStyle() {
	var output = document.querySelector('output');	
	output.style.color = document.querySelector('[name="text"]').value;
	output.style.backgroundColor = document.querySelector('[name="background"]').value;		
}
});

Sobald etwas eingegeben wird, feuert der change-Event und die eingegebenen Werte werden mit Element.style im output-Element ausgegeben.

Überholt: Animationen

Früher wurden Elemente animiert, indem die Werte von Element.style laufend dynamisch verändert wurden. Dies geht heute mit der Web Animations API und Element.animate(), die CSS-Eigenschaften direkt animiert, besser:

element.animate() - Array von Objekten
element.animate([
  {transform: 'translate(  0px)', color: 'black'},
  {transform: 'translate(100px)', color: 'red'},
  {transform: 'translate(  0px)', color: 'black'},
  ], {
    duration: 1000,               // Zeit in Ms,
    iterations: Infinity,         // Wiederholungen (hier unendlich)
    delay: 300                    // Verzögerung
});

Überholt: Stylewechsler

In der Vergangenheit wurde Element.style dazu missbraucht, HTML-Dokumente zu formatieren.

Veraltet: Setzen von style-Eigenschaften ansehen …
function changeCSS () {
    for (var i = 0, p = document.getElementsByTagName("p"); i < p.length; i++) {
        p[i].style.border = "5px solid #c32e04";
	p[i].style.borderRadius = "10px";
        p[i].style.backgroundColor = "#dfac20";
        p[i].style.color = "#3983ab";
        p[i].style.fontSize = "200%";
    }
}

Das Beispiel enthält drei Textabsätze. Durch Anklicken des Buttons wird die Funktion changeCSS() aufgerufen. Zunächst werden mit document.getElementsByTagName("p") alle p-Elemente des Dokuments ermittelt und in einem Array gespeichert. Anschließend wird in einer for-Schleife der Reihe nach auf alle p-Elemente zugegriffen.

p[i].stylespricht die style-Eigenschaft an. Dahinter folgt die gewünschte CSS-Eigenschaft, ebenfalls durch einen Punkt-Operator abgetrennt. Dieser wird jeweils ein gültiger Wert zugewiesen.

Dieses Beispiel lässt sich heute viel kürzer und übersichtlicher realisieren:

Aktuell: Ändern von Klassen ansehen …
function changeCSS () {
	let paragraphs = document.querySelectorAll('p').forEach(function(elem) {
		elem.classList.add('hervorhebung');
	})
}

Mit querySelectorAll werden alle Absätze selektiert und in einer live nodelist hinterlegt.
In einer Schleife wird diesen Elementen nun mit classList.add die Klasse hervorhebung gegeben.


Fazit: Sinnvoller Einsatz des style-Objektes

Das Setzen von CSS-Formatierungen direkt über das style-Objekt scheint (oberflächlich betrachtet) sehr einfach. Dennoch solltest du diese Präsentationsregeln nicht im JavaScript, sondern z. B. in einer Klasse im Stylesheet unterbringen.

Nur in manchen Fällen ist die Verwendung von Inline-Styles notwendig: Wenn der Eigenschaftswert nicht fest steht, sondern erst im JavaScript berechnet wird. Das ist der Fall z. B. bei Animationen, zur Kollisionserkennung bei Spielen (obwohl man dort eher Canvas verwenden würde) oder bei einer Positionierung abhängig von der Mauszeiger-Position wie beim Drag-and-Drop.

Empfehlung: Trenne konsequent Markup (HTML), Präsentation (CSS) und Verhalten (JavaScript). Alle Angaben zur Darstellung sollten via CSS erfolgen. Bei Bedarf ändere lediglich die Klassenzugehörigkeit der entsprechenden Elemente mithilfe der JavaScript-Eigenschaften Verzichte auf das direkte Setzen von CSS-Eigenschaften mit JavaScript, wie es in den oberen Beispielen vorgestellt wurde.


Mit Element.style können nur CSS-Eigenschaften abgefragt werden, die im HTML-Quelltext im style-Attribut notiert sind oder per JavaScript im style-Objekt gesetzt wurden.

Um auszulesen, welche Eigenschaften für ein Element aktuell gelten, muss anders vorgegangen werden.

Hauptartikel: JavaScript und CSS/CSS-Eigenschaften auslesen

Nutzung von Klassen in Stylesheets

Wenn Du das Aussehen eines Elements mit JavaScript ändern möchtest, ist es am einfachsten und effektivsten eine Klasse zu setzen oder zu entfernen. JavaScript steuert indirekt, und damit der Trennung der Schichten von Inhalt, Layout und Verhalten folgend, das Aussehen dieses Elements – und seiner Nachfahren oder Geschwister.

Der Clou dieser Vorgehensweise ist, dass mit dem Setzen der Klasse an einem Element nur eine minimale Änderung am DOM vorgenommen wird. Diese Änderung führt dazu, dass eine Regel aus dem Stylesheet plötzlich auf bestimmte Elemente greift – der Browser wendet daraufhin automatisch die definierten Formatierungen an.

className und classList

Um nun einem Element eine Klasse zuzuweisen oder wieder zu entfernen, gibt es – auch wieder aus historischen Gründen – zweierlei Möglichkeiten:

  1. className – einfach zu nutzen bei nur einer Klasse
  2. classList – bequem zu nutzen, vor allem bei mehrfacher Klassenzuweisung

Die Eigenschaft className entspricht in etwa dem class-Attribut im HTML-Quelltext. Dieses Attribut kann, durch Leerzeichen getrennt, verschiedene Klassen enthalten. Das Manipulieren der className-Eigenschaft ist aber genau dann mühsam, wenn man mit mehreren Klassen hantieren muss.

einfache Klassenzuweisung in JavaScript
// body die Klasse "js-enabled" geben
document.body.className = "js-enabled"; // entspricht <body class="js-enabled">
document.body.classList.add("js-enabled");

// body nun die Klasse "js-enabled" wieder wegnehmen:
document.body.className = ""; // entspricht <body class="">
document.body.classList.remove("js-enabled");

Das body-Element wird der Klasse js-enabled zugeordnet. Beispielhaft geschieht dies doppelt, sowohl mit className als auch mit classList. Die Methoden add und remove prüfen, ob eine Klasse dieses Namens bereits vorhanden ist. Daher wird mit classList.add die Klasse js-enabled nicht doppelt vergeben.

Die Vorteile von classList werden ganz schnell deutlich, wenn mit mehreren Klassen hantiert werden muss:

mehrfache Klassenzuweisung in JavaScript
// body die Klassen "js-enabled" und "unconfirmed" geben
document.body.className = 'js-enabled unconfirmed'; // entspricht <body class="js-enabled unconfirmed">
document.body.classList.add('js-enabled', 'unconfirmed');

// body nur die Klasse "unconfirmed" wieder wegnehmen:
document.body.className = document.body.className.replace(/\b?unconfirmed/, '');
document.body.classList.remove('unconfirmed');

Um mit className die Klasse unconfirmed zu entfernen, muss eine Stringoperation durchgeführt werden, welche hier mit String.replace unter Zuhilfenahme eines regulären Ausdrucks geschieht. Mit den Methoden von classList ist diese „Handarbeit“ nicht mehr notwendig.

Schalterklasse für viele Elemente

Wenn die zu ändernde Klasse bei vielen Elementen hinterlegt ist und du nicht alle Elemente einzeln aufsuchen willst, kannst du dem body eine "Schalterklasse" wie mode-1 und mode-2 geben und im Stylesheet Regeln pro Mode in dieser Art festlegen:

.mode-1 .klasse1 {
   ... einstellungen
}
.mode-2 .klasse1 {
   ... einstellungen
}

Auf diese Weise ändern alle Elemente mit Klasse "klasse1" ihre Styles, sobald am body die mode-Klasse geändert wird.[3]

Nehmen wir einmal an, wir wollten einen Lückentext gestalten, bei dem die Lücken auf Knopfdruck sichtbar werden sollen. Dazu bräuchten wir ein passendes Element (z. B. span), welches die Wörter enthält, die später zu Lücken werden sollen. Außerdem bräuchten wir eine Darstellungsregel, die den Inhalt unsichtbar macht, wohl aber die Lücken als solche kennzeichnet. Zu guter Letzt bräuchte es eine Klasse, die dafür sorgt, dass die ausgeblendeten Wörter wieder dargestellt werden.

Betrachten wir zuerst den CSS-Teil:

Darstellungsregeln für Lückentext
span {
  visibility: hidden;
}

.spoil span {
  visibility: visible;
}

Die CSS-Eigenschaft visibility macht die Inhalte von span-Elementen unsichtbar. Diese Unsichtbarkeit wird bei den span-Elementen wieder aufgehoben, die sich in einem Element befinden, welches entweder selbst die Klasse spoil hat, oder ein Nachfahre eines solchen Elements ist.

Der JavaScript-Teil tut im Wesentlichen nichts anderes, als dem body-Element die Klasse spoil hinzuzufügen, oder zu entfernen:

JavaScript für Lückentext
(function () {
  document.addEventListener("DOMContentLoaded", function () {
    var spoil = document.getElementById("spoil"),
        className = "spoil";

    if (spoil) {
      spoil.addEventListener("click", function () {
        document.body.classList.toggle(className);
      });
    }
  });
}());

Das Script selbst sitzt in einer sofort ausgeführten Funktion, die selbst eine (anonyme) Funktion definiert, welche genau dann ausgeführt werden soll, wenn das HTML-Dokument vollständig geladen wurde. In dieser anonymen Funktion wird nach einem Element mit der ID spoil gesucht, einem button zum Hin- und Herschalten. Die Funktion, die beim Anklicken des Buttons aktiv wird, fügt entweder die Klasse spoil dem body hinzu oder entfernt sie wieder, wofür classList die Methode toggle kennt.

Nun haben wir die wesentlichen Bausteine für den Lückentext zusammen. Mit CSS sorgen wir dafür, dass die Inhalte ausgeblendet und somit Lücken geschaffen werden. Mit JavaScript schalten wir zwischen Rätsel- und Lösungsansicht hin und her. Hier nun eine fertige Rätselseite:

Rätselseite mit Lückentext ansehen …
<button data-on="einblenden." data-off="ausblenden." id="spoil"></button>
button {
  display: block;
  margin: 0 auto;
}

button::after {
  content: attr(data-on);
}

.spoil button::after {
  content: attr(data-off);
}

Damit die Beschriftung des Klickbuttons sich passend mitändert, wurden die notwendigen Beschriftungen als data-Attribute notiert. In HTML5 können Sie jederzeit solche Attribute notieren, um sie z. B. als CSS-generierten Inhalt zu nutzen.


Siehe auch:

custom properties

In HTML5 ist es möglich, im Stylesheet neben den „normalen“ Eigenschaften zusätzlich CSS-Variablen zu deklarieren, die dann in mehreren Regelsätzen aufgerufen werden können.

Sie sind wie die im Style-Objekt festgelegten Eigenschaften Teil des CSSStyleDeclaration-Objekts, lassen sich aber nur mt den (auch für „“normale Eigenschaften anwendbaren) Methoden

CSS-Variablen mit setProperty() setzen

CSSStyleDeclaration.setProperty() setzt einen neuen Wert für eine Eigenschaft eines CSS-Stildeklarationsobjekts.[4]

Syntax

setProperty(Eigenschaftsname, Wert)
setProperty(Eigenschaftsname, Wert, Priorität)
Eigenschaftsname
Eine Zeichenfolge, die den Namen der zu ändernden CSS-Eigenschaft (Groß- und Kleinschreibung) darstellt.
Wert( Optional)
Eine Zeichenfolge, die den neuen Eigenschaftswert enthält. Wenn nicht angegeben, wird sie als leere Zeichenkette behandelt.
Priorität (Optional)
Eine Zeichenkette, mit der die CSS-Priorität "important" festgelegt werden kann. Wird sie nicht angegeben, wird sie als leere Zeichenkette behandelt. Die folgenden Werte werden akzeptiert:
String-Wert "important"
Schlüsselwort undefined
Zeichenkette leerer Wert ""

Im Tutorial "Einstieg in SVG" gibt es eine mit CSS-Animation angetriebene SVG-Uhr. Damit sie die aktuelle Uhrzeit anzeigt, wird mittels setProperty() die aktuelle Zeit den CSS-Variablen zugewiesen.

Setzen von CSS-Variablen mit JavaScript ansehen …
document.addEventListener('DOMContentLoaded', function () {
	  
  const svg = document.querySelector('svg'),
        currentTime = new Date();

  svg.style.setProperty('--start-seconds', currentTime.getSeconds());
  svg.style.setProperty('--start-minutes', currentTime.getMinutes());
  svg.style.setProperty('--start-hours', currentTime.getHours() % 12);
});

Das Script enthält einen Eventlistener, der nach dem Laden der Webseite mit new Date() ein neues Datumsobjekt mit der aktuellen Zeit (engl. currentTime) erzeugt.

Mittels style.setProperty() wird dann die aktuelle Zeit den CSS-Variablen zugewiesen.

Hauptartikel: SVG-Uhr

CSS-Variablen mit getPropertyValue() auslesen

Die Methodenschnittstelle CSSStyleDeclaration.getPropertyValue() gibt einen String zurück, der den Wert einer angegebenen CSS-Eigenschaft enthält.[5]

Syntax

getPropertyValue(Eigenschaft)

Parameter:

Eigenschaft
Eine Zeichenkette, die den Namen der zu prüfenden Eigenschaft (mit Bindestrich) darstellt.
Rückgabewert
Eine Zeichenkette, die den Wert der Eigenschaft enthält. Falls nicht gesetzt, wird die leere Zeichenkette zurückgegeben.

Siehe auch

In diesem Beispiel im nächsten Kapitel werden die berechneten Werte der Textgröße mit getPropertyValue() ausgegeben.

Siehe auch

  • CSS-Eigenschaften auslesen
    Box-Modell.svg
  • Custom properties
    (CSS-Variablen)
    var(--)

Weblinks

  1. MDN: Element.style
  2. MDN: CSSStyleDeclaration
  3. SELF-Forum: Eigenschaften in CSS-Klassen mit JavaScript ändern vom 21.06.2020
  4. MDN: CSSStyleDeclaration: setProperty() method
  5. MDN: CSSStyleDeclaration: getPropertyValue() method