Stack update 2016: Von SASS zu PostCSS

Stack update 2016: Von SASS zu PostCSS

Tl;dr: Wenn mit einem neuen Projekt begonnen wird, kann es sich auszahlen PostCSS umfassend einzusetzen. In existierenden Workflows hat SASS keine besonderen Nachteile und kann leicht mit PostCSS erweitert werden.

Obwohl ich Anfang 2015 ein wenig mit PostCSS herumexperimentierte, habe ich nie die großen Vorteile von PostCSS gegenüber SASS gesehen. Ich habe mir nun kurz Zeit genommen um mir PostCSS und die damit verbundenen Möglichkeiten noch einmal genauer anzusehen. Wenn Du darüber nachdenkst selbst auf PostCSS zu wechseln findest du in diesem Beitrag einige Anregungen.

Alte Methode: SASS

Wir haben SASS umfassend für viele Jahre eingesetzt, hatten jedoch zu Beginn das Problem, dass die Compile-Zeiten massiv anstiegen. Libsass war die Rettung, indem es eine schnelle C++-Alternative zum quälend langsamen Ruby SASS Compiler bietet.

Für was wir SASS und Zusatzmodule derzeit nutzen:

  • Imports zwecks Modularisierung unserer CSS-Dateien (wir verwenden SMACSS-Architektur)
  • Verschachtelte CSS-Regeln (lebenswichtig!)
  • Verwenden von Variablen (Unsere internen SASS-Bibliotheken basieren auf einem gemeinsamen Subset für einfachere Anpassbarkeit)
  • Einsetzen von flexibleren definitionen unter Verwendung des @extend Syntax
  • Definition von Mixins und Hilfsfunktionen
  • Automatisches Gruppieren von Media Queries mit breakpoint-sass
  • Farbtransformationen

Andere Werkzeuge aus unserem CSS Buildstep

  • Autoprefixer war eine willkommene Ergänzung in unserem gulp-basierten Workflow, weil wir damit einfach die standardbasierten CSS definitionen nutzen können. Vendor-Prefixe werden automatisch hinzugefügt ohne, dass man Mixins dafür verwenden musste (Welche bsp. das compass oder scotch framework bereitstellen). Was ich damals noch nicht mitbekommen habe: Autoprefixer basierte selbst bereits auf PostCSS.
  • CSSNano um resultierende CSS-Dateien zu komprimieren. Dies geschieht durch recht komplexe Logik - Hier sollte man aufpassen, insbesondere wenn man die resultierende Dateien mit anderem CSS einsetzt. Über die teils massiven Einsparungen in der Dateigröße kann man jedoch kaum streiten.

Obwohl wir keine besonderen Probleme mit unserem bisherigen Workflow hatten, gibt es einige Bereiche die weiter automatisiert werden können. Sehen wir was PostCSS für uns tun kann:

Neue Methode: PostCSS

PostCSS bezeichnet sich als CSS "Postprocessor" (während SASS und LESS "Preprocessors" sind) was heißt, dass es valide CSS stylesheets als Input verwendet und verschiedene Transformationen darauf anwendet. Im Gegensatz verwendet SASS spezielle *.sass oder *.scss-Dateien und gibt CSS-Dateien aus.

PostCSS ist weiters in Plugins organisiert (von welchen autoprefixer das meistverbreitetste ist) und kann einfach erweitert werden.

Ein großer Teil des Ganzen ist, dass zukünftige CSS Spezifikationen viele Probleme angehen, die SASS durch die Einführung seines eigenen Syntax löst. Warum sollte man also nicht gleich den hippen, neuen Syntax verwenden und diesen dann in derzeit unterstützten Syntax transformieren?

Was mir an der Sache gefällt ist, dass diese Methode näher an dem ist, was wir derzeit bereits mit Babel und JavaScript machen. Ein großer Nachteil ist jedoch, dass kaum Konsens über viele Details zukünftiger Spezifikationen besteht. Falls man sich noch nicht umstellen will, ist es absolut gerechtfertigt nur bestimmte PostCSS Plugins in Kombination mit bestehenden SASS-Tools zu nutzen.

Getting up to speed

Um PostCSS zu einem vernünftigen Ersatz zu machen, versuche ich zuerst die Funktionalität, die wir derzeit in SASS verwenden, zu replizieren. Wenn möglich, ersetzte ich hier SASS-spezifischen Syntax mit den Konstrukten zukünftiger Spezifikationen.

Importieren und Verschachtelung

Um einen großen Teil der Funktionalität des SASS-Stacks zurückzubekommen ist nur das hinzufügen der Plugins postcss-nested and postcss-easy-import notwendig. Dies ermöglicht das Importieren von Partials (mittels Prefix, damit diese nicht in eigene Dateien geschrieben werden) und das Verwenden von Verschachtelungen in deinen CSS-Regeln.

Als nette Zugabe unterstützt postcss-import (welches von postcss-easy-import verwendet wird) das importieren von Paketen aus NPMs "node_modules"-Ordner, was recht nett ist um komplexe relative URLs bei Imports zu vermeiden.

Variablen

Der Syntax der derzeitgen Spezifikation von "custom properties" (Variablen) in CSS weicht einigermassen von der aus SASS gewohnten Art ab. Da diese Spezifikation jedoch recht stabil ist, sollte es eine sichere Sache sein, gleich auf den neuen Syntax zu welchseln. Das PostCSS plugin nach dem Du hier suchst ist postcss-custom-properties. Zu meiner Überraschung sind custom properties auch bereits gut unterstützt.

Falls Du dich nicht mit custom properties beschäftigen willst: Es gibt immer noch postcss-simple-vars welches SASS-ähnliche Variablen ermöglicht.

Extends

Ein zur @extend Funktion von SASS sehr ähnliches Konstrukt ist der neue @apply Syntax. Obwohl kein Browser außer Chrome auch nur den Plan hat dieses Feature zu implementieren, bietet es uns eine solide Alternative. Das postcss-apply plugin ist hier zuständig.

Mixins

Die Geschichte ist bei Mixins etwas anders. Da es keine Anstrengungen gibt, dieses Feature in Spezifikationen zu verankern ist eine allgemeine browserbasierte Lösung derzeit nicht in Sicht. Für alle die hier nicht so empfindsam sind bietet das postcss-mixins Plugin eine solide SASS-ähnliche alternative. Mixins können hier zusätzlich auch via JavaScript definiert werden.

Gruppieren von Media-Queries

Da die verschachtelte Verwendung von Media Queries bereits durch postcss-nested unterstützt wird, wäre der Mehrwert vom bisherigen breakpoint-sass auf das Gruppieren von Media-Query Definitionen und das Bereitstellen von Variablen mit vordefinierten Breakpoint-Konfigurationen beschränkt.

Während das Gruppieren wie ein Job für einen CSS-Minifier wie cssnano aussieht, können Breakpoint-Definitionen mittels des Plugins postcss-custom-media bereitgestellt werden.

Farbtransformationen

Die Farbtransformationen die durch postcss-color-function mit neuem CSS-Syntax bereitgestellt werden, unterstützen eine Vielzahl von Möglichkeiten. Wieder heißt es hier: Die bisherigen Definitionen müssen angepasst werden.

Besseres CSS mit PostCSS

Alle PostCSS plugins die bis zu diesem Punkt angesprochen wurden dienen Großteils zum replizieren bestehender SASS-Funktionalität. Aber was können wir mit zusätzlichen Plugins für PostCSS erreichen? Postcss.parts versorgt uns mit einem inoffiziellen Katalog für Plugins für verschiedenste Aufgaben. Hier einige PostCSS Plugins die ich unserem Buildprozess hinzugefügt habe:

  • postcss-flexbugs-fixes: Da es trotz autoprefixer noch einige unangenehme Inkonsistenzen im Flexbox-Syntax gibt verwenden wir dieses Plugin um einige Spezifika für IE11 zu ergänzen, die wir ansonsten manuell abändern müssten.
  • postcss-sorting: Obwohl dies ein PostCSS Plugin ist, verwenden wir dies nicht als Teil des Buildprozesses - die Funktionalität macht Sinn für den Editor, welcher zum Erstellen des CSS verwendet wird. Glücklicherweise gibt es Plugins für Sublime Text und Atom. Was das Plugin macht, ist dass es die verschiedenen CSS-Eigenschaften in einer konsistenten Form sortiert, was die Lesbarkeit stark verbessert.

Obwohl die folgenden Tools alle PostCSS plugins bereitstellen, haben ich diese direkt über Gulp eingebunden (was auch empfohlen wird):

  • Stylelint via gulp-stylelint: Konsistente Formatierung in CSS sicherzustellen ist schwierig und wenn verschiedene Entwickler an einem Programm arbeiten quasi unvermeidlich. Um gewalttätige Wutausbrüche über die syntatische Korrektheit zu vermeiden kann Stylelint verwendet werden um direktes Feedback über gemeinsame Formatrichtlinien zu ermöglichen.
  • stylelint-selector-bem-pattern: Dies bindet postcss-bem-linter als plugin für Stylelint, was das Feedback in den Stylelint-Report integriert. Was das Plugin macht ist die Korrektheit von BEM- oder SUIT Benennungsmustern für das Stylesheet zu prüfen. Ein Benennungsschema zu verwenden ist eine große Erleichterung in komplexen Anwendungen.
  • CSSStats via gulp-cssstats: Interessante statistiken über deine CSS-Dateien. Ich würde nicht empfehlen, dies als Standardschritt im Build hinzuzufügen, es ist jedoch interessant als eigene Gulp-Aktion oder Teil des Produktiv-Builds.

Fazit

Es gibt für mich nicht besonders viele umwälzende Vorteile im Wechsel von SASS zu PostCSS. Es ist allgemein gut auf CSS-Syntax der nächsten Generation zu setzen, aber Großteils stellt dies derzeit eine rein kosmetische Entscheidung dar, da kein großartiges Mehr an Funktionen besteht und der "native" Browsersupport noch sehr lückenhaft ist (und noch für Jahre bleiben wird).

Die wahre Macht von PostCSS liegt in der einfachen Erweiterbarkeit. Deine eigenen Plugins zu schreiben ist einfach und PostCSS ist eine gute Plattform um Plugins für andere bereitzustellen. Die individuellen Plugins scheinen auch etwas aktiver zu sein, als SASS als Ganzes.

Das sich PostCSS und SASS aber einfach kombinieren lassen, würde ich empfehlen im bestehenden Workflow ein paar PostCSS Plugins zu ergänzen und einen kompletteren Ansatz dann auszuprobieren wenn ein komplett neues Projekt begonnen wird.

Wenn du Fragen oder Anmerkungen hast, freue ich mich von dir auf Twitter zu hören!