Tailwind untuk Brutalist Design System (Tanpa Spaghetti Class)
Token konsisten, utility reusable, dan komponen tetap brutal tapi maintainable. Ini cara kita bikin design system brutalist pake Tailwind tanpa bikin class jadi berantakan.
DaunsCode Editorial Team
admin@daunscode.com • 13 Feb 2026
Brutalist Design Itu Apa Sih?
Buat yang belum familiar, brutalist web design itu gaya desain yang terinspirasi dari arsitektur brutalis. Karakteristiknya: raw, bold, nggak banyak dekorasi, tipografi gede gede, border tebal, dan overall vibe nya "ini website, bukan majalah fashion".
Kenapa kita pilih brutalist? Karena di tengah lautan website yang semuanya keliatan sama (rounded corners, gradient, glassmorphism), brutalist design itu standout. Orang langsung inget.
Masalah Tailwind + Brutalist
Tailwind itu utility first CSS framework. Artinya kamu nulis style langsung di HTML pake class class kecil. Ini powerful tapi bisa jadi masalah kalau nggak dimanage:
// ini nightmare
<div className="border-2 border-black bg-white p-4 shadow-[4px_4px_0_0_black]
hover:shadow-[6px_6px_0_0_black] hover:-translate-y-0.5 transition-all
duration-200 text-black font-black tracking-tight uppercase text-sm
flex items-center justify-between gap-4">
Class nya sepanjang kereta api. Dan ini baru satu elemen. Bayangkan kalau satu halaman ada puluhan elemen kayak gini.
Solusi: Design Token + CSS Custom Properties
Langkah pertama: definisiin design token di CSS variables.
:root {
--bg: #e9e9e9;
--paper: #f7f7f7;
--ink: #090909;
--muted-ink: #5f5f5f;
--signal: #ff1b1f;
--signal-dark: #be1218;
}
.dark {
--bg: #0a0a0a;
--paper: #181818;
--ink: #f5f5f5;
--muted-ink: #c7c7c7;
--signal: #ff1f1f;
}
Dengan cara ini, dark mode jadi otomatis. Komponen cuma perlu reference variable, nggak perlu dark: prefix di mana mana.
Komponen Reusable
Daripada nulis class panjang berulang ulang, kita bikin komponen yang encapsulate style:
function BrutalCard({ children, className }) {
return (
<div className={`border-2 border-current bg-[var(--paper)]
shadow-[4px_4px_0_0_currentColor] card-lift ${className}`}>
{children}
</div>
);
}
Sekarang setiap kali butuh card, cukup <BrutalCard>. Clean.
CSS Layer untuk Hover Effects
Buat hover effects yang konsisten, kita bikin class utility di CSS:
.card-lift {
transition: transform 0.2s, box-shadow 0.2s;
}
.card-lift:hover {
transform: translateY(-3px);
box-shadow: 6px 6px 0 0 currentColor;
}
.btn-brutal {
position: relative;
overflow: hidden;
transition: color 0.3s;
}
.btn-brutal::before {
content: "";
position: absolute;
inset: 0;
background: currentColor;
transform: translateY(100%);
transition: transform 0.3s;
}
.btn-brutal:hover::before {
transform: translateY(0);
}
Class btn-brutal bikin efek slide fill yang keren. Background warna naik dari bawah pas di-hover. Brutalist banget tapi smooth.
Tipografi System
Di brutalist design, tipografi itu segalanya. Kita setup:
- Font utama: Geist Sans (clean, modern, variable font)
- Font mono: Geist Mono (buat label, tag, metadata)
- Heading: font-black (900 weight), tracking-tight, uppercase buat yang kecil
- Body: normal weight, line height yang nyaman buat baca
Contoh utility class:
.mono {
font-family: var(--font-mono);
text-transform: uppercase;
letter-spacing: 0.05em;
}
Class mono dipake buat semua label, metadata, dan tag. Konsisten di seluruh website.
Layout Grid
Buat layout, kita pake container class yang konsisten:
.container-grid {
max-width: 1280px;
margin: 0 auto;
padding: 0 1.5rem;
}
Simpel tapi efektif. Semua section pake container yang sama jadi alignment nya konsisten.
Animasi yang Subtle
Brutalist bukan berarti nggak boleh ada animasi. Tapi animasinya harus purposeful:
- Scroll reveal elemen muncul pas user scroll ke situ
- Hover feedback kasih tau user kalau elemen itu interaktif
- Page transition biar perpindahan halaman nggak kaku
Kita bikin komponen Reveal yang support berbagai direction:
<Reveal direction="up">Muncul dari bawah</Reveal>
<Reveal direction="left">Slide dari kiri</Reveal>
<Reveal direction="scale">Zoom in</Reveal>
Semua pakai IntersectionObserver jadi cuma trigger pas elemen masuk viewport. Performance friendly.
Dark Mode yang Nggak Ribet
Karena semua warna pakai CSS variables, dark mode implementation jadi gampang banget:
- Define variable buat light dan dark di
:rootdan.dark - Semua komponen reference variable, bukan hardcode warna
- Toggle class
.darkdi<html>element
Hasilnya? Dark mode yang konsisten tanpa harus nambahin dark: prefix di ratusan tempat.
Tips Biar Nggak Spaghetti
Beberapa prinsip yang kita pegang:
- Kalau class lebih dari 5 6, bikin komponen jangan biarkan div punya 20 class
- Pakai CSS variables buat warna jangan hardcode hex di utility class
- Bikin utility class buat pattern yang berulang kayak card-lift, btn-brutal
- Konsisten sekali mutusin pattern, stick sama itu. Jangan mix berbagai approach
- Prefers reduced motion selalu respectin user yang nggak mau animasi
Kesimpulan
Tailwind dan brutalist design itu bisa jalan bareng kok tanpa bikin codebase jadi berantakan. Kuncinya: design token lewat CSS variables, komponen reusable, dan utility class buat pattern yang berulang.
Hasilnya website yang keliatan raw dan bold tapi codebase nya clean dan maintainable. Win win.
Ready to build the next big thing?
DaunsCode siap bantu arsitektur, UI, dan implementasi produk digital yang scalable untuk bisnis kamu.
Let's Talk Project