Media query dengan Claude Code: panduan CSS praktis
Bangun CSS responsif dengan Claude Code: media query, container query, preferensi pengguna, dan tes Playwright.
Halaman yang terlihat rapi di laptop bisa tetap rusak di tempat yang paling penting: artikel mobile, kartu afiliasi di sidebar sempit, mode gelap, atau dashboard admin yang dipakai berjam-jam. Meminta Claude Code “buat responsif” terlalu umum. Berikan aturan layout, preferensi pengguna, dan cara verifikasi.
Media query menerapkan CSS saat kondisi browser atau perangkat cocok. Container query menerapkan CSS berdasarkan ukuran kontainer induk komponen. prefers-reduced-motion dan prefers-color-scheme menghormati pengaturan sistem pengguna. Referensi resmi yang sebaiknya dibuka: MDN CSS media queries, Using media queries, CSS container queries, CSSWG Media Queries Level 5, W3C CSS Containment Module Level 3, dan Playwright emulation.
Untuk fondasi terkait, baca CSS Grid dengan Claude Code, pola Flexbox, aksesibilitas, dan optimasi performa.
Aturan kerja
Mulai dari mobile-first. Layout layar kecil menjadi CSS dasar, lalu layar lebih lebar ditambah dengan @media (width >= 48rem). Jangan memilih breakpoint berdasarkan nama perangkat. Pilih saat konten mulai bermasalah: navigasi patah, kartu terlalu sempit, iklan terlalu dekat dengan teks, atau formulir sulit dibaca.
| Keputusan | Media query | Container query |
|---|---|---|
| Yang dilihat | Viewport, cetak, preferensi pengguna | Ukuran atau status kontainer induk |
| Cocok untuk | Layout halaman, navigasi, jarak global | Kartu, CTA, harga, UI reusable |
| Kesalahan umum | Terlalu banyak breakpoint perangkat | Lupa container-type |
| Prompt | “Ubah layout berdasarkan lebar viewport” | “Ubah kartu berdasarkan lebar tersedia” |
Kasus nyata
Untuk artikel blog, susun isi, CTA, dan artikel terkait secara vertikal di mobile. Tambahkan sidebar hanya saat ruang cukup. Kartu afiliasi atau produk sebaiknya memakai container query agar tetap rapi di isi artikel, sidebar, dan blok terkait.
Untuk halaman harga SaaS, kartu harga yang sama bisa muncul di homepage, landing page, dan checkout. Jika hanya memakai viewport, kartu bisa memakai layout lebar di kolom yang sempit.
Untuk dashboard admin, filter, tabel, tombol ekspor, dan pencarian berebut ruang. Di layar kecil, tabel dapat berubah menjadi daftar kartu; di layar besar, kolom tetap dipertahankan. prefers-reduced-motion membantu pengguna yang bekerja lama.
Untuk konten monetisasi, CTA harus terlihat tanpa merusak pengalaman membaca. Gunakan media query untuk ritme halaman dan container query untuk isi kartu CTA.
HTML/CSS siap pakai
Simpan sebagai responsive-demo.html dan buka di browser. Contoh ini memakai mobile-first, container query, mode gelap, reduced motion, dan tipografi clamp(). Hindari font-size: 4vw karena teks bisa terlalu besar di layar lebar dan terlalu kecil di layar sempit.
<!doctype html>
<html lang="id">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Responsive media query demo</title>
<style>
:root { color-scheme: light dark; --bg: #f7f8fb; --surface: #ffffff; --text: #1f2937; --line: #d8dee8; --accent: #0f766e; --accent-strong: #115e59; --shadow: 0 12px 30px rgb(15 23 42 / 0.12); }
* { box-sizing: border-box; }
body { margin: 0; font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; font-size: clamp(1rem, 0.94rem + 0.25vw, 1.125rem); line-height: 1.7; color: var(--text); background: var(--bg); }
a { color: var(--accent-strong); }
.site-header { padding: 1rem; border-bottom: 1px solid var(--line); background: var(--surface); position: sticky; top: 0; z-index: 10; }
.nav { display: flex; flex-wrap: wrap; gap: 0.75rem 1rem; align-items: center; justify-content: space-between; max-width: 72rem; margin: 0 auto; }
.brand { font-weight: 800; }
.nav-links { display: flex; gap: 0.75rem; padding: 0; margin: 0; list-style: none; }
.page { width: min(100% - 2rem, 72rem); margin: 2rem auto; display: grid; gap: 1.5rem; }
.hero, .article, .sidebar-card, .offer { background: var(--surface); border: 1px solid var(--line); border-radius: 8px; box-shadow: var(--shadow); }
.hero { padding: clamp(1.25rem, 1rem + 1.5vw, 2.5rem); }
h1 { margin: 0 0 0.75rem; font-size: clamp(2rem, 1.65rem + 1.6vw, 3.2rem); line-height: 1.15; }
.layout { display: grid; gap: 1.5rem; }
.article, .sidebar-card { padding: 1rem; }
.sidebar { display: grid; gap: 1rem; align-content: start; }
.offer-wrap { container-type: inline-size; container-name: offer; }
.offer { display: grid; gap: 1rem; padding: 1rem; overflow: hidden; }
.offer-media { min-height: 10rem; border-radius: 6px; background: linear-gradient(135deg, rgb(15 118 110 / 0.85), rgb(37 99 235 / 0.75)), repeating-linear-gradient(45deg, rgb(255 255 255 / 0.18) 0 10px, transparent 10px 20px); }
.button { display: inline-flex; width: fit-content; min-height: 2.75rem; align-items: center; justify-content: center; padding: 0.7rem 1rem; border-radius: 6px; background: var(--accent); color: white; font-weight: 700; text-decoration: none; transition: transform 180ms ease, background-color 180ms ease; }
.button:hover { transform: translateY(-2px); background: var(--accent-strong); }
@media (width >= 48rem) { .article { padding: 1.5rem; } .layout { grid-template-columns: minmax(0, 1fr) 18rem; align-items: start; } }
@media (width >= 72rem) { .layout { grid-template-columns: minmax(0, 2fr) minmax(18rem, 0.8fr); } }
@container offer (width >= 34rem) { .offer { grid-template-columns: 14rem minmax(0, 1fr); align-items: center; padding: 1.25rem; } }
@media (prefers-color-scheme: dark) { :root { --bg: #10151f; --surface: #18202d; --text: #eef2f7; --line: #334155; --accent: #2dd4bf; --accent-strong: #5eead4; --shadow: none; } }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; scroll-behavior: auto !important; transition-duration: 0.01ms !important; } }
</style>
</head>
<body>
<header class="site-header"><nav class="nav" aria-label="Main navigation"><div class="brand">ClaudeCodeLab</div><ul class="nav-links"><li><a href="#guide">Guide</a></li><li><a href="#offer">Template</a></li></ul></nav></header>
<main class="page"><section class="hero"><h1>Media queries that survive real layouts</h1><p>Mobile-first CSS, container-aware cards, dark mode, and reduced motion.</p></section><div class="layout" id="guide"><article class="article"><h2>Readable article body</h2><p>The article stays readable on phones and gains a sidebar only when there is enough room.</p><div class="offer-wrap" id="offer"><section class="offer"><div class="offer-media" aria-hidden="true"></div><div><h2>Responsive review checklist</h2><p>Use this area for a download, newsletter, or product CTA.</p><a class="button" href="#">Get the checklist</a></div></section></div></article><aside class="sidebar" aria-label="Related content"><section class="sidebar-card"><h2>Related</h2><p>Grid, Flexbox, accessibility, and performance belong in the same review.</p></section></aside></div></main>
</body>
</html>
Prompt Claude Code
Target: CSS responsif untuk halaman artikel
Aturan:
- CSS dasar mobile-first
- Media query viewport hanya untuk layout halaman
- Container query untuk kartu dan CTA reusable
- Jangan memakai font-size hanya dengan vw; gunakan clamp()
- Hormati prefers-color-scheme dan prefers-reduced-motion
Verifikasi:
- Cek 375, 768, 1024, 1440 px
- Cek dark mode dan reduced motion di Playwright
- Laporkan breakpoint duplikat atau tidak perlu
Review diff ini sebagai CSS responsif.
Prioritaskan horizontal overflow, ukuran teks tidak terbaca, CTA/iklan terjepit,
container-type yang hilang, pelanggaran reduced-motion, dan breakpoint berlebihan.
Kembalikan hanya baris spesifik dan perbaikan minimum.
Verifikasi Playwright
import { test, expect } from "@playwright/test";
const fileUrl = "file:///absolute/path/to/responsive-demo.html";
for (const width of [375, 768, 1024, 1440]) {
test(`no horizontal overflow at ${width}px`, async ({ page }) => {
await page.setViewportSize({ width, height: 900 });
await page.goto(fileUrl);
const hasOverflow = await page.evaluate(() => document.documentElement.scrollWidth > document.documentElement.clientWidth);
await expect(hasOverflow).toBe(false);
await expect(page.locator(".offer")).toBeVisible();
});
}
test("dark mode keeps text readable", async ({ page }) => {
await page.emulateMedia({ colorScheme: "dark" });
await page.goto(fileUrl);
await expect(page.locator("body")).toHaveCSS("color", "rgb(238, 242, 247)");
});
test("reduced motion disables hover timing", async ({ page }) => {
await page.emulateMedia({ reducedMotion: "reduce" });
await page.goto(fileUrl);
const duration = await page.locator(".button").evaluate((el) => getComputedStyle(el).transitionDuration);
expect(duration).toBe("0.01ms");
});
flowchart TD
A["CSS dasar mobile-first"] --> B["Media query untuk layout"]
B --> C["Container query untuk kartu"]
C --> D["Preferensi pengguna"]
D --> E["Screenshot dan overflow Playwright"]
E --> F["Prompt review Claude Code"]
Kesalahan dan monetisasi
Jangan menumpuk override max-width, memakai viewport untuk komponen reusable, mengatur font hanya dengan vw, atau mengabaikan reduced motion. Setelah Claude Code membuat CSS, validasi teks terjemahan, CTA nyata, iklan, mode gelap, dan layar sempit.
CSS responsif menjaga pendapatan karena penawaran tetap terlihat tanpa merusak pengalaman membaca. Letakkan CTA checklist gratis secara ringan di tengah artikel, lalu CTA template atau konsultasi yang lebih kuat di akhir. Mulai dari resource gratis, lihat produk, atau siapkan adopsi tim melalui training.
Dalam uji langsung Masa, peningkatan terbesar datang dari memindahkan kartu CTA ke container query. Kartu yang sama bekerja di isi artikel, sidebar, dan artikel terkait tanpa breakpoint viewport baru. Playwright memastikan tidak ada overflow di 375px, teks dark mode tetap terbaca, dan reduced motion diterapkan.
PDF gratis: cheatsheet Claude Code
Masukkan email dan unduh satu halaman berisi command, kebiasaan review, dan workflow aman.
Kami menjaga datamu dan tidak mengirim spam.
Tentang penulis
Masa
Engineer yang berfokus pada workflow Claude Code praktis dan adopsi tim.
Artikel terkait
Permission safety ladder Claude Code: perluas akses tanpa kehilangan kontrol
Naik dari read-only ke edit terbatas, command bukti, dan cek deploy dengan kontrol yang jelas.
Claude Code Small PR Proof Pack: perubahan kecil yang mudah direview
Paket bukti untuk PR Claude Code: diff, check, URL publik, jalur CTA, dan rollback.
Review gate Claude Code sebelum commit: diff, test, URL publik, dan CTA
Cara memakai Claude Code sebelum commit: diff scope, build, URL publik, link Gumroad, CTA konsultasi, missing test, dan file tidak terkait.