Dlaczego Tailwind CSS ogranicza skalowalne systemy projektowe: analiza podejść
Tailwind CSS przyspiesza prototypowanie, ale jego utylitarny podejście prowadzi do problemów przy skalowaniu. W systemach projektowych komponenty takie jak przyciski wymagają kombinacji wariantów, rozmiarów i stanów. Dodanie nowej wariacji, na przykład btn-focus, musi zachować zgodność z btn-sm, btn-lg, btn-outline. Stany takie jak hover (ciemniejsze o 15%) lub active (jaśniejsze o 10%) muszą być stosowane systemowo. W klasycznych frameworkach rozwiązuje się to za pomocą mixinów, na przykład:
.button-variant-other(@color; @background; @border);
Tailwind nie oferuje wbudowanych mechanizmów dla takiej integracji bez kompromisów.
CVA: szybko, ale ograniczone
Shadcn używa CVA dla przycisków z ustalonymi wariantami i rozmiarami:
variant "default" | "outline" | "ghost" | "destructive" | "secondary" | "link"
size "default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg"
Zalety:
- Szybki rozwój bez przełączania między plikami.
- Czysty API dla podstawowych przypadków.
Wady ujawniają się w długoterminowych projektach:
- Niemożliwe stworzenie
primary outlined smallbez rozszerzenia. - Ustalony zestaw kombinacji gromadzi techniczny dług przez 6+ miesięcy.
Dla prostych projektów jest to akceptowalne, ale w rozwoju enterprise prowadzi do wzrostu kosztów.
Zmienne CSS: uniwersalne rozwiązanie
Podejście z zmiennymi CSS oddziela logikę stanów od wariantów:
.btn {
@apply inline-flex items-center justify-center rounded px-4 py-2 font-body;
background-color: var(--btn-color);
color: var(--btn-text, white);
}
.btn:hover {
background-color: color-mix(in srgb, var(--btn-color), black 15%);
}
.btn:active {
filter: brightness(1.1);
}
.btn-primary {
--btn-color: theme('colors.blue.600');
}
.btn-whatever {
--btn-color: …;
}
Kluczowe plusy:
- Automatyczne stany dla dowolnych kolorów.
- Łatwo dodawać warianty przez zmienne.
- Zgodne z dowolnymi bibliotekami UI.
Minus dla Tailwind: utrata prędkości, ponieważ style są przenoszone do osobnych plików.
Dyrektywa @utility: prowizorka dla utility
Dyrektywa generuje klasy dynamicznie:
@utility btn-* {
font-size: --value(--text-ui-*, [length]);
background-color: --value(--color-ui-*, [color]);
color: --value(--color-ui-*-text, [color]);
}
To pozwala łączyć z modyfikatorami Tailwind dla hover lub responsive. Jednak:
btn-focusnie jest przeznaczony dlasmlublg— klasy funkcjonalne nie skalują się.- Tworzenie
primary small outlinewymaga kruchej wariacji w komponentach. - System załamuje się przy złożonych kombinacjach.
Porównanie podejść
| Podejście | Prędkość | Skalowalność | Integracja stanów | Zależność od Tailwind |
|--------|----------|------------------|----------------------|-------------------------|
| CVA | Wysoka | Niska | Ograniczona | Pełna |
| Zmienne CSS | Średnia | Wysoka | Pełna | Niska |
| @utility | Średnia | Średnia | Częściowa | Wysoka |
CVA nadaje się dla MVP, zmienne CSS — dla production, @utility — opcja pośrednia.
Co jest ważne
- Tailwind nie narzuca struktury: utylitarność wymaga samodzielnie zbudowanego systemu.
- Komponenty jako klasy: ogranicza złożone systemy projektowe ustalonymi opcjami.
- Techniczny dług: prostota na starcie prowadzi do refaktoringu po pół roku.
- Alternatywy działają: zmienne CSS dają elastyczność bez utraty Tailwind.
Tailwind idealny dla szybkiego startu, ale dla dojrzałych systemów projektowych wymaga hybrydowych rozwiązań lub rezygnacji ze ścisłej utylitarności.
— Editorial Team
Brak komentarzy.