Hoe Tailwind CSS ons 20% aan ontwikkeltijd bespaart

“Spaghetti-code”, was mijn eerste gedachte toen Arjen met Tailwind CSS op de proppen kwam. Hoe kan een techniek waarbij je opmaak en structuur door elkaar schrijft ons verder helpen? Dat klinkt eerder alsof we tien jaar terug gaan in de tijd.

Eerlijk is eerlijk. BEM – de techniek die we tot een jaar geleden gebruikten voor het structureren van onze CSS – zat ons steeds meer in de weg. Strikte isolatie tussen elementen maakte alles erg robuust, maar kostte ook veel tijd. Daarnaast waren veel keuzes arbitrair, maar tegelijkertijd niet specifiek genoeg om (intern) te standaardiseren.

Tijd om mijn initiële scepsis aan de kant te zetten en te zien of Tailwind inderdaad het antwoord is op onze vragen.

CSS wattus? Tail wie?

Even een stapje terug. Wanneer je naar een website kijkt bestaat deze voor een groot deel uit HTML en CSS. De eerste structureert de informatie die weergegeven wordt; de tweede zorgt vervolgens voor de opmaak. Om de structuur aan de opmaak te koppelen, hebben we een referentie (“class”) nodig.

Neem bijvoorbeeld een kaartje voor een nieuwsbericht: een “news-card”. Deze geven we vervolgens een rode achtergrond en een groene tekst door middel van CSS regels. BEM schrijft vervolgens een naamgeving voor die deze referenties tussen HTML en CSS structureert. Hiermee voorkom je dat je per ongeluk een regel overschrijft wanneer dit niet de bedoeling is. Daarnaast geeft het een extra laag van betekenis. Zo weet je bijvoorbeeld dat de “news-card__title” een subonderdeel is van het eerder genoemde kaartje.

Tailwind draait dit principe om. Door middel van het combineren van de verschillende referenties pas je de opmaak toe op de HTML-structuur. Op deze manier kan je dus in één opslag zien wat voor opmaak er toegepast wordt op zo’n element op de pagina. De referenties verwijzen namelijk naar hoe het element eruit ziet. Niet naar was het is. Op het eerste gezicht lijkt het misschien wat cryptisch, maar na wat gewenning is het meteen duidelijk dat een “bg-red” zorgt voor een element met een rode achtergrond.

Out with a BEM

Even terug naar BEM. Waarom was dat ook alweer zo’n goed idee? Eén van de belangrijkste voordelen van BEM is dat het voorziet in isolatie tussen verschillende onderdelen van een webpagina. CSS heeft namelijk een eigenaardige eigenschap; regels binnen Cascading Style Sheets kunnen soms onbedoeld door je volledige pagina structuur sijpelen. En dat blijkt soms best problematisch te zijn wanneer je met meerdere mensen in een project werkt. De kans is daardoor aanwezig dat je zomaar iets overschrijft terwijl dat niet de bedoeling is. What’s in a name, right?

BEM (kort voor Block Element Modifier) lost dit probleem op door regels in een bepaalde namespace (“block”) te zetten. Dit zorgt ervoor dat regels alleen binnen dit deel van de pagina toegepast worden, of in onderliggende delen (“elements”). Daarnaast voorziet het in een stukje naamgeving, maar dwingt dit niet af. Voldoende om naar je collega te signaleren waar het element zich bevindt binnen de pagina, maar continu nadenken over eenduidige naamgeving vereist behoorlijk wat discipline.

Hoewel deze vorm van isolatie een groot voordeel is, brengt het ook een aantal negatieve eigenschappen met zich mee. Want wat doe je wanneer er een nieuwe variant opduikt in het ontwerp? Voeg je een “modifier” toe op een bestaand BEM “block”? Maak je een compleet nieuw “block” aan? Volg jij het nog? Een beetje techneut probeert natuurlijke elke vorm van dubbeling te voorkomen, maar ze weet ook dat dit vaak het punt is waar ze zichzelf in de nesten werkt.

Bij Pixelpillow hebben we het geluk dat onze collega ontwerpers erg goed nadenken over het designsysteem. Maar zelfs binnen het meest strakke systeem zijn uitzonderingen noodzakelijk. Het maken van een uitzondering is altijd een dure aangelegenheid, maar zorgt vaak net voor dat stukje esthetiek dat anders vaak verloren gaat. Helemaal wanneer je een nog eens een nieuwe variant in je BEM code moet vrotten.

Met de wind in de rug

Een nieuwe techniek lijkt altijd interessant in abstracto, maar je weet pas echt of het haar belofte waarmaakt wanneer je het toepast binnen een “echt” project. Bij de eerstvolgende mogelijkheid stonden Arjen en collega Rick dus in de startblokken om met Tailwind aan de slag te gaan. Al snel werden een aantal dingen duidelijk:

Waarbij we voorheen veel tijd moeten steken in het bedenken van onnodige naamgeving, schrijf je nu lekker achter elkaar door. Binnen BEM was het namelijk altijd nodig om een referentie tussen de HTML en CSS te hebben. In Tailwind niet. Het is dus niet langer nodig om na te denken over hoe je een subtitel onder een afbeelding in een contactblok nu weer moet gaan noemen … (BEM: “.contact-card__header__subtitle”).

In Tailwind definieer je in een configuratie de kleuren, fonts en meeteenheden die je in een project wilt gebruiken. Binnen ons BEM systeem was dit ook het geval, maar het bleek in Tailwind niet langer nodig om van te voren alle varianten van een terugkerend element in kaart te brengen. Een uitzondering is zo gemaakt. We denken dus niet meer na over onnodige abstracties. Soms heeft die button daar nét wat meer ruimte nodig en het is dan fijn dat je snel een uitzondering kan maken op het designsysteem.

Een wijziging doorvoeren op een stuk code dat je collega heeft geschreven?  Makkelijk, want je ziet in één oogopslag hoe alles in elkaar zit. Daarnaast is er maar “one way to do it”, dus geen discussie over dingen die er niet echt toe doen (2 spaties…). Dit scheelt behoorlijk in de doorlooptijd en overdracht binnen een project. We corrigeren makkelijker elkaars werk en dat laat alles net even wat soepeler lopen.

We waren bang dat Tailwind onze “design systems” om zeep zou helpen omdat het maken van uitzonderingen een stuk makkelijker is. In de praktijk bleek dit in de praktijk mee te vallen omdat de Tailwind configuratie voldoende houvast biedt. De definitie van het systeem is simpelweg verplaatst: van het CSS bestand naar de HTML structuur van onze componenten, die vervolgens weer terug te vinden zijn in Storybook.

En nu?

Inmiddels is Tailwind de standaard voor nieuwe projecten bij Pixelpillow. Onze frontenders hebben niet langer het idee dat ze tegen de CSS structuur in werken, maar werken met het systeem mee. Dat geeft tijd en ruimte om wat extra aandacht te geven aan het detailleren van het ontwerp. En dat pilotproject? Dat hebben we 20% onder budget weten af te ronden, terwijl dat slechts de eerste kennismaking met Tailwind was.