JavaScript und CSS/Stylesheets dynamisch wechseln

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Im Artikel CSS-Eigenschaften setzen‎‎ wurde vorgestellt, wie Du Formatvorlagen ändern kannst, indem Du mit className oder classList Klassen hinzufügst, die dann andere Formatierungen haben.

Du kannst aber auch komplette Stylesheets wechseln. Abgesehen von der wenig bekannten (und nur vom Firefox unterstützten) Möglichkeit alternative Stylesheets im Browsermenü umzuschalten, kannst du dies auch direkt auf deiner Webseite mit einem kleinen Menü und JavaScript realisieren.

Achtung!

Hier geht es um ein proof-of-concept.

Heute würde man so einen Stylesheet-Wechsler mit einer prefers-color-scheme oder prefers-contrast-Medienabfrage ohne JavaScript realisieren. Moderne Beispiele findest Du unten unter Siehe auch.

--Matthias Scharwies (Diskussion) 08:13, 3. Aug. 2022 (CEST)

Es gibt verschiedene Gründe für alternative Stylesheets. Das kann rein ästhetische Gründe haben, aber auch höhere Kontraste und größere Schriftgrößen für eingeschränkt sehfähige Benutzer anbieten. So stellt caniuse.com ein alternatives Layout mit zugänglichen Farben zur Verfügung.

Screenshot


Anwendungsbeispiel

Stylesheets einbinden

Normalerweise sind die Stilvorgaben einer Webseite in einem separaten Stylesheet notiert, das dann mit einem link-Element referenziert wird.

Einbindung eines Stylesheets
<link rel="stylesheet" type="text/css" href="styles/layout.css" title="Grundlayout">


Einbindung mehrerer Stylesheets
<link rel="stylesheet" type="text/css" href="styles/standard.css" title="Grundlayout">
<link rel="alternate stylesheet" type="text/css" href="styles/klassisch.css" title="klassisch"> 
<link rel="alternate stylesheet" type="text/css" href="styles/kontrast.css" title="schwarz-weiß">

Stylewechsel

Durch einen Klick auf einen Button soll ein anderes Stylesheet geladen werden.

Auswahlmenü
<aside>
  <h2>Ansicht ändern</h2>
  <button data-stylesheet="./styles/standard.css">Standard</button>
  <button data-stylesheet="./styles/klassisch.css">klassisch</button>
  <button data-stylesheet="./styles/kontrast.css">kontrast</button>
</aside>

Für dieses Beispiel wurden Buttons ausgewählt. Sie haben data-Attribute, deren Werte den möglichen Stylesheets entsprechen. Du kannst Stylesheets aber auch über ein select-Menü oder einen Link (wie bei Caniuse) auswählen.


Durch einen Klick auf einen dieser Button wird jetzt das Stylesheet ausgetauscht.

Einbindung eines Stylesheets
  var currentSheet = document.getElementById("stylesheet"),
  switcher = document.getElementById("styleswitcher");

  function loadStyle () {
    currentSheet.href = stylez;
  }

  switcher.addEventListener("click", function (ev) {
    var b = ev.target; // button

    if (b && b.hasAttribute("data-stylesheet")) {
      stylez = b.getAttribute("data-stylesheet");
    } 

    loadStyle();
  });

Mit einem Klick auf den Styleswitcher wird überprüft, ob das geklickte Element ein data-Attribut hat. Falls ja, wird der Wert des data-Attributs der Variable stylez zugewiesen. In der Funktion loadStyle() wird die Variable nun dem href-Attribut des Stylesheets zugewiesen und entsprechend geladen.

Änderungen speichern

Das Stylesheet lässt sich dynamisch umschalten – eventuelle Eingaben sind aber bei einem Neuaufruf der Seite verloren. Du kannst die ausgewählten Werte in einem Cookie speichern. Hier wird aber die moderne und bequemere Alternative der Web Storage API verwendet.

Speichern und Auslesen der ausgewählten Stylesheets ansehen …
(function () {
  document.addEventListener("DOMContentLoaded", function () {

    var currentSheet = document.getElementById("stylesheet"),
        switcher = document.getElementById("styleswitcher");

    function loadStyle () {
      if (localStorage.getItem("stylez")) {
        currentSheet.href = localStorage.getItem("stylez");
      }
    }

    // only continue if required elements are present
    if (currentSheet && switcher) {

      // set previously stored stylesheet?
      loadStyle();

      // listen for clicks on buttons
      switcher.addEventListener("click", function (ev) {
        var b = ev.target; // button

        if (b && b.hasAttribute("data-stylesheet")) {

          // save value
          localStorage.setItem(
            "stylez",
            b.getAttribute("data-stylesheet")
          );

          loadStyle();
        }
      });
    }
  });
}());
Die in der Variablen stylez gespeicherten Werte der data-Attribute werden mit localStorage.setItem(Schlüssel, Wert) gespeichert:
localStorage.setItem(
  "stylez",
  b.getAttribute("data-stylesheet")
);
und anschließend mit localStorage.getItem(Schlüssel, Wert) wieder ausgelesen.
Beachte: Genau wie bei Cookies werden die Daten der Web Storage API in den Verzeichnissen der einzelnen Browser gespeichert. Sie gelten also nur für den Computer und den Browser, mit dem diese Änderungen vorgenommen werden. Ansonsten müssten diese Einstellungen serverseitig gespeichert werden.

Variante mit dynamisch erzeugtem Menü

In dieser Variante erscheinen das aside-Element und die buttons aber nicht im regulären Markup, sondern werden nur dann dynamisch erzeugt, wenn JavaScript aktiviert ist. Denn auch die Stylesheets können nur dynamisch gewechselt werden, wenn Javascript aktiviert ist. Nutzer ohne JavaScript erhalten kein für sie funktionsloses Menü.


Wechseln der Stylesheets - dynamisches Menü
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" type="text/css" href="styles/standard.css">
  <link rel="alternate stylesheet" type="text/css" href="styles/klassisch.css" title="klassisch">
  <link rel="alternate stylesheet" type="text/css" href="styles/kontrast.css" title="kontrast">
  <script>
(function () {
  document.addEventListener("DOMContentLoaded", function () {

    var main = document.querySelector("main:first-of-type"),
        l, s,
        stylez = [];

    // do we have alternate stylesheets?
    [].slice.call(
      document.querySelectorAll('link[rel]:not([href*="Beispiel:"])')
    ).forEach (function (el) {

      stylez.push(el); // save node

      if (el.rel.match(/^stylesheet$/i)) {

        // keep standard stylesheet
        l = el;

      } else {

        // remove any alternative stylesheets
        el.parentNode.removeChild(el);
      }
    });

    if (stylez.length > 0) {

      // create style switcher
      s = document.createElement("aside");
      s.innerHTML = "<h2>Ansicht ändern</h2>";

      main.insertBefore(s, main.firstChild);

      // create buttons
      stylez.forEach(function (el) {
        var b = document.createElement("button");

        b.setAttribute("data-stylesheet", el.href);

        if (el.title) {
          b.textContent = el.title;
        }

        if (el === l) {
          b.textContent = "Standard";
        }

        s.appendChild(b);
      });
    }

    function loadStyle () {
      if (localStorage.getItem("stylez")) {
        l.href = localStorage.getItem("stylez");
      }
    }

    // only continue if required elements are present
    if (l && s) {

      // set previously stored stylesheet?
      loadStyle();

      // listen for clicks on buttons
      s.addEventListener("click", function (ev) {
        var b = ev.target; // button

        if (b && b.hasAttribute("data-stylesheet")) {

          // save value
          localStorage.setItem(
            "stylez",
            b.getAttribute("data-stylesheet")
          );

          loadStyle();
        }
      });
    }
  });
}());
  </script>
  <title>Stylesheets dynamisch wechseln</title>
</head>
<body>
  <h1>Stylesheets dynamisch wechseln</h1>
  <main>
  </main>
</body>
</html>

Das Beispiel überprüft in einer forEach-Schleife, ob es alternative Stylesheets gibt und erzeugt für jedes dynamisch einen Button.


Siehe auch

Vorschau-garten.gif CSS-Garten

Eine auf dem HTML-Grundgerüst und dem Seitenstrukturierungs-Tutorial aufbauende übersichtliche Webseite, die mit neun verschiedenen Layouts ausgeliefert wird.

Vorschau-01.png Dark Mode
mit prefers-color-scheme die Wünsche und Einstellungen der Nutzer abfragen
Diese Seite bietet ein helles und ein dunkles Theme
Vorschau-02-ani.gif Design Nr. 02

Eine poppige Seite im 3-Spalten-Layout mit einem auffälligen Header.

Mit einigen wenigen Handgriffen kann das Theme der Seite farblich angepasst werden.

Vorschau-Visitenkarte.gif Visitenkarte

Ein eleganter OnePager als Landing Page oder Portfolio für eine Bewerbung. Natürlich responsiv und mit allem drin!

Weblinks