CSS, HTML und Javascript mit {stil}

DOM insertRule, removeRule

Style insertRule removeRule – übersichtlicher als lange style-Strings

Das Ändern des style-Attributs ist eine der Hauptaufgaben von Javascript. Anstelle von wiederholten Queries und Änderungen des style-Attributs ist das Einfügen, Entfernen oder Deaktivieren von style-Elementen effizienter.

insertRule und removeRule fügen neue CSS-Stile in ein style-Element ein und entfernen sie wieder. Das Verfahren ist übersichtlicher als lange Strings in das style-Attribut von HTML-Elementen einzufügen.

document.createElement erzeugt <style>-Elemente on the fly, nicht anders als das Erzeugen von Elementen im body des Dokuments. Hier z.B. ermittelt ein Script die Höhe von Blöcken für einen Accordeon-Effekt.

HERZLICH
DSC07390-300

Caramels gummies toffee sesame snaps chupa chups candy jelly beans.

Occelli
DSC05777-300

Cake dessert candy canes marzipan chocolate cake cupcake. Lemon drops toffee jelly tootsie roll jelly carrot cake cheesecake. Tootsie roll candy canes candy. Jelly-o cotton candy pastry jelly gingerbread.

Tartufo
DSC09079-300

Tart lollipop liquorice sugar plum. Candy canes caramels lemon drops icing wafer chocolate cake lemon drops chocolate.

Süßer Morgen
DSC07230-300

Pastry caramels lemon drops gummies. Gingerbread croissant biscuit ice cream.

Stylesheet mit Javascript erzeugen

Statt alle Blöcke immer wieder mit setAttribute() und removeAttribute() zu ändern, initialisiert ein dynamisch erzeugtes Style-Element alle Blöcke.

Zuerst: Das höchste Accordion-Element heraussuchen, damit alle Ebenen des Accordion-Effekts dieselbe Höhe haben:

var style = document.createElement("style");
document.head.appendChild(style);
style.type="text/css";

var tallest = 0;
for (var i=0; i< box.length; i++) {
   var height = box[i].clientHeight;
   tallest = height > tallest ? height : tallest;
}

insertRule / addRule

Stylesheets haben eine Methode insertRule, die CSS-Regeln auf dieselbe Weise einfügt wie die Notation in der CSS-Datei oder in style-Tags.

Gegenüber CSS im style-Attribut setzt ein dynamisches insertRule auch gleich Breakpoints und verzweigt das CSS im style-Tag mit der @supports-Regel.

// stylesheet.insertRule(rule, index);

style.sheet.insertRule("ul { height: 0; overflow:hidden; transition: height 1s; }", 0 );
style.sheet.insertRule(".toggle { height: " + tallest + "px; overflow:visible; }", 1 );

Das zweite Argument ist der Index, an dem die Regel eingefügt wird. Per Vorgabe werden neue Regeln am Ende des Stylesheets eingefügt, aber der Parameter muss trotzdem immer gesetzt werden. Der Index darf nicht größer sein als die Zahl der Regeln im Style-Element und reagiert ausgesprochen sensibel, wenn der Index außer Kontrolle gerät.

IndexSizeError: DOM Exception 1: Index or size was negative, or greater than the allowed value.

insertRule wurde von IE9 noch nicht unterstützt. In IE9 wirkte noch addRule() (das wiederum von Firefox nicht unterstützt wird und obendrein kein Standard ist). Wer IE9 unbedingt noch versorgt will:

function addCSSRule(sheet, selector, rules, index) {
   if ("insertRule" in sheet) {
      sheet.insertRule(selector + "{" + rules + "}", index);
   } else if ("addRule" in sheet) {
      sheet.addRule(selector, rules, index);
   }
}

addCSSRule (style.sheet, "#nav_menu ul", "height: 0; overflow:hidden; transition: height 1s;", 0);
addCSSRule (style.sheet, ".toggle", "height: " + tallest + "px !IMPORTANT; overflow:visible !IMPORTANT;", 0);

Mit einer äquivalenten Methoden werden CSS-Regeln aus dem Stylesheet entfernt:

stylesheet.removeRule(i) // moderne Browser 
stylesheet.deleteRule(i) // IE9

Statt über alle Elemente zu iterieren, kann die CSS-Klasse toggle direkt aus einem Element mit classList.remove('toggle') entfernt werden, wenn ein neues Element im Accordion aktiviert wird.

for (var i=0; i<h.length; i++) {
   h[i].onclick = function () {
      document.querySelector('.toggle').classList.remove('toggle');
      this.nextElementSibling.classList.add('toggle');
   }
}

Regeln für Media Queries einfügen

Nicht nur die volle Breite der Selektoren, sondern auch Media Queries können in dynamisch erzeugten Stylesheets eingesetzt werden. Das funktioniert mit insertRule:

sheet.insertRule("@media only screen and (max-width:1260px) { .accordion { max-width:480px } }");

styleSheets auflisten

Das styleSheet-Objekt enthält alle externen Stylesheets der Seite – sowohl Styleheets, die mit <style> notiert sind als auch diejenigen, die mit <link rel="stylesheet"> eingebunden sind.

document.styleSheets gibt eine Liste der Stylesheets der Webseite zurück. Die Liste kann nicht geändert werden, aber document.styleSheets kann einzelne Stylesheets deaktivieren.

Der Rückgabewert von document.styleSheets sieht aus wie ein Array, ist aber eine nodeList. Der Zugriff erfolgt über den Index.

var sheets = document.styleSheets;
var len = sheets.length; 
for (var i=0; i<len; i++) {
    console.log(document.styleSheets[i]);
}

sheets[0] ist das erste styleSheet im Dokument, das durch ein link- oder style-Element eingebunden ist. sheets.length ist die Anzahl der styleSheets.

    Die Eigenschaften der styleSheets (type, disabled, title, media, href, ownerDocument, parentStyleSheet) liefern weitere Informationen. Bis auf disabled können alle Eigenschaften nur gelesen werden.

    Der Zugriff auf die geladenen styleSheets kann auch durch die DOM Core-Methoden document.getElementsByTagName('style') und document.getElementsByTagName('link') erfolgen. Dann können die Attribute title, href, media, … durch setAttribte() geändert werden.

    var firstSheet = document.getElementsByTagName('style')[0].sheet;
    var owner = document.styleSheets[0].ownerNode;
    

    stylesheets disabled

    disabled ist ein boole'scher Wert und gibt an, ob ein styleSheet in Kraft ist (disabled = false) oder nicht. Default ist false.

    <link rel="stylesheet" href="dom-stylesheets.css" title="extra" />
    
    var sheets = document.styleSheets;
    var len = sheets.length;
    for (var i=0; i<len; i++) {
       if (sheets[i].title && sheets[i].title == 'extra') {
          sheets[i].disabled = true;
       }
    }
    

    styleSheets identifizieren

    Das styleSheet-Objekt unterstützt nur den Zugriff durch den Index, also über die Position des styleSheets im Dokument. Zur Identifikation kann aber auch die href-Eigenschaft herangezogen werden, wenn das Stylesheet durch ein <link>-Tag in das Dokument eingebunden wurde oder das title-Attribut (sofern title gesetzt ist und die title-Attribute eindeutig sind).

    Ein gleichlautendes title-Attribut erlaubt das Zusammenfassen von zwei oder mehr Style Sheets zu einer Gruppe, die gemeinsam außer Kraft gesetzt oder deaktiviert werden können.

    Weitere Eigenschaften von styleSheets

    ownerNode
    gibt einen Verweis auf den Knoten zurück, der das aktuelle styleSheet enthält. Gibt in regulären HTML-Seiten i.d.R. ein LINK- oder STYLE-Element zurück. In XML-Dokumenten kann dies die linkende ProcessingInstruction sein.
    parentStyleSheet
    Verweis auf das Top-Level-Stylesheet bei Style Sheets, die durch die @page-Regel eingebunden sind. Bei Style Sheets, die durch LINK- oder STYLE eingebunden sind, wird null zurückgegeben.
    media
    Gibt das media-Objekt des styleSheets als Liste zurück. Die Eigenschaft mediaText gibt den Medientyp als String zurück. Default ist screen.
    {} insertRule removeRule