Da jeg først så Tailwind CSS, var reaksjonen den samme som de fleste: "Hvorfor skal jeg skrive klassenavn som ser ut som inline styles?" Etter å ha brukt BEM-konvensjoner, CSS Modules og til og med styled-components, føltes det som et steg bakover. Men etter å ha bygd to komplette prosjekter med Tailwind — denne porteføljen og Tuli sin frontend — har jeg endret mening fullstendig.
Tailwind er ikke bare klassenavn. Det er et designsystem som bor i koden, og det har fundamentalt endret hvordan jeg jobber med frontend.
Hvorfor utility-first slår alt annet for meg
Problemet med tradisjonell CSS — BEM, CSS Modules, eller til og med styled-components — er at du alltid ender opp med å ta to beslutninger: hva skal komponenten se ut som, og hva skal CSS-klassen hete? Det høres trivielt ut, men over tid blir navngivning en konstant kognitiv belastning. .card-header__title--highlighted eller .card-title-highlight? Det spiller ingen rolle — begge er vilkårlige.
Med Tailwind forsvinner navngivningsproblemet. Stilen er direkte i komponentkoden. Når jeg ser <div className="rounded-2xl bg-white/10 backdrop-blur-xl border border-white/20 p-6">, vet jeg nøyaktig hva elementet ser ut som uten å åpne en CSS-fil.
Men den virkelige gevinsten er konsistens. Tailwind tvinger deg til å bruke forhåndsdefinerte verdier — p-4 (1rem), p-6 (1.5rem), p-8 (2rem). Ingen vilkårlige pikselverdier som padding: 13px eller margin-top: 7px. Resultatet er at hele appen føles visuelt sammenhengende, selv når forskjellige utviklere jobber på forskjellige deler.
Glassmorphism-designsystemet på porteføljen
Denne porteføljen bruker en glassmorphism-estetikk — halvtransparente elementer med blur-effekter over en mørk bakgrunn. Med Tailwind kan jeg definere dette som et konsistent mønster uten en eneste custom CSS-klasse:
function GlassCard({ children, className }: { children: React.ReactNode; className?: string }) {
return (
<div className={`
rounded-2xl
bg-white/5
backdrop-blur-xl
border border-white/10
shadow-lg shadow-black/20
transition-all duration-300
hover:bg-white/10 hover:border-white/20 hover:shadow-xl
${className ?? ''}
`}>
{children}
</div>
);
}
// Brukes slik:
<GlassCard className="p-6">
<h3 className="text-lg font-semibold text-white">Prosjektnavn</h3>
<p className="mt-2 text-sm text-gray-400">Beskrivelse her.</p>
</GlassCard>Legg merke til mønsteret: basisstilen er i komponenten, men spacing og innhold er fleksibelt via className-propen. Hover-effekten (hover:bg-white/10) er deklarert rett i markup. Ingen separate :hover-regler i en CSS-fil.
Responsive design uten media queries
En av Tailwinds største styrker er responsive modifikatorer. Istedenfor å skrive media queries i en separat fil, definerer jeg responsive atferd direkte:
<div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
{projects.map((project) => (
<GlassCard key={project.slug} className="p-6">
<h3 className="text-base font-semibold text-white md:text-lg">
{project.title}
</h3>
<p className="mt-2 text-sm leading-relaxed text-gray-400">
{project.excerpt}
</p>
</GlassCard>
))}
</div>grid-cols-1 md:grid-cols-2 lg:grid-cols-3 — én kolonne på mobil, to på tablet, tre på desktop. Alt på én linje. Ingen @media (min-width: 768px) spredt utover forskjellige filer.
Prefixene er mobile-first: uprefixede klasser gjelder alltid, md: gjelder fra 768px, lg: fra 1024px. Det tvinger deg til å designe mobil først, som er god praksis uansett.
Tilpasning via konfigurasjonen
Tailwind ut av boksen er bra, men den virkelige kraften kommer når du tilpasser konfigurasjonen til prosjektets designsystem:
// tailwind.config.ts
const config = {
theme: {
extend: {
colors: {
glass: {
light: 'rgba(255, 255, 255, 0.05)',
medium: 'rgba(255, 255, 255, 0.10)',
heavy: 'rgba(255, 255, 255, 0.20)',
},
},
backdropBlur: {
xs: '2px',
},
animation: {
'fade-in': 'fadeIn 0.5s ease-out',
'slide-up': 'slideUp 0.6s ease-out',
},
},
},
};Nå kan jeg bruke bg-glass-light, bg-glass-medium og bg-glass-heavy overalt i prosjektet. Hvis designet endrer seg, oppdaterer jeg verdien ett sted og alt følger med. Det er et ekte designsystem — ikke bare tilfeldige utility-klasser.
Når Tailwind IKKE er svaret
Tailwind er ikke perfekt for alt. For kompleks animasjonslogikk, der keyframes avhenger av JavaScript-state, er det ofte bedre å bruke CSS-in-JS eller vanlig CSS med CSS-variabler. For tredjepartskomponenter som kommer med egen styling, kan det bli rotete å overstyre med Tailwind-klasser.
Og for enkle statiske sider der du skriver HTML for hånd uten komponenter? Da mister du den største fordelen — gjenbrukbare komponentmønstre — og ender opp med duplisert markup.
Oppsummering
Tailwind CSS handler ikke om å skrive CSS på en annen måte. Det handler om å bygge et designsystem direkte i komponentkoden. Ingen navngivning, ingen filer å holde synkronisert, ingen vilkårlige verdier. Kombinert med React-komponenter gir det en utvikleropplevelse der design og kode lever i perfekt harmoni.
Start med de innebygde verdiene, bygg komponentmønstre som GlassCard, og utvid konfigurasjonen når prosjektet krever det.