Schlagwort: Projekt 26

#Projekt26 ist eine Initative von Torsten Landsidel, dass Bloggen wieder zu beleben. Alle zwei Wochen muss ein Blogartikel geschrieben werden und ein anderen Blogartikel kommentiert werden. Ziel ist es den Blog wieder als zentralen Ort für den Austausch zu nutzen und wieder weniger abhängig von Social Media Plattformen zu werden.

Eine Übersicht an Beiträgen die im Rahmen des Projektes geschrieben worden sind, findet ihr auf Twitter unter dem Hashtag #Projekt26 oder in dem Gist von Torsten.

Ist Tailwind CSS eine gute Idee für WordPress Themes & Plugins?

Tailwind CSS hat sich in den letzten Jahren von einem belächelten CSS-Framework zu einem echten Schwergewicht entwickelt. Der Grund dafür ist einfach: Es nimmt euch komplett die Frage ab, wie ihr eure CSS-Klassen benennt: gar nicht!

Statt euch für jedes Element eures Designs eine oder mehrere Klassennamen auszudenken und die Klasse dann in eurem Stylesheet zu definieren, definiert ihr bei Tailwind den Style direkt über einfach zu merkende CSS-Klassen im HTML-Markup, z.B. block p-2 mx-3 mt-3 bg-gray-900 hover:bg-gray-700 text-white cursor-pointer. Aufgelöst sieht der genutzte Teil des Stylesheets wie folgt aus:

.block { display: block; } .p-2 { padding: 0.5rem; } @media (min-width: 1280px) { .xl\:p-4 { padding: 1rem; } } .mx-3 { margin-left: 0.75rem; margin-right: 0.75rem; } .mt-3 { margin-top: 0.75rem; } .bg-gray-900 { background-color: rgb(17, 24, 39); } .hover\:bg-gray-700:hover { background-color: rgb(55, 65, 81); } .text-white { color: rgb(255, 255, 255); } .cursor-pointer { cursor: pointer; }
Code-Sprache: CSS (css)

Sogar Media Queries und Hover-Zustände lassen sich problemlos mit den Tailwind-Klassen schnell und einfach anwenden und theoretisch könnt ihr euer Design komplett im HTML schreiben.

Wie sich das anfühlt, davon vermittelt die Tailwind-Website ein gutes Gefühl oder ihr tobt euch auf dem Spielplatz aus.

Mein Tailwind-Lebenslauf

Ich nutze Tailwind CSS bereits seit Anfang 2018 (Version 0.3.0, mittlerweile gibt es Version 2.0) nachdem ich darüber einen Podcast gehört habe und bis heute hatte ich keinen Grund mich nach einem anderen CSS Framework umzuschauen. Das hat(te) folgende Gründe:

Ich sehe mich mehr als Entwickler und weniger als Designer und fand es deswegen immer extrem umständlich mir Klassennamen auszudenken, an die man sich auch 3 Monate später noch erinnert (das Problem habe ich grundsätzlich mit Namen) und so auch wirklich wiederverwendet. Meistens denkt man sich dann doch eher eine neue CSS-Klasse aus, als das eigene toll definierte Design System zu verwenden.

Eigentlich will ich mich auch gar nicht so viel mit Design beschäftigen. Deswegen habe ich früher auch Bootstrap oder Bulma ausprobiert. Das Problem ist einfach nur: Die Website sieht aus wie geschätzt 50% des Webs und das hat mir noch nie gefallen. Ich konnte zwar einigermaßen gut mit CSS umgehen und eigentlich schreibe ich auch gerne CSS, aber bestehende Klassen zu überschreiben, um den Stil anzupassen, hat mich schon immer genervt (vor allem bei WordPress Themes).

Ich kann also einigermaßen gut mit CSS umgehen, kann mir keine Namen ausdenken und vor allem merken und habe keine Lust auf das Standarddesign von Bootstrap oder Bulma. Tailwind war da der perfekte Kompromiss: Ich muss selber CSS schreiben, bin auf eine begrenzte Anzahl gut zu merkender Klassennamen limitiert und muss mir vor allem keine eignen Namen ausdenken.

Gleichzeitig habe ich bei Tailwind nicht das Gefühl ich verlerne CSS. Im Gegenteil. Ich bin in den letzten drei Jahren deutlich sicherer im Umgang mit CSS geworden und habe auch kein Problem mal eine Klasse wirklich zu definieren und zu stylen. Der Grund dafür ist die Dokumentation von Tailwind CSS. Diese ist wirklich extrem gut und erklärt sehr anschaulich wie alle CSS Eigenschaften funktionieren. Hier zum Beispiel am Beispiel von justify-content:

Auszug aus der Tailwind Dokumentation zu justify-content für Flex(box)

Ein weiterer Grund warum ich Tailwind liebe, ist, dass es mir alle Freiheiten lässt, mich aber gleichzeitig einschränkt. Zum Beispiel was die Nutzung von Paddings und Margins angeht. Früher hatte ich Abstände in Form von 1px, 2px, 3px, 5px, 8px, 9px, 10px …, 99px in meinem Stylesheet, was dazu führt, dass das Design irgendwann total inkonsistent wirkt. Tailwind limitiert mich hier durch die Klassen und gibt mir eine ausreichende, aber nicht überforderte, Auswahl in festen Abständen 0.25rem, 0.5rem, 0.75rem, 1rem… vor. Damit komme ich deutlich besser klar.
Das Gleiche gilt für Farben. Hier liefert Tailwind eine vordefinierte Farbpalette mit Abstufungen, an die man sich halten kann, aber auch nach Belieben verändern oder erweitern kann. Auch das führt dazu, dass das eigene Design deutlich konsistenter wirkt.

Auch wenn ich Tailwind mal nicht verwende, schaue ich alle CSS-Eigenschaften in der Tailwind Dokumentation nach. Selbst wenn ihr euch gegen den Einsatz von Tailwind entscheidet, kann ich euch das nur empfehlen. Unter Properties stehen ja immer die wahren CSS-Eigenschaften der Tailwind-Klasse.

Was gegen Tailwind in WordPress Themes & Plugins spricht

Jetzt aber genug mit den Lobeshymnen auf Tailwind. Die Frage dieses Artikels war ja: Ist es eine gute Idee Tailwind für ein WordPress Theme oder Plugin zu verwenden und was muss ich beachten und ggf. anders machen?

Wie immer lautet die grundsätzliche Antwort darauf: Es kommt darauf an! Tailwind ist keine eierlegende Wollmilchsau!

Deswegen erst einmal ein paar Punkte die dagegen sprechen:

Theme HTML Markup ändert sich oft

Da ihr euer Style direkt im HTML Markup definiert, ändert sich das Markup sehr häufig. Das führt vor allem in Kombination mit Child-Themes zu großen Problemen. Überschreibt ihr ein Template im Child-Theme und ändert Klassen im Parent-Theme, müsst ihr auch daran denken das Child-Theme anzupassen.

Wird euer Theme nicht nur von euch genutzt, z.B. ihr bietet es in der WordPress.org Theme Repository an, ist Tailwind meiner Meinung nach der falsche Weg. Ihr könnt aber trotzdem die Tailwind Klassen in eurem Stylesheet mit der @apply-Regel nutzen.

Ich kann hier übrigens auch voll und ganz die Kritik an Tailwind verstehen. In der Theorie sollte HTML und CSS getrennt werden aber die Realität in der Praxis sieht meiner Meinung nach meistens ganz anders aus. Alleine um CSS Flexbox und Grid richtig nutzen zu können, muss man das HTML Markup entsprechend designen und zu oft schreibt man am Ende CSS-Selektoren, die bis ins unendliche verschachtelt und einfach nicht wiederverwendbar sind.

Block Markup ändert sich oft

In Plugins halten ja immer mehr Gutenberg Blöcke Einzug. Hier hat man die Wahl zwischen clientseitig mit JavaScript gerenderten Blöcke, d.h. das Markup inkl. ggf. der Tailwind-Klassen wird so in der Datenbank gespeichert, oder serverseitig gerenderten Blöcke, wo i.d.R. nur die Attribute in der Datenbank gespeichert werden.

Für clientseitig gerenderte Blöcke kann ich nur von Tailwind abraten. Wenn ihr nicht direkt den perfekten Style hinlegt und ihn nachträglich ändern wollt, wird jeder alte Block im Block Editor eine Fehlermeldung anzeigen und muss wiederhergestellt werden. Außerdem müsst ihr jeden Block im Editor per Hand updaten, damit die Tailwind-Klassen übernommen werden. Glaubt mit: Das wollt ihr nicht.
Hier ist es definitiv sinnvoll sich einmal CSS-Klassen auszudenken und im Stylesheet den Style zu definieren. Ihr könnt aber auch hier wieder @apply nutzen.

Bei serverseitig gerenderten Blöcke sieht es wieder anders aus. Hier ist es kein Problem den HTML Elementen direkt Tailwind-Klassen zu verpassen. Ändert ihr euren PHP-Code, wird die Änderung ja direkt von allen bestehenden Blöcken ausgeliefert.

Was man bedenken sollte

Zusätzlich gibt es einige Punkte, die ihr vor eurer Einsatz in einem WordPress Theme oder Plugin bedenken solltet:

CSS Klassen von WordPress

Wenn ihr ein Theme designt, stylt ihr nicht nur euer eigenes HTML Markup, sondern auch die Menüs, Widgets, Kommentare … von WordPress. Dieses haben fest definierte CSS Klassen, die sich nicht so einfach ändern lassen. Hier müsst ihr also zwangsläufig das Design über euer Stylesheet regeln und Tailwind verliert zumindest einen Teil der Vorteile. Die Tailwind Klassen könnt ihr aber trotzdem zum stylen dank @apply nutzen.

Tooling

Um Tailwind auszuprobieren, könnt ihr zwar einfach einmal die .css-Datei über einen CDN laden, die Datei ist aber rund 3 mb groß! Nichts, was ihr für euer Theme oder Plugin wirklich bei jedem Seitenaufruf ausliefern wollt.

Ihr müsst also zwangsläufig mit npm, Webpack (hier vereinfacht euch Laravel Mix sehr das Leben) und PostCSS beschäftigen, um das volle Potenzial von Tailwind auszunutzen und danke PurgeCSS die .css-Datei klein zuhalten (deutlich unter 100 kb i.d.R.).

Für ein Theme lohnt sich der Aufwand (und der Wartungsaufwand) definitiv, aber nicht für jedes kleine Plugin, wo man nur ein paar Zeilen CSS schreiben muss, um z.B. seinen Block zu stylen.

Ich habe viele private Plugins für Travel-Dealz geschrieben, die nicht öffentlich zugänglich sind und liefere i.d.R. den gesamten Style über das Theme aus und muss deswegen nur einmal das ganze Tooling aufsetzen.

Lösungen

Es gibt einige Probleme, die man durch den Einsatz von Tailwind zwangsläufig haben wird, aber dafür gibt es auch gute Lösungen:

@apply

Nicht immer kann man die Tailwind-Klassen direkt im HTML Markup anbringen, auch wenn es der bevorzugte Weg ist. An dieser Stelle kommt die @apply-Regel in Spiel. @apply ist eigentlich bisher ein inoffizieller W3C Vorschlag und soll dazu dienen, CSS-Variablen als wiederverwendbare Bündel (Mixins) zu definieren, die man dann über die @apply-Regel auf CSS-Regeln anwenden kann.

Bei Tailwind dient @apply dazu die Tailwind-Klassen auf CSS-Regeln im eigenen Stylesheet anzuwenden, z.B.

/* Input */ .btn { @apply py-2 p-4; }
Code-Sprache: CSS (css)

Da es für @apply bisher eh keine Unterstützung von den Browsern gibt, wird das ganze mithilfe von PostCSS in reguläres CSS übersetzt:

/* Output */ .btn { padding: 1rem; padding-top: 0.5rem; padding-bottom: 0.5rem; }
Code-Sprache: CSS (css)

Mit diesem Trick könnt ihr ganz normales CSS schreiben, aber trotzdem die „Kurzbefehle“ von Tailwind verwenden. Ihr könnt in @apply seit Tailwind 2.0 sogar die ganz normalen Tailwind-Klassen für Media Queries, z.B. xl:p-4, verwenden.

PurgeCSS

Wenn ihr Tailwind CSS nutzen wollt, führt kein Weg an PurgeCSS vorbei. PurgeCSS sorgt dafür, dass in eurem endgültigen Stylesheet, welches ihr an die Website-Besucher ausliefert, im besten Fall keine nicht benutzen CSS-Klassen enthalten sind.

Wenn ihr npm run production ausführt, rennt PurgeCSS durch alle von euch festgelegten HTML, PHP, JavaScript-Dateien und erstellt eine sehr lange Liste mit möglichen CSS-Klassen, die ihr verwendet habt. Diese Liste wird mit allen von euch und Tailwind definierten CSS-Klassen abgeglichen und nur die Übereinstimmungen landen in dem Stylesheet für eure Produktionsumgebung.

Statt alle Tailwind-Klassen, die rund 3 mb groß sind (3020.9 KiB), reduziert PurgeCSS meine Stylesheet für diesen Blog z.B. auf 44 KiB.

Hinzu kommt noch, dass in Tailwind-Klassen viele Zeichenabfolgen sich sehr oft wiederholen, was dazu führt, dass sich die Datei außerordentlich gut komprimieren lässt. So wird aus 44 KiB mithilfe von Gzip 9 KiB, die nur übertragen werden müssen.

Das Problem an WordPress Themes: Viele CSS-Klassen von WordPress muss man stylen, PurgeCSS wird sie aber im Theme-Ordner nicht finden, weil sie aus dem Core kommen. D.h. die mühevoll gestylten Klassen werden von PurgeCSS entfernt. Es gibt aber mehrere Wege damit umzugehen:

Ignorieren: Alles, was ihr mit einem CSS-Kommentar purgecss ignore verseht, wird von PurgeCSS ignoriert.

/*! purgecss start ignore */ @import './components/comments.css'; /*! purgecss end ignore */
Code-Sprache: CSS (css)

Wichtig ist allerdings den Kommentar mit ! als important zu kennzeichnen, damit es nicht vorher schon beim Minifizieren entfernt wird. PurgeCSS rennt beim Zusammenbauen ganz zum Schluss.

Ignore kann ich euch für alle CSS-Klassen empfehlen, die ihr mit @apply oder regulärem CSS styled.

Purge Templates: Ihr könnt euch in eurem Theme einen Ordner mit HTML-Dateien anlegen, z.B. purge-templates, diesen in PurgeCSS einbeziehen und dort einfach das Markup hineinkopieren.

Mein Ordner mit Templates die nur von PurgeCSS verwendet werden

Ich nutze die Purge Templates hauptsächlich für Komponenten aus anderen Plugins, wo ich direkt Tailwind-Klassen einsetzte und diese nicht im Theme liegen.

Safelisting: Ihr könnt PurgeCSS auch eine Safelist an Klassen mitgeben, die nicht gepurged werden sollen. Hier ist es auch möglich mit Regex zu arbeiten.

Meine Erfahrungen mit Safelisting sind allerdings nicht besonders gut. Man vergisst es dann doch wieder und später die Safelist auszumisten ist ebenfalls deutlich schwieriger, als sinnvoll benannte Dateien in einem Ordner zu löschen. Ich nutze eher die Purge Templates oder das Ignorieren über Kommentare.

Tailwind Ökosystem

Ein Grund, warum ich an Tailwind hängen geblieben bin, ist auf jeden Fall das Ökosystem, was sich um Tailwind entwickelt hat.

  • Tailwind UI: Wer die UI Components von Bootstrap vermisst, findet mit den Tailwind UI Components eine gute (aber kostenpflichtige) Alternative. Die Erschaffer von Tailwind, Adam Wathan und Steve Schoger, haben typische UI-Components mit Tailwind umgesetzt, die sich dank Tailwind auch sehr leicht verändern lassen.
  • Refactoring UI: Ebenfalls von Adam & Steve gibt es ein kostenpflichtiges E-Book, wie man schöne UI’s selber designt und das aus dem Blickwinkel eines Entwicklers.
  • Tailwind Forms: Das TailwindCSS Plugin sorgt für grundlegenden Style von Form-Elementen. Besonders nützlich in Zusammenarbeit mit WordPress, weil man an viele Inputs, z.B. für Kommentare, sonst nicht so einfach herankommt.
  • Tailwind Typography: Ein weiteres Tailwind Plugin, welches für die prose Klasse für eine schöne Typografie sorgt. Nutze ich auch hier im Block, ist mit an eigenen Stellen aber schon zu aggressiv und ich musste eigene Styles überschreiben.

Fazit

Ich bin definitiv ein großer Fan von Tailwind, kann es aber trotzdem nicht uneingeschränkt für den Einsatz mit WordPress empfehlen. Ihr solltet gut abwägen, ob ihr mit den Einschränkungen klarkommt.

Falls ihr Tailwind einfach mal ausprobieren wollt, kann ich euch den Tailwind Spielplatz empfehlen und selbst wenn ihr euch gegen Tailwind entscheidet, kann ich euch trotzdem die Tailwind Dokumentation als grundlegende CSS-Dokumentation ans Herz legen.

Laravel Tools für WordPress: Webpack in elegant mit Laravel Mix 6

In der kleinen Serie zu Laravel Tools für WordPress, habe ich euch bereits Laravel Valet für die lokale Entwicklungsumgebung vorgestellt. Heute geht es wieder um ein Tool, was euch bei der Entwicklung von Themes & Plugins helfen kann. Besonders, wenn ihr an Block Editor (Gutenberg) Blöcken schraubt.

Laravel Mix vereinfacht euch die Arbeit mit Webpack enorm und spätestens, wenn ihr euren ersten Block in JavaScript programmiert, kommt ihr nicht mehr an Webpack (oder einem anderen JavaScript-Modul-Packer) vorbei. Die Konfiguration von Webpack empfinde ich aber als sehr kompliziert. Vor allem, wenn man noch nie mit React gearbeitet hat. Laravel Mix nimmt euch die Konfiguration in 80% der Fälle ab und reduziert den Konfigurationsaufwand extrem.

Weiterlesen „Laravel Tools für WordPress: Webpack in elegant mit Laravel Mix 6“

Vue.js Components im WordPress Block Editor / Gutenberg anzeigen

Gutenberg basiert ja (leider) auf React. Ich programmiere aber schon seit Jahren viel lieber mit Vue.js. Zwar habe ich mich damit abgefunden Blöcke für den Block Editor aka Gutenberg in React zu schreiben (wobei man nur sehr begrenzt eigentlich React verwendet, eher noch JSX), aber trotzdem verwende ich für einige Blöcke Vue.js. Im Fronend kein Problem, aber eine Vorschau im Block Editor angezeigt zu bekommen, inkl. Änderungen an den Attributen, war eine echte Herausforderung.

Weiterlesen „Vue.js Components im WordPress Block Editor / Gutenberg anzeigen“

WordPress 5.6: Standard für die Verlinkung von Bildern setzen

Mit WordPress 5.6 wird endlich wieder die Option image_default_link_type im Block Editor/Gutenberg berücksichtigt. Für ihr oder ein anderer Nutzer eurer Website einen neuen Bild- oder Gallerie Block ein, werden die Bilder dann standardmäßig auf die Mediendatei, Anhangsseite oder (bisher der Standard) gar nicht verlinkt.

Weiterlesen „WordPress 5.6: Standard für die Verlinkung von Bildern setzen“

WordPress: Remote HTTP Request vor Timeouts absichern

Zusätzliche Daten & Informationen über einen HTTP Requests in einem WordPress Plugin oder Themen zu laden ist eine sehr schöne Möglichkeit den eigenen Content mit zusätzlichen Informationen anzureichern. Ich nutzte für Travel-Dealz.de mehrere APIs z.B. um Klimadiagramme für Reiseziele bereitzustellen oder Status- und Vielfliegermeilen für einen Flug zu berechnen.

Allerdings werden die Abfragen i.d.R. beim Seitenaufruf durchgeführt und das kann den Seitenaufruf für den Besucher der Seite stark verzögern oder im schlimmsten Fall zu einem Timeout führen = der Besucher erhält nur eine Fehlermeldung und verlässt die Seite wieder.

Weiterlesen „WordPress: Remote HTTP Request vor Timeouts absichern“

WordPress Snippets für Custom Post Status

In WordPress gibt es Custom Post Types, Custom Fields, Custom Taxonomies und auch Custom Post Status, um neben Draft, Future, Pending, Private, Publish und Trash eigene Custom Post Status bereitzustellen. Leider wird das Thema in den letzten Jahren sehr stiefmütterlich behandelt und man kann schnell Eindruck gewinnen, dass man am liebsten Custom Post Status komplett aus dem Core entfernen würde. So werden Custom Post Status nicht mehr wirklich in Gutenberg berücksichtigt und ein Ticket, dass Custom Post Status automatisch in die UI bringen soll, ist seit geschlagenen 11 Jahren offen!

Trotzdem haben Post Status meiner Meinung nach einen entscheidenden Vorteil: Sie werden direkt in der wp_posts Tabelle in der post_status Spalte mit einem Index gespeichert. Filtern oder sortieren anhand dieser Spalte ist damit extrem schnell und erfordert kein JOIN zu einer anderen Tabelle, z.B. wp_postmeta im Fall von Custom Post Fields.

Weiterlesen „WordPress Snippets für Custom Post Status“

WordPress 5.5: Standard Block Vorlagen (Patterns) entfernen

Mit WordPress 5.5 sind endlich die Block Patterns, auf Deutsch Block Vorlagen, in den Core eingezogen. Damit könnt ihr Patterns = Vorlagen für mehrere Blöcke in z.B. der functions.php in eurem Theme erstellen und den Nutzer im Block Editor bereitstellen.

WordPress liefert auch standardmäßig ein paar Beispiele mit. Wem diese Beispiele nicht zusagen, muss die Patterns ebenfalls über die functions.php entfernen.

Weiterlesen „WordPress 5.5: Standard Block Vorlagen (Patterns) entfernen“

Scripts Aktions-abhängig laden, z.B. wenn ein Button geklickt wird

Für WordPress und natürlich andere CMS gibt es tausende Plugins und viele davon laden eigene Scripts und Styles bei euch im Frontend. Die Anzahl und vor allem die Größe kann eure Website-Performance massiv beeinträchtigen. Wie man Plugins dazu bringt, Scripts & Styles nur zu laden, wenn sie wirklich notwendig sind, habe ich euch bereits gezeigt.

Es gibt aber Elemente z.B. Share-Buttons oder Autosuggest-Suchen die sind auf jeder Seite vertreten, werden aber nur bei einem Bruchteil der Seitenaufrufe wirklich von Nutzer genutzt. Nur, wenn der User den Beitrag teilen möchte oder eine Suche eintippt.

Ziel ist es an dieser Stelle das benötigte Script erst zu laden, wenn man sich sehr sicher ist, dass der Nutzer die Aktion ausführen will. Im Idealfall muss der User vorher auf einen Button klicken aber auch wenn der User mit der Maus über dem Suchfeld oder Button schwebt, kann als Auslöser herangezogen werden.

Weiterlesen „Scripts Aktions-abhängig laden, z.B. wenn ein Button geklickt wird“

WordPress Website als App (PWA) im Google Play Store veröffentlichen

Immer mehr Menschen nutzen nur noch ihr Smartphone und dort werden vor allem Apps genutzt. Doch eine App zu programmieren und vor allem zu pflegen kann neben der eigenen WordPress Website sehr zeitaufwendig sein.

Ich kann davon mit Travel-Dealz ein Lied singen. Alle Features einer modernen Website in einer App abzubilden ist mit immensem Aufwand verbunden. Dabei kann man Websites so gut mobil optimieren, dass eine zusätzliche App eigentlich überhaupt nicht notwendig ist.

Seit einigen Jahren gibt es bereits sogenannte Progressive Web Apps, kurz PWA. Websiten, die zahlreiche Merkmale von nativen Apps besitzen. Sie können wie eine App auf dem Smartphone „installiert“ werden und man findet auf dem Homescreen das App-Icon. Öffnet man die PWA, wird einfach die Website in einem Webview (nicht im Browser) geöffnet. Außerdem sind Push Notifications oder Offline-Funktionen möglich.

Der größte Nachteil ist aber, dass man nicht im App Store für iPhone/iPad oder im Google Play Store für Android vertreten ist.

Zumindest im Google Play Store kann man mittlerweile aber seine Progressive Web App wie eine ganz normale native App veröffentlichen! Deswegen zeige ich euch in diesem Artikel, wie ihr aus eurer WordPress Website eine Progressive Web App macht und diese anschließend im Google Play Store veröffentlicht!

Weiterlesen „WordPress Website als App (PWA) im Google Play Store veröffentlichen“