PostCSS Logo

Nützliche PostCSS-Module

Gibt es die überhaupt, wird sich so mancher denken… und die Antwort ist wie immer – it depends™. Natürlich gibt es nützliche PostCSS-Module, die Entwicklern beim Schreiben von CSS unterstützen, für andere passt es eher nicht in den Workflow. Nur weil es das jetzt gibt, heißt es nicht, dass jeder Webworker es gleich einsetzen muss. Dennoch denke ich, dass bei vielen mindestens ein PostCSS-Modul Einzug in den Build-Prozess gefunden hat, nämlich Autoprefixer.

Aber mal kurz ein Schritt zurück – was macht eigentlich dieses PostCSS? PostCSS-Module verändern das geschriebene CSS, dabei kann das CSS auch vorher durch einen Präprozessor erstellt worden sein, muss es aber auch nicht. PostCSS kann auch SCSS-Dateien verarbeiten bevor es mit Sass kompiliert wird. Wenn man Sass verwendet, ist man ein großes Featureset gewohnt, das bereits enthalten ist. PostCSS ist erstmal nur das Gerüst und kann mit individuellen Plugins bestückt werden. Quasi ein LEGO für CSS-Entwicklung, man kann es nach den eigenen Wünschen zusammenstecken. <meinung>Es gibt Puristen, die Präprozessoren den Rücken gekehrt haben, jetzt aber zig PostCSS-Module einsetzen, die das CSS verwursteln – das soll jetzt besser sein? Na ich weiß nicht. </meinung>

Nichtsdestotrotz gibt es Module, die mir persönlich die Arbeit erleichtern. Und was mir die Arbeit leichter macht, ohne dass ich meinen kompletten Workflow umstellen muss (reicht, wenn man das alle 2–3 Jahre macht), finde ich gut. Ich verwende PostCSS zusätzlich zu Sass, für die Aufgaben, die Sass nicht oder nicht so komfortabel beherrscht. Letztlich soll PostCSS bei der Erstellung von CSS unterstützen. Jeder sollte sich sein eigenes Bild davon machen, ob es für ihn/das Team nützlich ist.

Hinweis:

Ich habe in den Code-Beispielen die Verwendung mit Grunt-PostCSS genutzt (quasi aus dem Gruntfile.js kopiert). Wer andere Build-Tools nutzt muss u.U. andere Konfigurationen angeben. Wie die PostCSS-Plugins eingebunden werden, findet ihr immer in der Plugin-Readme.

Autoprefixer

Das bekannteste PostCSS-Plugin und in den letzten Jahren auch das nützlichste ist Autoprefixer. Ihr kennt das – viele neue CSS3-Eigenschaften wurden mit Vendorpräfixe in die Browser gebracht und jeder Hersteller hat fleißig mitgemacht und seine eigenen Präfixe eingeführt. Beliebtes Beispiel war border-radius. So las man dann oft folgendes Beispiel im Netz:

.rounded-corner {
  -webkit-border-radius: 1em;
     -moz-border-radius: 1em;
          border-radius: 1em;
}

Wir wissen, dass border-radius schon ewig keine Vendorpräfixe braucht, aber andere Eigenschaften haben heute immer noch welche. Jede neue Eigenschaft doppelt und dreifach schreiben ist bescheuert, war aber nötig.</history> Für Sass gab es Compass, das eine Vielzahl an CSS3-Mixins lieferte, die einem diese Aufgabe abnahm. Man inkludierte 1x das Mixin und Compass schrieb die Vendorpräfixe. Deshalb war Compass sehr beliebt. Das Problem war, dass Compass die Vendorpräfixe immer eingesetzt hat, unabhängig davon, ob die Präfixe noch gebraucht wurden oder nicht.

Das macht Autoprefixer anders. Hier kann ich einen Browser-Support angeben. Autoprefixer prüft anhand caniuse.com-Daten, ob ein Präfix für die definierten Browser noch notwendig ist.

Grunt-PostCSS Config für Autoprefixer

require('autoprefixer')({
    browsers: ['last 2 version', 'ie >= 9', 'Android >= 2.3', 'Firefox ESR']
})

Als Webworker schreibe ich dann standardkonformes CSS und Autoprefixer wandelt das anschließend in CSS um, das alle meine Browser verstehen, die ich unterstützen möchte. Mittlerweile auch so intelligent, dass es die unterschiedlichen Flexbox-Syntaxen und die verschiedenen linear-gradient Schreibweisen einfügt. Also tatsächlich richtig mächtig.

Kleiner Zusatzhinweis:
Anstatt der Caniuse-Daten Browser-Daten kann ich mittlerweile auch eigene Analyse-Daten als Grundlage verwenden. Ich kann angeben, dass ich alle Browser unterstütze, die mehr als 5% Zugriffe auf meine Webseite ausmachen.

Beispiel:

require('autoprefixer')({
    browsers: ['> 5% in my stats', { stats: 'path/to/the/stats.json' }]
})

doiuse

Doiuse checkt, ob ich CSS-Eigenschaften einsetze, die Browser in meinem angegebenen Browser-Support nicht verstehen.

require('doiuse')({
  browsers: ['last 2 version', 'ie >=9', 'Android >= 4'],
  ignore: ['rem', 'css-boxshadow', 'css-transitions']
})

Zum Beispiel supporte ich in der oberen Config alle IEs ab Version 9. Verwende ich Flexbox-Styles in meinem CSS, würde das Plugin Alarm schlagen, da der IE9 Flexbox nicht versteht.

Aktuell prüft es das meiner Meinung nach zu gut. ;) Es prüft dabei, ob die Angabe bei Caniuse dunkelgrün ist, also voll unterstützt wird. Ein teilweiser/buggy Support wird als fehlerhaft angezeigt, überprüft aber nicht, ob ich den „buggy“ Fall im CSS überhaupt nutze. Das kann leicht verwirren. Dieses Verhalten soll sich aber in Zukunft ändern, so der Plugin-Autor. Das Plugin soll dann besser kennzeichnen welche Eigenschaft buggy/partial Support hat und welcher Browser die Eigenschaft überhaupt nicht versteht.

Rundum finde ich das aber ein nützliches Plugin, das zur Codequalität beiträgt.

CSS Next

CSS Next ist ein Sammelsurium an Plugins, welche mehrere Sachen machen. Man kann mit CSS Next bereits jetzt schon CSS der Zukunft schreiben. Es ermöglicht unter anderem die Benutzung von nativen Variablen (Custom Properties), Custom Media Queries oder wandelt Pixel-Angaben und rem-Werte um. Zudem hat CSS Next Autoprefixer und „Sass-Features“ wie Nesting schon an Board. Es ist quasi das Babel des CSS.

Ein Beispiel für Custom Properties

/* custom properties */
:root {
  --heading-color: #ff0000;
}

/* custom selectors */
@custom-selector :--headings h1, h2, h3, h4;

/* usage */
:--headings {
  color: var(--heading-color);
}

CSSNext kompiliert das zu:

h1, h2, h3, h4 {
  color: #ff0000;
}

Ich denke, dass es nicht viele Entwickler geben wird, die die allerneuesten Features für CSS schon heute verwenden werden. Viele Webworker schrecken ja schon davor zurück Flexbox einzusetzen, weil sie es noch nicht allumfänglich verstehen bzw. Browser-Bugs fürchten oder noch uralte Browser unterstützen müssen. Dennoch spannend zu beobachten, ob es dazu führt, dass mehr Entwickler zukunftsweisendes CSS schreiben.

postcss-assets

Ich muss sagen, dass ich es praktisch fand, dass Compass Funktionen bereit stellt, die mir die Breite und Höhe einer Datei auslesen können. In einigen Projekten brauchte ich das. Die Funktionalität bietet „postcss-assets“ genau so.

Beispiel: Breite eines Logo auslesen:

.logo {
  width: width("logo.svg");
  height: height("logo.svg");
}

Das kompilierte CSS:

.logo {
  width: 100px;
  height: 40px;
}

Zudem kann man auch Grafiken enkodiert (als background-image), also inline ins CSS ausgeben lassen. Aber dazu im nächsten Kapitel noch ein Plugin, dass das noch umfänglicher macht.

Beispiel inline SVG als background-iamge:

.logo {
  background-image: inline("logo.svg");
}

Das kompilierte CSS:

background-image: url("data:image/svg+xml,%3Csvg…")

Des Weiteren kann ein Cache-Buster aktiviert werden, praktisch besonders bei statischen Seiten.

postcss-svg

PostCSS-SVG stellt kleine Helferlein für die Arbeit mit SVG bereit. Icon-System hin oder her, Iconfont vs. SVG, ihr kennt das. Das Thema ignorieren wir hier mal. Es gibt Anforderungen, die außerhalb von Icons liegen. Ich hatte ein Projekt, da ist es erforderlich gewesen, dass eine Box einen unförmigen Hintergrund hat (Sprechblase) – ein Paradebeispiel für SVG als background-image. Nun ist es allerdings so, dass dieser Hintergrund mehrere Farbvarianten hatte, was auf den ersten Blick mehrere Assets mit den jeweiligen Farben bedeuten würde.

Oder man fügt den SVG-Code als enkodierten String ins CSS ein und tauscht dabei die Füllfarbe aus. Das PostCSS-Plugin postcss-svg macht das für uns.

Beispiel Sass

.svg-bg1 {
  background-image: svg('path/to/bg-svg', 
  '[fill]: #{$color-text}');
}

.svg-bg2 {
  background-image: svg('path/to/bg-svg', 
  '[fill]: #{$color-main}');
}

Wenn man Assets enkodiert ins CSS einbindet, muss man unbedingt vorher die Datei so klein schrumpfen wie es nur geht.


Dateien enkodiert ins CSS aufzunehmen ist immer ein Drahtseilakt… einerseits möchte man das CSS so schlank wie möglich halten, andererseits Requests sparen. Lohnt es sich für 2–3 Dateien ein Sprite zu erstellen oder ist der Request für das Sprite „teurer“? Muss/kann das einzelne Sprite-Element visuell verändert werden? Ist es wartbar? Wenn beim Build-Prozess generiert, sollte das kein Problem sein. Diese Fragen sollten sich Entwickler stellen, wenn sie grafische Elemente einbinden.


In dem besagten Projekt fand ich es die beste Lösung die SVG-Formen als background-image zu verwenden. Über die PostCSS-Funktion verknüpft und die Füllfarbe zugewiesen, fertig.

Ideal wäre für mich, wenn man diese Teile in ein separates Stylesheet auslagern und async nachladen könnte. Aber soweit hab ich den Bauprozess nicht gebracht.

CSSnano

CSSnano ist ebenfalls eine Ansammlung kleiner Scripte, die das CSS möglichst klein schrumpfen wollen. Dabei versuchen sie weiter zu gehen, als Minifizierer von Sass & Co. Neben den üblichen „ich entferne alle Whitespaces“, werden auch CSS-Regeln zusammen gezogen, die den gleichen Selektor haben. Da muss man vorsichtig sein, da dabei die Kaskade verändert werden könnte und das Ergebnis nicht mehr das Selbe ist. Auch versucht es z-Indizes zu simplifizieren. Auch das führt manchmal dazu, dass das gewünschte Aussehen im Anschluss nicht mehr passt. Ich empfehle, dass man das ausführlich gegenüber den bisherigen CSS-Minifier testet und vergleicht, ob es einen Vorteil bringt. Dennoch leistet es grundsätzlich eine gute Arbeit beim Minifizieren von CSS-Dateien.

Natürlich ist die Liste an Plugins lang und es gibt sicherlich für jeden nützliche und unnütze Plugins. Wer einen Präprozessor ersetzen möchte, kann CSSNext oder PreCSS verwenden. Wer nicht in die Probleme mit Flexbugs rennen möchte, kann mit postcss-flexbugs-fixes viele Bugs im Buildtasks elimieren – durchaus praktisch. Auf der Seite postcss.parts sind viele PostCSS-Plugins in unterschiedlichen Kategorien aufgeführt.

Welche nützlichen PostCSS-Plugins habt ihr noch im Einsatz?

9 thoughts on “Nützliche PostCSS-Module”

  1. autoprefixer verwende ich auch, klar. Dazu:

    1. pixrem, um ggf. px-Fallbacks für rem erzeugen zu lassen
    2. css-mqpacker kombiniert verteilte @media-Queries, so dass man nicht achtundrölfzig Mal „@media screen and (min-width: 48em) { … }“ im CSS hat, sondern nur ein Mal; hält also das CSS schlank

  2. Den „Gefahrenhinweis“ für CSSnano kann ich nicht nachvollziehen. Das Zusammenführen von Selektoren macht er meines Wissens nach nicht, zumindest nicht in den Standard-Einstellungen, welche „safe“ sind und das Ergebnis nie verändern sollten. Lediglich bei komplett gleichen Selektoren und Properties wird der obere entfernt, da diese nie zum Tragen kommen kann.

    Überhaupt sind „unsafe“ Optimierungen standardmäßig nicht aktiv, hier muss der Entwickler bewusst reinoptieren, was CSSnano wohl kaum vorzuwerfen ist :)

  3. Hi Sven,

    super Artikel, vielen dank schon einmal dafür – ich stelle gerade meinen Workflow um – dein Artikel hat mich noch ein Stück weiter gebracht :)

    Ich habe bei CSSNano reingeschaut und festgestellt, dass es selbst den Autoprefixer ausführt – im Endeffekt braucht man dann doch kein separates Autoprefixer Plugin mehr oder nicht?

    Grüße
    Sven

  4. @Sven Wolfermann – Sorry, da hab ich mich geirrt, cssnano wird erst ab der kommenden Versino standardmäßig „safe“ sein, bis dahin sollte man diese Option wohl selber setzen.

  5. Sehr effiziente Vorgehensweise. Den Ansatz seinen Workflow auf die wichtigsten Faktoren alle 2 – 3 Jahre umzustellen, halte ich für extrem vernünftig. Man sollte sich auch gut überlegen ob man jeden „Trend“ direkt in der Produktivumgebung einsetzen sollte, jedoch gehören PostCSS-Module oder Plugins sicherlich zu den nützlichen Tools der Entwicklung.

Kommentare sind geschlossen.