Halaman profil belajarmu sekarang enak dipandang di monitor. Sekarang lakukan satu ujian sederhana: seret tepi jendela browser, sempitkan pelan-pelan sampai kira-kira selebar layar ponsel.
Terasa, kan. Dua kartu yang tadinya lega mulai berdesakan seperti penumpang kereta pagi. Nama situs dan menu saling dorong di baris yang sama. Padahal justru dari layar sekecil itulah kebanyakan orang membaca blog.
Kabar baiknya: masalah ini punya solusi yang rapi, dan namanya kamu mungkin sudah sering dengar. Responsive, kemampuan tampilan menyesuaikan diri dengan ukuran layar. Satu halaman, satu CSS, nyaman di ponsel maupun monitor lebar.
Episode ini penutup Session 2. Kita akan membuat seluruh kerja keras empat episode kemarin luwes di semua ukuran layar, dan dalam perjalanannya, membayar satu janji lama dari Session 1.
Yang Akan Dipelajari
Di akhir episode ini, kamu akan memahami apa itu responsive dan kenapa halamanmu ternyata sudah setengah responsive tanpa kamu sadari.
Kamu akan mengenal media query, cara menulis aturan CSS yang hanya berlaku pada kondisi layar tertentu, beserta istilah breakpoint, titik lebar tempat tampilan berubah.
Kamu juga akan mencicipi cara pikir mobile-first: menata untuk layar kecil dulu, lalu menambah kemewahan saat layarnya melebar; kita akan merefaktor CSS Episode 2.04 mengikuti cara pikir itu.
Terakhir, dua sentuhan aksesibilitas khas layar sentuh: area sentuh yang cukup besar dan garis focus yang tidak boleh dihilangkan.
Kita belum membahas menu hamburger yang butuh JavaScript, gambar responsive, atau breakpoint bertingkat-tingkat. Satu breakpoint yang dipilih dengan sadar sudah membawa halaman kita sangat jauh.
Janji Lama yang Dibayar: meta viewport
Sebelum menulis CSS baru, buka index.html dan lihat baris ini di dalam <head>, penghuni lama sejak Episode 1.02:
<meta name="viewport" content="width=device-width, initial-scale=1">Waktu itu kita hanya bilang: metadata yang membantu browser menyesuaikan halaman dengan layar perangkat, penjelasannya menyusul. Hari ini episodenya tiba.
Tanpa baris ini, browser ponsel berpura-pura menjadi layar lebar: halaman dirender selebar kira-kira 980px lalu diperkecil sampai muat, dan pembaca disuguhi teks mungil yang harus dicubit-cubit. Baris ini menghentikan sandiwara itu: width=device-width menyuruh browser memakai lebar layar yang sebenarnya, dan initial-scale=1 memulai tanpa zoom.
Semua teknik responsive hari ini berdiri di atas baris itu. Untunglah ia sudah terpasang sejak lama; kamu tinggal memetik hasilnya.
Kabar Baik: Halamanmu Sudah Setengah Responsive
Sekarang perhatikan bagian yang justru tidak bermasalah saat jendela disempitkan: kolom teksnya.
Itu bukan kebetulan. Di Episode 2.03, kita memasang max-width: 640px di main, bukan width: 640px. Batas atas, bukan lebar paksa. Di jendela yang lebih sempit dari 640px, main ikut menyempit dengan patuh, dan teksnya mengalir menyesuaikan diri.
Lebar yang mau mengalah seperti ini disebut flexible width, dan ia fondasi diam-diam dari semua layout responsive. Aturan praktisnya sederhana: hindari lebar mati. Biarkan element selebar alaminya, atau batasi dengan max-width; simpan width piksel untuk hal-hal yang memang harus tetap, seperti foto profil kita.
Jadi yang benar-benar bermasalah di layar sempit tinggal dua: galeri dua kolom dan navbar satu baris. Keduanya aturan yang kita tulis sendiri di Episode 2.04. Kita hanya perlu memberi tahu browser kapan aturan itu pantas dipakai.
Media Query: CSS dengan Syarat
Perkenalkan alat utamanya: media query, blok CSS yang hanya berlaku kalau syaratnya terpenuhi.
@media (min-width: 600px) {
.galeri-kartu {
grid-template-columns: 1fr 1fr;
}
}Cara membacanya: kalau lebar layar minimal 600px, jalankan aturan-aturan di dalam blok ini. Di layar yang lebih sempit, seluruh isi blok diabaikan, dan galeri mengikuti aturan dasarnya di luar blok.
Angka 600px itu disebut breakpoint: titik lebar tempat tampilan berganti bentuk. Dari mana angkanya? Bukan dari daftar tipe ponsel. Breakpoint yang baik dipilih dari kontennya sendiri: dua kartu kita masing-masing butuh sekitar 280px sampai 300px agar isinya bernapas, jadi di bawah kira-kira 600px mereka lebih baik bertumpuk. Kalau suatu hari kontenmu berubah, breakpoint-nya boleh ikut bergeser.
Mobile-First: Menata dari Layar Kecil Dulu
Perhatikan arah syarat tadi: min-width, bukan max-width. Ini bukan kebetulan, melainkan cara pikir yang punya nama: mobile-first.
Mobile-first artinya aturan dasar CSS ditulis untuk layar paling kecil: satu kolom, sederhana, semuanya bertumpuk. Lalu lewat media query min-width, kita menambahkan penataan ekstra saat ruangnya tersedia: kartu boleh berdampingan, navbar boleh satu baris.
Kebalikannya, desktop-first, menata untuk layar lebar dulu lalu membongkarnya di layar kecil lewat max-width. Itu yang tanpa sadar kita lakukan di Episode 2.04: aturan dua kolom kita tulis sebagai aturan dasar. Bukan dosa, halamannya toh baru diuji di monitor. Tetapi membongkar selalu lebih rawan daripada menambah, jadi hari ini kita balik arah berpikirnya, dan kamu akan merasakan betapa kecil perubahannya.
Praktik Kecil: Refactor ke Mobile-First
Dua file kita sentuh lagi hari ini, sedikit saja.
Langkah pertama, di index.html: beri class pada dua link navigasi supaya bisa kita rapikan area sentuhnya nanti.
<nav>
<a class="tautan-nav" href="index.html">Beranda</a>
<a class="tautan-nav" href="tentang.html">Tentang Saya</a>
</nav>Langkah kedua, di style.css, tiga perubahan: aturan header kembali ramping (tiga baris flex-nya pindah), .galeri-kartu menjadi satu kolom sebagai aturan dasar, lalu satu media query baru di bagian paling bawah file menampung versi layar lebarnya. Ditambah satu aturan kecil .tautan-nav.
Supaya tidak ada yang tercecer di episode penutup ini, berikut style.css lengkapmu setelah semua perubahan, hasil akhir seluruh Session 2:
body {
font-family: Arial, sans-serif;
font-size: 17px;
line-height: 1.6;
color: #333333;
background-color: #f9f7f2;
}
h1 {
color: #1f3a5f;
font-size: 28px;
}
h2 {
color: #1f3a5f;
font-size: 20px;
}
header {
background-color: #e8eef5;
padding: 16px;
}
nav {
display: flex;
gap: 16px;
}
.tautan-nav {
padding: 8px;
}
main {
max-width: 640px;
margin-left: auto;
margin-right: auto;
padding: 16px;
}
footer {
background-color: #e8eef5;
padding: 16px;
margin-top: 24px;
}
.catatan {
color: #5f5f5f;
font-size: 14px;
}
section {
background-color: #ffffff;
border: 1px solid #d9d9d9;
padding: 16px;
}
.galeri-kartu {
display: grid;
grid-template-columns: 1fr;
gap: 16px;
margin-top: 16px;
}
.kartu-utama {
border: 1px solid #1f3a5f;
}
@media (min-width: 600px) {
header {
display: flex;
justify-content: space-between;
align-items: center;
}
.galeri-kartu {
grid-template-columns: 1fr 1fr;
}
}Simpan keduanya, refresh, lalu mainkan lebar jendelanya. Di jendela lebar, semuanya seperti kemarin: navbar satu baris, dua kartu berdampingan. Sempitkan melewati 600px: kartu-kartu bertumpuk rapi satu kolom, nama situs dan menu kembali bertingkat, dan tidak ada yang berdesakan. Halaman yang sama, dua wajah yang sama-sama nyaman.
Kalau ingin melihatnya sebagaimana ponsel sungguhan, browser punya alat bantu: tekan F12 untuk membuka DevTools, lalu klik ikon ponsel (device toolbar). Kamu bisa memilih ukuran layar ponsel populer dan memastikan halamanmu nyaman di sana.
Kalau semua langkah tadi benar, halamanmu kurang lebih akan tampil seperti ini:
Dan preview di atas punya keistimewaan: ia benar-benar responsive. Kalau kamu membaca dari monitor, coba sempitkan jendela browsermu pelan-pelan dan lihat kartu di dalam preview ikut bertumpuk; kalau kamu membaca dari ponsel, kamu sedang melihat wajah satu kolomnya sekarang.
Tap Target dan Focus: Ramah Jari, Ramah Keyboard
Dua sentuhan terakhir, dan keduanya tentang manusia, bukan ukuran layar.
Pertama, area sentuh alias tap target. Jari tidak sepresisi kursor. Link teks yang mungil mudah diklik di desktop, tetapi menyebalkan di ponsel: salah pencet, kena link sebelah. Karena itulah tadi kita memberi padding: 8px pada .tautan-nav; tulisannya sama, tetapi area yang bisa disentuh melebar ke sekelilingnya. Patokan umum: sediakan area sentuh yang lapang untuk semua hal yang bisa diketuk, jangan pelit ruang di menu.
Kedua, focus. Coba tekan tombol Tab beberapa kali di halamanmu: browser menggambar garis di sekeliling link yang sedang aktif. Itu focus, penanda posisi bagi orang yang menjelajah memakai keyboard. Suatu hari kamu mungkin menemukan trik untuk menghilangkan garis itu karena dianggap mengganggu desain. Jangan. Bagi pengguna keyboard, kehilangan garis focus seperti kehilangan kursor: masih bisa berjalan, tetapi buta arah.
Kesalahan Umum Pemula
Kesalahan pertama: media query sudah benar tetapi tidak ada efeknya di ponsel. Tersangka utamanya justru di HTML: baris meta viewport hilang atau salah ketik. Tanpa dia, browser ponsel memakai lebar pura-pura dan min-width: 600px selalu terpenuhi. Punya kita aman sejak Episode 1.02, tetapi ingat ini saat membuat file HTML baru.
Kesalahan kedua: salah arah syarat. min-width: 600px berarti berlaku pada 600px ke atas; max-width: 600px berarti 600px ke bawah. Tertukar satu kata, tampilanmu terbalik total antara ponsel dan desktop.
Kesalahan ketiga: aturan di dalam media query kalah oleh aturan di bawahnya. Ingat cascade dari Episode 2.02: kekuatan selector yang sama, yang belakangan menang. Kalau media query ditaruh di tengah file lalu ada aturan .galeri-kartu lagi di bawahnya, si bawah menang di semua ukuran layar. Kebiasaan yang aman: media query tinggal di bagian paling bawah file.
Kesalahan keempat: lupa kurung kurawal ganda. Media query punya kurung pembungkus sendiri, dan aturan-aturan di dalamnya punya kurung masing-masing. Satu penutup hilang, semua aturan setelahnya ikut mogok diam-diam. Kalau ada bagian CSS yang tiba-tiba mati semua, hitung kurungmu.
Kesalahan kelima: menguji hanya dengan satu ukuran. Responsive bukan dua wajah saja; di antara 320px dan 1920px ada banyak lebar. Seret tepi jendela pelan-pelan dari sempit ke lebar dan pastikan tidak ada titik canggung: teks tergencet, kartu terlalu kurus, atau scroll ke samping yang muncul diam-diam.
Rangkuman
Responsive adalah kemampuan satu halaman menyesuaikan diri dengan segala ukuran layar, dan fondasinya tiga: meta viewport yang jujur soal lebar layar, flexible width yang mau mengalah (max-width, bukan width mati), dan media query yang menerapkan aturan hanya saat syaratnya terpenuhi, berganti bentuk di titik yang disebut breakpoint.
Cara pikir mobile-first menulis aturan dasar untuk layar kecil dan menambahkan penataan lewat min-width saat ruang tersedia. Plus dua sopan santun untuk pengguna sungguhan: tap target yang lapang dan garis focus yang dibiarkan hidup.
Dengan ini, Session 2 resmi selesai. Lihat lagi perjalanannya: dari halaman polos, kamu menghubungkan CSS dan memahami selector, menjinakkan cascade dan box model, menata tipografi dan ritme baca, menyusun layout dengan flexbox dan grid, dan hari ini membuat semuanya luwes di segala layar. Halaman profil belajarmu kini blog statis kecil yang tertata, nyaman dibaca, dan siap dibuka dari perangkat apa pun. Itu bukan pencapaian kecil.
Berikutnya
Selama dua session, halaman kita punya struktur dan penampilan, tetapi ia diam. Diklik tidak menjawab, diketik tidak bereaksi. Bagian ketiga dari cerita web adalah perilaku, dan bahasanya bernama JavaScript.
Di Session 3 yang dibuka Episode 3.01, kita berkenalan dengan JavaScript di browser: melihatnya bekerja lewat console, menyimpan data di variable, dan pelan-pelan membuat halaman kita bisa diajak bicara. Struktur sudah, pakaian sudah; saatnya halaman kita belajar bergerak.
Belajar Lebih Lanjut
Kalau ingin belajar lebih lanjut, kamu juga bisa membaca beberapa rujukan berikut.