Menu

rem vs em vs px: Satuan CSS, Persentase, vw dan vh

rem relatif terhadap ukuran font root, em terhadap ukuran font elemen itu sendiri, px bernilai tetap, dan % bergantung pada property-nya. Lihat setiap satuan diukur di demo bertingkat, kenapa em berlipat ganda, kapan memakai yang mana, dan cara kerja vw, vh, dan dvh.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

rem vs em dalam satu demo bertingkat

rem relatif terhadap ukuran font root (elemen <html>, 16px secara default). em relatif terhadap ukuran font saat ini, yang untuk font-size berarti ukuran font elemen induknya. Tumpuk class yang sama tiga tingkat, dan perbedaannya langsung terlihat:

Ukuran yang dicetak adalah hasil hitungan browser. Setiap 1.25em mengalikan ukuran elemen induknya: 20px, lalu 25px, lalu 31.25px. Setiap 1.25rem hanya melihat root: 20px, 20px, 20px. Efek berlipat inilah yang membuat ukuran font em jadi tidak terkendali di list dan menu bertingkat, dan itulah sebabnya sebagian besar situs mengatur ukuran font dengan rem.

Setiap satuan relatif terhadap apa

SatuanRelatif terhadap1 satuan secara default
pxtidak ada (sebuah piksel CSS)1px
remukuran font elemen root (html)16px
emukuran font elemen itu, untuk font-size sendiri, ukuran font elemen induk16px di tingkat teratas
%bergantung pada property-nya (lihat di bawah)
vw / vh1% dari lebar / tinggi viewport
dvh, svh, lvh1% dari tinggi viewport dinamis, kecil, atau besar
vmin / vmax1% dari sisi viewport yang lebih kecil / lebih besar
chlebar karakter "0" di font saat inisekitar setengah em
exx-height font saat inisekitar setengah em

Piksel CSS bukan piksel perangkat: di ponsel dengan layar 3x, 1px selebar 3 piksel perangkat. Ukuran visualnya kurang lebih sama di berbagai layar, itulah sebabnya px masih cocok untuk border dan bayangan.

em untuk jarak yang mengikuti teks

em bukan hanya untuk ukuran font. Pada padding, margin, width, atau border-radius, satuan ini berarti "dikali ukuran font elemen ini". Dengan begitu, satu class tombol bisa dipakai di ukuran berapa pun:

Padding setiap tombol adalah setengah ukuran fontnya secara vertikal dan satu kali ukuran fontnya secara horizontal, jadi ketiganya terlihat seperti tombol yang sama dalam tiga ukuran. Dengan padding px, kamu butuh aturan padding terpisah untuk setiap ukuran.

Perlu diingat, secara default tombol tidak mewarisi ukuran font halaman (browser memberi kontrol form ukuran font sendiri), jadi tombol di tengah berukuran 13.33px di Chrome, bukan 16px. Tambahkan font: inherit pada tombol dan input kalau kamu ingin ukurannya sama dengan halaman.

Persentase: bergantung pada property-nya

% tidak punya satu arti saja. Setiap property menentukan persentase itu dihitung dari apa:

Property% relatif terhadap
width, max-width, left, rightlebar elemen induk (containing block)
height, top, bottomtinggi elemen induk, dan hanya kalau elemen induk punya tinggi yang ditetapkan
padding, margin (keempat sisi)lebar elemen induk
font-sizeukuran font elemen induk (150% = 1.5em)
line-heightukuran font elemen itu sendiri
transform: translate()ukuran elemen itu sendiri

width: 50% bernilai 200px, setengah dari elemen induk. padding-top: 5% bernilai 20px: 5% dari lebar elemen induk, bukan tingginya. Lalu height: 50% tidak berpengaruh apa-apa, karena elemen induk tidak punya tinggi yang ditetapkan, jadi child hanya setinggi teksnya ditambah padding itu. Halaman width dan height membahas aturan itu secara detail.

vw, vh, dan bar alamat di ponsel

1vw adalah 1% dari lebar viewport dan 1vh 1% dari tingginya. Keduanya berguna untuk bagian layar penuh dan untuk ukuran yang fleksibel (sering kali di dalam clamp()). Di ponsel, vh punya jebakan: bar alamat browser muncul dan menghilang saat kamu men-scroll, dan 100vh adalah tinggi tanpa bar itu, jadi hero dengan height: 100vh terpotong di bagian bawah saat bar-nya tampil. Satuan yang lebih baru mengatasinya:

SatuanTinggi yang dipakai
100vhviewport besar (bar tersembunyi) di sebagian besar browser ponsel
100svhviewport kecil (bar tampil): selalu muat
100lvhviewport besar, secara eksplisit
100dvhviewport dinamis: berubah saat bar bergerak
.hero {
  min-height: 100vh;  /* fallback for older browsers */
  min-height: 100svh; /* fits the screen even with the address bar visible */
}

vw juga punya jebakan sendiri: 100vw sudah termasuk lebar scrollbar vertikal kalau scrollbar itu memakan ruang (seperti di Windows), jadi width: 100vw bisa lebih lebar dari halaman dan menambahkan scrollbar horizontal. Pakai width: 100% untuk "selebar penuh elemen induk".

ch untuk panjang baris yang nyaman dibaca

ch adalah lebar karakter "0", jadi max-width: 65ch membatasi paragraf menjadi sekitar 65 karakter per baris, panjang yang nyaman untuk dibaca, di ukuran font berapa pun:

Satuan mana yang dipakai

UntukPakaiAlasan
Ukuran fontremKonsisten di mana pun, menghormati pengaturan ukuran font pembaca
Padding dan gap di komponenrem atau emem kalau harus ikut membesar dengan teks komponen itu sendiri
Border, garis tipis, bayanganpxHarus tetap tipis di ukuran font berapa pun
Lebar layout%, fr, max-width dalam rem atau chMengikuti container, membatasi panjang baris
Bagian layar penuhsvh / dvh (dengan cadangan vh)Mengatasi bar alamat di ponsel
Ukuran teks fleksibelclamp() yang mencampur rem dan vwIkut membesar dengan layar dalam batas tertentu

Kenapa rem menghormati pembaca dan px tidak

Browser punya pengaturan ukuran font default, yang dipakai orang-orang yang butuh teks lebih besar. Pengaturan ini mengubah ukuran font root, jadi semua yang memakai rem dan em ikut membesar. font-size: 14px tetap 14px, apa pun pilihan pembacanya. Zoom browser juga memperbesar px, tetapi pengaturan ukuran font itulah yang diandalkan banyak pembaca. Inilah alasan utama untuk mengatur ukuran font dengan rem.

Sebagian situs mengatur html { font-size: 62.5%; } supaya 1rem sama dengan 10px dan hitungannya lebih mudah. Cara ini tetap menghormati pengaturan pembaca (62,5% dari apa pun pilihannya), tetapi jangan lupa mengatur font-size yang nyaman dibaca di body, atau setiap elemen tanpa ukuran sendiri akan menampilkan teks 10px.

Kesalahan yang sering terjadi

  • Ukuran font em di elemen bertingkat. Nilainya berlipat di setiap tingkat. Pakai rem untuk ukuran font.
  • height: 50% yang tidak berpengaruh apa-apa. Elemen induk butuh tinggi yang ditetapkan agar tinggi persentase bisa berfungsi.
  • Mengira padding-top: 10% mengikuti tinggi elemen induk. Persentase padding dan margin vertikal memakai lebar elemen induk.
  • width: 100vw memunculkan scrollbar horizontal. Nilainya sudah termasuk scrollbar. Pakai 100%.
  • height: 100vh terpotong di ponsel. Pakai 100svh atau 100dvh.
  • Mengatur html { font-size: 12px }. Nilai px di root menimpa pengaturan ukuran font pembaca untuk seluruh halaman. Biarkan root apa adanya atau pakai persentase.

Pertanyaan yang sering diajukan

Apa perbedaan rem dan em?

rem relatif terhadap ukuran font elemen root (<html>), jadi 1.5rem berukuran sama di mana pun di halaman. em relatif terhadap ukuran font elemen itu sendiri (untuk font-size, ukuran font elemen induknya), jadi nilainya berlipat saat elemen bertingkat.

1rem itu berapa piksel?

16px secara default, karena browser mengatur ukuran font root menjadi 16px. Kalau pengguna memperbesar ukuran font default di pengaturan browser-nya, atau kamu mengatur html { font-size: ... }, 1rem ikut berubah.

Sebaiknya memakai rem atau px untuk ukuran font?

Pakai rem untuk ukuran font. Satuan ini menghormati pengaturan ukuran font default pembaca di browser, yang diabaikan oleh px. Zoom browser memperbesar keduanya, tetapi tidak semua pembaca memakai zoom.

Kapan sebaiknya memakai em, bukan rem?

Pakai em untuk jarak yang harus menyesuaikan dengan teks elemen itu sendiri, seperti padding tombol atau ukuran ikon di samping teks. Class yang sama pun terlihat pas di ukuran font berapa pun. Pakai rem untuk ukuran font dan jarak di tingkat halaman, supaya tidak ada yang berlipat.

Apa perbedaan 100vh dan 100dvh?

Di browser ponsel, 100vh adalah tinggi saat bar alamat tersembunyi, jadi bagian dengan 100vh lebih tinggi daripada layar yang terlihat selama bar itu tampil. 100dvh (dynamic viewport height) mengikuti bar saat muncul dan menghilang, dan 100svh selalu memakai tinggi yang lebih kecil.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai