Mobile-First & Responsive — UI/UX

Mobile-First — Desain dari Layar Kecil Mobile-first berarti mendesain untuk layar mobile terlebih dahulu, lalu menambahkan complexity untuk layar yang lebih…

Responsive artinya satu halaman yang menyesuaikan diri dengan tiap lebar layar, dari HP sampai monitor. Mobile-first adalah cara menulisnya: CSS untuk layar paling kecil ditulis dulu, tanpa media query, lalu aturan baru ditambahkan dengan @media (min-width: ...) setiap kali layarnya cukup lebar. Bayangin berkemas untuk liburan. Kalau kamu mulai dari ransel kecil, kamu terpaksa memilih yang penting dulu: baju ganti, charger, obat. Dapat koper besar, tinggal menambah. Kalau mulai dari koper penuh lalu harus pindah ke ransel, kamu membongkar dengan buru-buru, dan yang penting bisa tertinggal.

🧪 Tebakan cepat: Kartu kamar Bu Sri dibuat mendatar (foto di kiri) dengan @media (min-width: 600px). Di HP yang dimiringkan, layar 667px, kartunya selebar 635px dan tampil bagus. Di tablet 768px, tiga kartu berjajar dan tiap kartu cuma 224px. Apa yang terjadi pada kartu di 768px? Jawabannya ada di bagian "Container query: kartu yang menyesuaikan tempatnya".

Kenapa mulai dari HP

Angka "70%+ traffic web Indonesia dari HP" sering dikutip, dan itulah jawaban yang diminta kuis. Datanya dari StatCounter (persentase page view yang dilacaknya, bukan jumlah orang): 70,18% di 2016 dan 74,35% di 2017. Sesudahnya naik turun: 66,56% di 2022, 63,06% di 2023, 64,78% di 2024, 61,51% di 2025, dan cuma 45,29% untuk Januari sampai September 2026. Pelajarannya: sebut tahunnya kalau mengutip angka, dan lebih baik lagi, lihat analytics situsmu sendiri.

Alasan yang gak tergantung angka itu ada dua:

Viewport meta dulu

<meta name="viewport" content="width=device-width, initial-scale=1">

Tanpa baris ini, browser HP berpura-pura layarnya 980px, menyusun halaman selebar itu, lalu mengecilkannya. Kami mencobanya di emulasi HP 375px (Chromium dan WebKit): tanpa meta, lebar halaman 980px, tiga kolom muncul, dan semuanya diperkecil sampai teksnya susah dibaca. Dengan meta, lebarnya 375px dan media query bekerja seperti seharusnya.

Base dulu, lalu min-width

/* Dasar: berlaku dari 320px, tanpa media query */
.page  { max-width: 1200px; margin: 0 auto; padding: 16px; }
.rooms { display: grid; gap: 16px; }                     /* satu kolom */

/* 768px ke atas: tiga kolom, jarak lebih lega */
@media (min-width: 768px) {
  .page  { padding: 24px; }
  .rooms { grid-template-columns: repeat(3, 1fr); gap: 24px; }
}

Hasilnya, diukur di Chromium, WebKit, dan Firefox:

Layar Kolom Lebar kartu Kartu Judul (clamp())
320px 1 288px foto di atas 24px
375px 1 343px foto di atas 25,38px
667px (HP dimiringkan) 1 635px foto di kiri 32,67px
768px 3 224px foto di atas 35,2px
1280px 3 384px foto di atas 40px

Breakpoint 768px gak dipilih karena merek tablet tertentu, tapi karena di situ tiga kartu mulai muat: (720 - 2 × 24) / 3 = 224px. Taruh breakpoint di tempat layoutmu mulai rusak atau mulai lowong.

Kebalikannya adalah desktop-first: desain tiga kolom dulu, lalu dikurangi dengan max-width. Yang sering terjadi saat pindah ke HP: layout patah, isinya meluber, dan bagian yang gak muat disembunyikan, sampai akhirnya didesain ulang dari nol. Kami mengukur halaman yang cuma punya CSS desktop (repeat(3, 1fr) tanpa media query) di 320px: browser gak menumpuk kolomnya sendiri. Tiap kartu jadi 74,67px, harga "Rp 350.000 / malam · 2 tamu" pecah jadi 4 baris, dan isi kartu meluber 24px keluar kartunya.

Container query: kartu yang menyesuaikan tempatnya

Media query bertanya ke layar. Di 768px layarnya lebar, jadi @media (min-width: 600px) membuat kartu mendatar, padahal kartunya cuma 224px. Foto 192px masuk, teks dapat sisa 81px: harga pecah 4 baris, isinya meluber 79px keluar kartu, dan seluruh halaman bisa digeser ke samping 54px (sama di tiga browser). Jadi jawaban tebakannya: kartunya rusak, karena media query gak tahu lebar kartu. Itu jawaban tebakannya.

Container query bertanya ke wadahnya:

.room { container-type: inline-size; }   /* tiap sel grid jadi container */

/* Kartu selebar 30rem (480px) ke atas: foto di kiri */
@container (min-width: 30rem) {
  .room-card { grid-template-columns: 12rem 1fr; }
  .photo { grid-row: 1 / span 3; height: auto; min-height: 120px; }
}

clamp(): ukuran huruf yang tumbuh

h1 { font-size: clamp(1.5rem, 1rem + 2.5vw, 2.5rem); }

clamp(min, nilai, max) memakai nilai di tengah, tapi gak pernah di bawah min atau di atas max. 1vw adalah 1% lebar layar. Di 768px: 16 + 0,025 × 768 = 35,2px. Batas bawah 24px tercapai tepat di 320px (16 + 8), batas atas 40px mulai 960px. Satu baris ini menggantikan beberapa media query untuk ukuran huruf, dan ukurannya tumbuh halus tanpa lompatan.

Bandingkan judul tetap 40px: "Homestay Kabut, Dieng" pecah jadi 2 baris di 320px dan 375px, dan memakan 96px tinggi layar sebelum tamu melihat kamar apa pun. Dengan clamp() judulnya 1 baris.

Simpan rem di dalam nilai tengahnya. 1rem ikut membesar kalau pengguna menaikkan ukuran huruf bawaan browser; vw cuma ikut lebar layar. Judul yang cuma 5vw gak membesar sedikit pun untuk orang yang butuh huruf lebih besar.

⚠️ Jebakan yang sering ketemu

TL;DR: Mobile-first: tulis CSS untuk layar terkecil dulu tanpa media query, lalu tambah aturan dengan @media (min-width: ...), selalu min-width. Mulai dengan <meta name="viewport" content="width=device-width, initial-scale=1"> (tanpanya HP menyusun halaman di 980px). Angka "70%+ traffic dari HP" adalah data StatCounter 2016 sampai 2017; 2025 tercatat 61,51%, jadi sebut tahunnya dan cek analytics sendiri. Uji di 320px (WCAG 1.4.10 Reflow), 375, 768, dan 1280px: halaman Bu Sri 1 kolom di HP (288px dan 343px), 3 kolom 224px di 768px dan 384px di 1280px. Desktop-first sering berakhir dengan layout patah, isi meluber, atau isi yang disembunyikan, sampai harus didesain ulang. Container query (container-type: inline-size dan @container (min-width: 30rem)) membuat kartu menyesuaikan lebarnya sendiri, bukan lebar layar. clamp(1.5rem, 1rem + 2.5vw, 2.5rem) membuat judul tumbuh dari 24px ke 40px (35,2px di 768px); simpan rem di dalamnya supaya ikut setelan ukuran huruf pengguna.

Yang akan kamu pelajari