Tutorial CSS / Ukuran Fleksibel CSS: max-width, min(), dan clamp()
Layout fluid memungkinkan dimensi menyesuaikan dengan ruang yang tersedia sambil memberlakukan batasan yang berguna. Lebar relatif, max-width, dan fungsi seperti clamp() dapat menjaga konten tetap terbaca tanpa memaksakan dimensi tetap yang sama di setiap layar.
Pisahkan lebar viewport dan lebar yang tersedia
Area tempat halaman web ditampilkan di browser disebut viewport. Namun, lebar yang tersedia untuk kartu di dalam konten utama mungkin lebih kecil dari viewport. Ini karena kartu harus muat di ruang yang tersisa dengan mengecualikan margin induk, jarak dari kolom lain, dan batas lebar maksimum.
Persentase di width: 100% menggunakan lebar area dasar di sekitar elemen dalam tata letak blok biasa. 100vw didasarkan pada lebar viewport, jadi meskipun ditempatkan di dalam kartu kecil, ukurannya bisa sebesar seluruh layar. Ketika bilah gulir vertikal dan margin luar ditambahkan, overflow horizontal dapat terjadi. Untuk lebar elemen di dalam konten utama, pertama pertimbangkan persentase atau ukuran otomatis.
| Deklarasi | induk sempit | induk lebar | Standar penggunaan |
|---|---|---|---|
| width: 48rem | Mungkin lebih besar dari induk | Pertahankan 48rem | Tidak cocok sebagai nilai default untuk teks yang dapat dipersingkat |
| width: 100% | Dikurangi agar sesuai dengan induk | Terus meningkat hingga lebar induk | Elemen yang perlu mengisi induk |
| width: 100%; max-width: 48rem | Dikurangi menjadi kurang dari 48rem | Hingga 48rem | Teks yang memerlukan lebar bacaan terbatas |
| min-width: 48rem | Tidak berkurang di bawah 48rem | Ditentukan sesuai dengan aturan ukuran yang berbeda | Gunakan hanya ketika ada ukuran minimum yang diperlukan |
Membatasi dan memusatkan area konten
*, *::before, *::after { box-sizing: border-box; }
.content {
width: 100%;
max-width: 48rem;
margin-inline: auto;
padding-inline: 1rem;
}
Dengan border-box, padding dan border masuk ke dalam lebar yang dideklarasikan. Jika font root adalah 16px dan induk memiliki lebar 390px, lebar luar kotak konten ini adalah 390px dan padding 16px di setiap sisi menyisakan 358px untuk konten. Pada lebar induk 1000px, lebar luar berhenti pada 768px dan margin otomatis memusatkannya. Untuk detail lebih lanjut, lihat Lebar, Tinggi, Batas min/max, dan box-sizing CSS.
Menerapkan content-box pada elemen yang sama akan menambahkan padding ke width: 100%, membuatnya lebih lebar dari induknya. Di sisi lain, margin juga tidak termasuk dalam border-box. Saat menentukan width: 100% dan margin tetap di kedua sisi bersama-sama, Anda harus memeriksa jumlah totalnya. Jika min-width dan max-width bertentangan, periksa juga min-width, karena min-width dapat membuatnya menjadi lebih besar.
Gunakan min() dan clamp()
min() memilih nilai yang lebih kecil di antara kandidat. width: min(100%, 48rem) menggunakan nilai yang lebih kecil antara lebar induk dan 48rem, jadi batas lebar 100% dan maksimum yang ditentukan sebelumnya dapat diungkapkan dalam satu deklarasi.
.content { width: min(100%, 48rem); }
h1 { font-size: clamp(1.5rem, 1rem + 2vw, 2.5rem); }
clamp(minimum, preferred, maximum) menggunakan nilai preferred setelah membatasinya antara minimum dan maksimum. Fungsi ini tidak menghitung rata-rata ketiga argumen. Pada judul di atas, rem didasarkan pada ukuran font root dan vw didasarkan pada 1% lebar viewport. Jika ukuran root adalah 16px, minimum adalah 24px, maksimum adalah 40px, dan nilai yang diinginkan adalah 16px ditambah 2% lebar layar.
| lebar viewport | Hitung nilai preferred | ukuran judul sebenarnya |
|---|---|---|
| 320px | 16 + 6,4 = 22,4px | Minimum 24px |
| 600px | 16 + 12 = 28px | 28px |
| 1200px | 16 + 24 = 40px | 40px |
| 1600px | 16 + 32 = 48px | Maksimum 40px |
Jika Anda membuat teks konten utama hanya bergantung pada lebar layar, teks tersebut mungkin menjadi terlalu kecil pada layar sempit atau saat diperbesar. Ketika menggunakan ukuran fluid pada judul, titik awal yang baik adalah memiliki batas bawah yang dapat dibaca dan menjaga konten utama tetap menggunakan ukuran berbasis rem. Hanya karena Anda mencampur rem tidak otomatis menjamin aksesibilitas pembesaran, jadi Anda perlu memeriksa pembesaran dan pengaturan font default di browser secara aktual juga. Anda dapat memeriksa peran setiap argumen dalam definisi clamp() MDN dan penjelasan aksesibilitas.
Jalankan contoh kartu dan gambar fluid
Simpan kode berikut sebagai fluid-size.html dalam UTF-8 dan buka di browser Anda. Gambar adalah data SVG yang disertakan dalam file, jadi tidak perlu mengunduh gambar terpisah atau pustaka eksternal. Bandingkan lebar body, jumlah kolom kartu, dan ukuran judul di layar lebar dan layar sempit sekitar 390px. Jika Anda ingin menempatkan beberapa kartu secara fleksibel, periksa CSS Grid: repeat, auto-fit, auto-fill, dan Area Bernama untuk mengetahui cara mengatur lebar minimum untuk kolom.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>fluid-size.html</title>
<style>
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; font: 1rem/1.6 sans-serif; color: #243447; }
h1, h2, p { margin-top: 0; } a { color: #145f8f; }
a:focus-visible, button:focus-visible, input:focus-visible { outline: 3px solid #ac4100; outline-offset: 3px; }
.content { width: min(100%, 48rem); margin-inline: auto; padding: 1rem; }
h1 { font-size: clamp(1.5rem, 1rem + 2vw, 2.5rem); line-height: 1.3; }
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); gap: 1rem; }
.card { min-width: 0; padding: 1rem; background: #e8f3fa; overflow-wrap: anywhere; }
.card img { display: block; max-width: 100%; height: auto; margin-bottom: 1rem; }
.token { font-family: monospace; }
</style>
</head>
<body>
<main class="content">
<h1>Size elements to fit the screen and content</h1>
<p>The content is at most 48rem wide and shrinks to fit its parent on smaller screens.</p>
<div class="cards">
<article class="card"><img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22400%22%20height%3D%22300%22%20viewBox%3D%220%200%20400%20300%22%3E%3Crect%20width%3D%22400%22%20height%3D%22300%22%20fill%3D%22%23287699%22%2F%3E%3Crect%20width%3D%22400%22%20height%3D%2235%22%20fill%3D%22%23205c32%22%2F%3E%3Crect%20y%3D%22265%22%20width%3D%22400%22%20height%3D%2235%22%20fill%3D%22%239e3131%22%2F%3E%3Ccircle%20cx%3D%22200%22%20cy%3D%22150%22%20r%3D%2270%22%20fill%3D%22%23f6ae4c%22%2F%3E%3Crect%20x%3D%2212%22%20y%3D%22120%22%20width%3D%2230%22%20height%3D%2260%22%20fill%3D%22white%22%2F%3E%3Crect%20x%3D%22358%22%20y%3D%22120%22%20width%3D%2230%22%20height%3D%2260%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E" width="400" height="300" alt="Practice drawing with upper and lower bands and center circle"><h2>card with picture</h2><p>The image stays within the card width and preserves its original aspect ratio.</p></article>
<article class="card"><h2>A heading and description that wrap onto several lines</h2><p>Without a fixed height, the card grows as its text gets longer.</p></article>
<article class="card"><h2>Long identifier</h2><p class="token">ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789</p></article>
</div></main>
</body>
</html>
Kartu minmax(min(100%, 14rem), 1fr) menggunakan lebar minimum default 14rem, tetapi jika induknya lebih sempit, minimum tersebut menjadi 100% dari lebar induk, bukan dikurangi sebesar 100%. auto-fit menghitung jumlah kolom yang muat, menyusutkan track berulang yang kosong, lalu membagi sisa ruang pada kolom yang terisi. Karena adanya padding di dalam kartu, lebar sebenarnya dari teks dan gambar lebih kecil daripada lebar luar kartu. Jangan menilai jumlah kolom berdasarkan nama perangkat, tetapi berdasarkan lebar yang tersedia untuk induk.
min-width: 0 menghapus batas ukuran minimum yang bisa mencegah kartu menyusut. overflow-wrap: anywhere menyediakan pemisahan dalam URL panjang atau pengenal ketika diperlukan. Mereka memiliki peran yang berbeda: membiarkan kotak menyusut tidak secara otomatis membungkus teksnya. Pembungkusan mengubah tampilan, bukan nilai string yang disalin.
Uji satu perubahan ukuran sekaligus
- Kurangi layar menjadi 390px. Teks harus muat di dalam layar, kartu harus berjalan secara vertikal, dan pita di atas dan di bawah gambar serta lingkaran di tengah semuanya harus terlihat.
- Ubah hanya lebar dari
.contentmenjadi48rem. Setelah memeriksa mengapa teks meluap di layar sempit, kembalikan kemin(100%, 48rem). - Ubah hanya nilai maksimum dari judul menjadi
3remdan lihat perbedaannya di layar yang lebih lebar. Bandingkan hasil perhitungan nilai preferred: ukuran hanya berubah jika nilai itu melewati maksimum lama. Setelah membandingkan, kembalikan maksimum ke 2.5rem. - Hapus hanya
overflow-wrap: anywheredari.card. Periksa dan pulihkan jika identifier panjang berada di luar kartu. Percobaan selanjutnya untuk mengubah ukuran root dan pembesaran browser dicatat di bawah kondisi terpisah.
Sebelum menyisipkan overflow-x: hidden, yang menyembunyikan overflow, ke seluruh halaman, periksa lebar, margin, lebar minimum, dan string. Jika Anda menyembunyikannya dari pandangan, konten atau elemen operasi mungkin terpotong tanpa menyelesaikan penyebabnya. Untuk prinsip dasar konfigurasi responsif, Anda juga dapat merujuk pada panduan desain responsif MDN.




