Lerne Coding
CSS Houdini bringt die Magie in CSS
21.04.2020

CSS Houdini - CSS bekommt Magie!

Inhaltsverzeichnis
[[TABLE OF CONTENTS]]
access_timeGeschätzte Lesezeit ca. Minuten

Houdini ist der Schlüssel zwischen JavaScript und CSS. Ich will dir nun eine Erklärung liefern was CSS Houdini ist und erste Beispiele zeigen. Es werden einige neue APIs kommen, um neue CSS-Eigenschaften zu registrieren - und zwar über JavaScript. Diese können dann direkt in CSS verwendet werden. Anzumerken ist, dass Houdini selbst nicht der Titel der API ist. Unter Houdini verbergen sich verschiedene APIs, um das CSSOM anzusprechen (CSS Object Model). 

Folgende API's soll Houdini beinhalten:

  • Layout API
  • Paint API
  • Parser API
  • Properties & Values API
  • AnimationWorklet
  • Typed OM (CSS Typed Object Model)
  • Font Metrics API

Der Browser Support für die Paint API ist noch nicht vollständig vorhanden. Firefox hat noch keinen Support für eines der Features. Edge ab 79, Chrome ab 65 und Opera ab 52 sind bereits mit der Paint API ausgestattet. Allerdings muss zum jetzigen Zeitpunkt das Ganze immer noch als Experiment betrachtet werden. Selbst bei der Recherche für den Artikel habe ich hin und wieder Elemente gefunden, die trotz der aktivierten Flags für die neuen Features nicht korrekt funktioniert haben.

Eine ausführliche Ansicht über aktuell laufende und noch nicht laufende Funktionen findest du auf der Webseite von "Is Houdini ready yet‽" unter https://ishoudinireadyyet.com/

Beim Chrome Dev Summit 2019 wurde von Una Kravets ein kleiner Ausschnitt von Houdini gezeigt, welcher sehr interessant ist. Der Ausschnitt wurde bereits 2018 einmal erwähnt. In dem Video wird Houdini noch einmal sehr anschaulich vorgestellt.

Next-generation web styling (Chrome Dev Summit 2019) ...

Zu beachten ist, dass noch nicht alle APIs marktreif und ggf. nicht fertig ausgearbeitet sind, weshalb ich hier erst einmal nur drei elementare Parts vorstellen werde, die schon im Chrome standardgemäß implementiert sind. Firefox hat schon angekündigt, die Features auch zu unterstützen. Da es aktuell noch in der Entwicklung ist, lässt es jedoch noch etwas auf sich warten.

Paint API

Als erstes wollen wir uns mit der Paint API beschäftigen. Diese erzeugt über die Paint-Funktion einen Image Value. Der Image Value kann allen Elementen zugeordnet werden, die ein Image erwarten.

CSS Painting API VerfĂĽgbarkeit Weltweit: 77.48%

Allows programmatic generation of images used by CSS

Internet Explorer nein
Microsoft Edge 79 +
Firefox nein
Google Chrome 65 +
Safari nein
Opera 52 +
iOS Safari nein
Opera Mini nein
Android Webview 131 +
Android Chrome 131 +
Android Firefox nein
Samsung Internet 9.2 +
Daten abgerufen von https:/­/­caniuse.com/­css-paint-api

Das kann zum Beispiel sein:

  • Background Image
  • Border Image
  • List Style Image
  • Mask Image

Als Beispiel habe ich eine Border erstellt, die eine random Farbe annehmen und in drei verschiedenen Positionen verwendet werden kann: top, center und bottom.

h1{
    font-size: 3em;
    margin-top: 3em;
    padding: .1em;
    width: 500px;
    --border-height:20;
    --border-position: bottom;
    background-image: paint(borderRandomColor);
}

Für dieses Beispiel haben wir zwei neue Parameter registriert. Einen Positions-Parameter, sowie einen Parameter für die Stärke der Border. Zu guter Letzt setzen wir noch das background-image auf die Paint-Funktion "borderRandomColor". Mittels dieser Funktion wird nun entsprechend eine Border generiert.

Nun müssen wir noch eine JavaScript-Klasse mit zwei notwendigen Methoden erstellen. Die anderen sind von mir frei gewählt. Als erstes brauchen wir eine Methode "inputProperties". Dort definieren wir, welche Properties im CSS gesetzt werden können.

Als Zweites erwartet unsere Paint-Funktion drei Parameter:

  • ctx - PaintRenderingContext2D - dieses ist ein Teil von CanvasRenderingContext2D, weshalb einiges ähnlich ist. Da es darauf aufbaut, kann man sich prima am Canvas-Parameter orientieren.
  • size/geom - enthält die Höhe und die Breite des Elements wo die Paint-Funktion verwendet wird. In unserem Beispiel enthält es die Höhe und Breite der h1
  • props enthält unsere gesetzten Parameter. Über einen Getter können wir diese abrufen.
class borderRandomColor{

    static get inputProperties() {
        return [
            '--border-height',
            '--border-position'
        ];
    }

    paint(ctx,size,props){

        if(props.get('--border-height').length != 1 || props.get('--border-position').length != 1){
            return false;
        }

        var height = props.get('--border-height')[0];
        var position = props.get('--border-position')[0].trim();
        var color = this.randomColor();

        if(position == "top"){
            position = 0;
        }

        if(position == "bottom"){
            position = size.height;
        }

        if(position == "center"){
            position = size.height/2;
            height = height/2;
        }

        ctx.beginPath();

        ctx.lineWidth = height;

        ctx.moveTo(0, position);
        ctx.lineTo(size.width, position);

        ctx.strokeStyle = color;
        ctx.stroke();

    }

    randomColor(){
        return "rgb(" + this.getRandom(0,255) + "," + this.getRandom(0,255) + "," + this.getRandom(0,255) + ")";
    }

    getRandom(min, max) {
        return Math.random() * (max - min) + min;
    }
}

registerPaint('borderRandomColor',borderRandomColor);

Mittels der Funktion "registerPaint" können wir nun die Paint-Methode "borderRandomColor" registrieren, damit sie im CSS zur Verfügung steht.

Random Color Border
Random Color Border

Um nun unsere borderRandomColor als PaintletWorker zur Verfügung zu stellen, müssen wir dieses noch registrieren.

CSS.paintWorklet.addModule('borderRandomColor.js');

Properties & Values API

Die Properties und Value API gibt euch die Möglichkeit, eigene Propertys und deren Standardwerte zu definieren. So kannst du, nachdem du Folgendes in JS Registriert hast, in CSS var(—color) verwenden, ohne diesen Wert zu definieren und es wird der Standardwert rot angenommen.

CSS.registerProperty({
    name: "--color",
    syntax: "<color>",
    initialValue: "red",
    inherits: false
});

Zukünftig sollte auch eine direkte Registrierung der Werte in CSS möglich sein. Momentan funktioniert diese allerdings noch nicht - die Syntax sähe wahrscheinlich so aus - momentan ist dieses Feature aber in noch keinem Browser vorhanden:

@property --color{
    syntax: '<color';
    inital-value: red;
    inherits: false;
}
Api css: registerproperty
Google Chrome 28
Android Chrome unbekannt
Microsoft Edge 12
Firefox 22
Android Firefox unbekannt
Internet Explorer nein
Opera unbekannt
Android Opera unbekannt
Safari 9
iOS Safari unbekannt
Samsung unbekannt
Android Webview unbekannt
Daten abgerufen von https:/­/­developer.mozilla.org/­docs/­Web/­API/­CSS
Weitere Informationen unter https:/­/­caniuse.com/­mdn-api_css_registerproperty

Typed OM

Das Typed OM ist eine coole Neuerung. Mittels Typed OM sind Styles von nun an Objekte und es muss nicht mehr mit Strings gearbeitet werden. Stattdessen können mittels Getter und Setter die Styles verändert werden.

Das alte CSSOM zum Setzen eines Padding-top sah zum Beispiel so aus:

el.style.paddingTop = "50px";

Mittels des neuen CSSOM ist diese Variante nicht mehr notwendig - und diese Vereinfachte Variante kann verwendet werden:

el.attributeStyleMap.set('padding-top',CSS.px(50));

Der Vorteil ist, dass wir mit richtigen Einheiten und Integern arbeiten können. Und wenn wir uns mit einem get einen Wert holen, müssen wir für diesen nicht mehr die Einheit entfernen, sonder können direkt auf den Value der CSSUnitValue zugreifen, ohne string Replace oder Sonstiges auszuführen.

console.log(el.attributeStyleMap.get('padding-top'));
// CSSUnitValue {value: 50, unit: "px"}
Api element: attributestylemap
Google Chrome 1
Android Chrome unbekannt
Microsoft Edge 12
Firefox 1
Android Firefox unbekannt
Internet Explorer 4
Opera 8
Android Opera 10.1
Safari 1
iOS Safari unbekannt
Samsung unbekannt
Android Webview ≤37
Daten abgerufen von https:/­/­developer.mozilla.org/­docs/­Web/­API/­Element
Weitere Informationen unter https:/­/­caniuse.com/­mdn-api_element_attributestylemap

Fazit

CSS Houdini wird uns mit einer grandiosen Integration zwischen CSS und JavaScript die Zukunft von CSS bringen; spätestens, wenn auch noch die anderen vier APIs voll verfügbar sind und dann auch noch der Browser Support für Firefox und Safari komplett da ist. Momentan sind erst drei APIs verfügbar.

Diese APIs fehlen im Chrome zum Beispiel noch komplett bzw. sind in einem sehr frühen Stadium der Entwicklung:

  • Layout API
  • Parser API
  • AnimationWorklet
  • Font Metrics API

Ich bin gespannt, was uns die Zukunft und CSS Houdini noch bringen wird. Gibt es irgendwann Frameworks, die CSS komplett neu erfinden? Oder eigene Layout Typen und Weiteres durch Custom Properties?

Kommentare zum Artikel

Es sind noch keine Kommentare vorhanden? Sei der/die Erste und verfasse einen Kommentar zum Artikel "CSS Houdini bringt die Magie in CSS"!

Kommentar schreiben

Verwante Beiträge
close