module.exports = {
theme: {
extend: {
colors: {
brand: {
light: '#5c6ac4',
DEFAULT: '#4141e0',
dark: '#202223',
}
},
spacing: {
'content-gap': '24px', // token semantic, nu doar o valoare oarecare
}
}
}
}Am văzut zeci de proiecte în care tailwind.config.js devenise o groapă de gunoi pentru fiecare padding ciudat cerut de designeri. Sau, mai rău, proiecte pline de w-[327px] și bg-[#f0f0f0] de zici că scriam CSS inline direct în HTML-ul ăla vechi din 2012. Astăzi vreau să vă arăt cum facem noi demarcația între cele două în proiectele reale, ca să nu ne luăm de cap la refactoring.
Capcana parantezelor drepte
Arbitrary values (-[...]) sunt o binecuvântare și un blestem. Au apărut ca să rezolve problema aia enervantă din primele versiuni de Tailwind: când aveai nevoie de o singură poziționare ciudată și trebuia să mergi în config să inventezi o clasă nouă gen spacing-7.5 pe care nu o mai folosea nimeni niciodată.
Dar am pățit-o la un proiect SaaS cu vreo 12.000 de utilizatori activi. Fiecare developer din echipă a început să bage bg-[#1a2b3c] și text-[15px] direct în componente, ca să termine task-ul mai repede. După șase luni, când clientul a vrut un rebranding minor pe culorile de brand, am descoperit că aveam vreo 35 de nuanțe diferite de albastru în toată aplicația. A fost nevoie de două zile întregi de search-and-replace manual și de teste de regresie vizuală ca să curățăm mizeria.
Când e OK să folosești arbitrary values?
Nu sunt adeptul regulilor extremiste de genul „interzis paranteze drepte prin reguli de linter”. Sunt cazuri unde chiar au sens și te salvează de la a polua fișierul de configurare:
- Poziționări absolut unice: Un element decorativ din fundal care trebuie să stea la
top-[112px] right-[-20px]. Știi sigur că n-o să mai folosești coordonatele astea nicăieri altundeva în aplicație. - Valori dinamice: Când înălțimea sau lățimea unui element depinde de un calcul din runtime, deși aici adesea e mai curat să folosești proprietatea standard
stylea elementului. - Integrarea cu librării terțe: Când ai o hartă interactivă sau un widget de chat și trebuie să-i forțezi o dimensiune fixă, gen
h-[450px], ca să se alinieze cu restul layout-ului.
Merge brici pentru prototipuri rapide sau landing page-uri pe care le arunci după o campanie de marketing de o lună. E absolut horror pentru aplicații mari, unde consistența vizuală e critică.
Regula celor trei utilizări pentru Design Tokens
La noi în echipă am stabilit o regulă simplă: regula celor trei utilizări.
Dacă ai nevoie de o valoare customizată în cel puțin trei locuri diferite din cod, acea valoare devine oficial un "design token" și trebuie să meargă direct în config. De exemplu, dacă designerul vine cu un font-size nou de 13px pentru tooltip-uri, etichete de formular și tabele, nu scriem text-[13px] peste tot. Mergem frumos în config și extindem tema în mod semantic.
Trade-off-ul sincer
Dacă ești foarte strict cu design system-ul și pui absolut totul în config, o să pierzi timp la început. Trebuie să te pui de acord cu designerul pe denumiri semantice (brand-primary, neutral-muted etc.). În schimb, când faci refactoring sau când adaugi Dark Mode, ești boier. Schimbi trei linii în config și s-a rezolvat în tot proiectul.
Dacă mergi pe arbitrary values, livrezi feature-ul cu 20% mai repede astăzi, dar plătești cu dobândă mare peste 6 luni când codul devine de neîntreținut.
Cum gestionați asta în echipele voastre? Aveți o regulă clară sau e vestul sălbatic în PR-uri?