Halaman dokumen menggulir utuh dari atas ke bawah; dashboard tidak. Pada aplikasi web, kerangkanya — sidebar dan header — tetap diam, dan hanya area isinya yang menggulir. Perilaku ini disebut app shell, dan dicapai dengan satu kombinasi yang belum kita rakit sebelumnya: grid berperilaku setinggi viewport plus overflow pada area tertentu. Chapter ini sekaligus menjadi bukti komposisi: hampir semua bagiannya adalah pola yang sudah kita buat di section ini.
Kerangka App Shell Setinggi Viewport #
.shell {
display: grid;
height: 100dvh;
grid-template-columns: minmax(220px, 260px) 1fr;
grid-template-rows: auto 1fr;
grid-template-areas: "samping kepala" "samping isi";
overflow: hidden;
}Perhatikan bedanya dengan layout sidebar yang kita rakit sebelumnya. Di sana, halaman menggulir utuh dan sidebar memakai position: sticky untuk tetap terlihat. Di sini strateginya berbalik: height: 100dvh mengunci kerangka pada tinggi viewport, overflow: hidden mencegah halaman ikut menggulir, dan baris auto 1fr memberi header tinggi sesuai isinya lalu menyerahkan sisa tinggi kepada area isi. Sidebar pun tidak butuh sticky — dia memang tidak pernah bergerak.
Area Isi yang Menggulir #
Kunci terakhir pola ini adalah satu deklarasi yang mudah terlewat:
.area-isi {
grid-area: isi;
overflow-y: auto;
min-height: 0;
padding: 24px;
}min-height: 0 terlihat mencurigakan, tetapi inilah bagian terpenting pola ini. Item grid secara default tidak boleh lebih kecil dari kontennya (ukuran minimum otomatis, persis seperti 1fr yang meluber pada layout sidebar). Tanpa min-height: 0, konten yang panjang memaksa baris 1fr bertambah tinggi melebihi shell, dan seluruh halaman kembali menggulir — pola ini gagal diam-diam. Dengan min-height: 0, area isi menerima tinggi berapa pun yang disediakan barisnya, lalu overflow-y: auto mengurus sisanya di dalam.
Merangkai Pola-Pola Sebelumnya #
App shell adalah titik temu dari section ini. Setiap wilayahnya adalah pola yang sudah kita rakit sebagai chapter tersendiri:
| Wilayah | Pola yang dipakai | Sumbernya |
|---|---|---|
| Header | Latar penuh dengan baris flex brand plus aksi | Pola: Header dan Navigation |
| Sidebar | Kolom minmax(220px, 260px) dengan daftar menu | Pola: Sidebar Layout |
| Grid kartu statistik | repeat(auto-fit, minmax()) di dalam area isi | Pola: Card Grid |
| Laporan selebar penuh | grid-column: 1 / -1 di dalam grid konten | Pola: Card Grid dan materi grid |
| Konten terpusat | Centered container di dalam area isi | Pola: Centered Container |
Karena area isi adalah elemen biasa, isi bebas memakai pola apa pun di dalamnya: container 960px untuk halaman pengaturan, grid kartu untuk statistik, atau layout artikel untuk laporan. Kerangka tidak peduli isinya — itulah nilai pola ini.
Demo berikut merakit shell lengkap. Gulir area isinya dan perhatikan sidebar dan header tetap diam:
Kesalahan Umum #
| Kesalahan | Akibatnya | Perbaikannya |
|---|---|---|
min-height: 0 terlewat pada area isi | Konten panjang memaksa baris 1fr melebihi shell, halaman ikut menggulir utuh | Tambahkan min-height: 0 sebelum overflow-y: auto |
Shell tanpa overflow: hidden | Gulir halaman masih bisa terpicu oleh konten yang meluber | Kunci kerangka dengan overflow: hidden |
Tinggi memakai 100vh | Bagian bawah kerangka tertutup address bar ponsel | Gunakan 100dvh seperti yang dibahas di chapter Viewport Units |
Sidebar diberi position: sticky | Sticky tidak berperan karena halaman memang tidak pernah menggulir | Lepaskan sticky; sidebar yang diam adalah perilaku shell |
Ringkasan #
Dashboard layout menukar strategi dari pola sidebar biasa: alih-alih halaman menggulir dengan sidebar sticky, kerangkanya dikunci setinggi viewport dan area isilah yang menggulir. overflow: hidden pada shell, overflow-y: auto plus min-height: 0 pada area isi adalah pasangan yang membuatnya bekerja. Setiap wilayahnya ternyata pola lama yang dipasang ulang — bukti bahwa section ini membangun satu kosakata layout yang menyambung. Pola berikutnya menutup halaman dari sisi sebaliknya: footer.