Eleventy: PostCSS und Tailwind CSS integrieren
About 2 min reading time
In meinem Eleventy Tutorial habe ich ja bereits gezeigt, wie man einen Blog mit Eleventy aufsetzen kann und auch, wie man CSS in eine Eleventy Webseite integieren kann.
Da ich gerne mit Tailwind CSS arbeite, möchte ich dieses natürlich auch in meinen privaten Projekten einsetzen und habe hier auch einige Setups ausprobiert. Die meisten setzen hierbei PostCSS und TailwindCSS "klassisch" auf und passen dann die Skripte in der package.json so an, dass erst die Eleventy Seite gebaut wird und dann das passende CSS generiert wird. Das kann man so tun, machte in meinen Augen aber das Setup in der package.json komplizierter.
Meine Alternative nutzt Eleventy Bordmittel, um das CSS zu generieren und fügt sich mit wenigen Zeilen Code in die bestehende Konfiguration ein.
Das ganze könnt ihr Euch in meinem Tutorial Projekt im tailwind Branch ansehen (commit).
Die Idee ist die folgende: Statt einem nachgelagerten Prozess, nutzen wir während des Builds über einen asynchronen Filter PostCss und erzeugen so über Eleventy auch direkt unser CSS.
Damit wir PostCSS und Tailwind CSS nutzen können, müssen wir es im ersten Schritt installieren:
npm i -D tailwindcss postcss autoprefixer cssnano
In unserer Eleventy Konfiguration benötigen wir jetzt noch einen asynchronen Filter:
const tailwind = require('tailwindcss');
const postCss = require('postcss');
const autoprefixer = require('autoprefixer');
const cssnano = require('cssnano');
const postcssFilter = (cssCode, done) => {
// wir rufen hier PostCSS auf.
postCss([tailwind(require('./tailwind.config')), autoprefixer(), cssnano({ preset: 'default' })])
.process(cssCode, {
// Pfad zu unserer CSS Datei
from: './src/_includes/styles/tailwind.css'
})
.then(
(r) => done(null, r.css),
(e) => done(e, null)
);
};
Natürlich könnt ihr mit wenigen Anpassungen auch nur PostCSS nutzen. Lasst dann einfach den Tailwind CSS spezifischen Code raus.
Den Filter fügen wir jetzt in der Konfiguration, zusammen mit einem "watch target", hinzu
module.exports = function (config) {
// ...
config.addWatchTarget('./src/_includes/styles/tailwind.css');
config.addNunjucksAsyncFilter('postcss', postcssFilter);
// ...
};
Über addWatchTarget
teilen wir Eleventy mit, dass Änderungen an dieser Datei einen erneute build auslösen sollen, wenn wir gerade die Anwendung lokal mit --serve
laufen lassen. Der asynchrone Filter sorgt dafür, dass wir unser CSS umwandeln können.
Jetzt fehlt nur noch das CSS, welches wir unter ./src/_includes/styles/tailwind.css
im Projekt hinzufügen. Dort kann natürlich ganz normal mit Tailwind CSS gearbeitet werden:
@tailwind base;
@tailwind components;
@tailwind utilities;
Wenn wir jetzt unser CSS in der Seite ergänzen möchten, haben wir zwei Möglichkeiten:
- als inline style an beliebiger Stelle in unsererm template
- als eigene CSS Datei
Welche Variante hier die richtige ist, hängt stark vom Projekt ab und ist wahrscheinlich einen eigenen Blogpost wert. Ich zeige hier schnell beide Varianten:
Im head
der Seite (in unserem Beispiel in der Datei src/_includes/layout.njk
):
<style>
{% set css %}
{% include "styles/tailwind.css" %}
{% endset %}
{{css | postcss | safe}}
</style>
Wir setzen hier zunächst den Wert css
im Template und nutzen dann den postcss
Filter. Über den safe
Filter wird das ganze dann in unserem Template eingefügt. Für mich die richtige Lösung, wenn ich nur wenig CSS habe und die erzeugte HTML Datei nicht zu groß wird.
Wenn man lieber eine eigene CSS Datei erzeugen möchte, kann man dies über ein eigenes Template machen (z. B. src/style.njk
)
---
permalink: style.css
---
{% set css %}
{% include "styles/tailwind.css" %}
{% endset %}
{{css | postcss | safe}}
Dank dem permalink
in der FrontMatter wird diese Datei als style.css
erzeugt und kann dann in unserem Template eingebettet werden (src/_includes/layout.njk
).
<link rel="stylesheet" href="/style.css" />
Kennt ihr einen besseren Weg, um CSS in Eleventy zu erzeugen und integrieren? Habt ihr weitere Fragen zu Eleventy? Schreibt mir gerne auf Mastodon.