Skip to content
Kembali ke Blog
Tutorial

PX vs REM vs EM: Panduan Lengkap Satuan CSS

px vs rem vs em dijelaskan: arti tiap satuan CSS, kapan memakai rem untuk aksesibilitas, jebakan em bertumpuk, dan tabel keputusan per properti untuk web.

12 menit membaca

PX vs REM vs EM: Panduan Lengkap Satuan CSS

Berikut jawaban singkat untuk px vs rem vs em, sebelum penjelasan apa pun. Pakai rem untuk hampir semua ukuran, seperti ukuran font, padding, margin, gap, border-radius, dan breakpoint, karena rem ikut menyesuaikan diri dengan setelan ukuran font browser milik pembaca. Pakai px untuk segelintir hal yang memang tidak boleh ikut membesar, seperti border 1px atau offset bayangan (shadow) yang presisi. Pakai em untuk kasus lokal yang jarang muncul, ketika sebuah nilai harus tumbuh mengikuti ukuran font elemen itu sendiri, misalnya padding tombol yang mengikuti teks tombolnya.

Aturan itu sudah mencakup 90% keputusan. Sisanya yang 10% adalah tempat masalah biasanya muncul: matematika penumpukan (compounding) em yang mengejutkan semua orang saat pertama kali, bug media query yang merusak tata letak saat di-zoom, dan kasus ketika px sebenarnya pilihan yang lebih ramah aksesibilitas. Panduan ini membahas ketiganya, lengkap dengan CSS yang bisa langsung dijalankan, plus tabel keputusan per properti yang bisa Anda buka selama menulis style.

Apa arti px, rem, dan em sebenarnya

Tiga satuan, tiga titik acuan yang berbeda. Perbedaan acuan itulah yang membedakan semuanya.

px adalah satuan mutlak (absolute unit). Satu px adalah satu piksel CSS, dan ukurannya tetap apa pun yang ada di sekitarnya. border: 1px solid adalah satu piksel, titik. “Mutlak” juga berarti px mengabaikan preferensi pengguna, dan bagian tentang aksesibilitas nanti menjelaskan mengapa itu penting.

rem relatif terhadap ukuran font elemen root. Root adalah <html>, dan browser menetapkan ukuran fontnya ke 16px secara default. Jadi 1rem setara 16px pada setelan standar, di seluruh halaman, tanpa peduli seberapa dalam penyarangannya (nesting). Daya tariknya ada pada konsistensi ini: satu nilai acuan yang tidak menimbulkan kejutan.

em relatif terhadap ukuran font elemen saat ini (atau induknya, untuk properti selain font-size). Karena acuan itu berubah seiring Anda menyarangkan elemen, nilai em bergeser tergantung konteks. 1.5em yang sama bisa menjadi 24px di satu tempat dan 30px di tempat lain.

Acuan yang perlu dihafal adalah 16px = 1rem. Kalau tidak ada hal lain yang Anda serap, serap yang ini. Ketika Anda perlu menerjemahkan suatu nilai tertentu, konverter px ke rem melakukan pembagian terhadap basis apa pun yang Anda pilih.

px vs rem vs em sekilas

SatuanRelatif terhadapIkut skala ukuran font pengguna?Penggunaan umumPerilaku saat disarangkan
pxTidak ada (mutlak)TidakBorder, offset bayangan, garis tipisSelalu berukuran sama
remUkuran font root <html>YaUkuran font, spasi, breakpointSelalu berukuran sama
emUkuran font elemen saat iniYaNilai lokal yang terikat ke komponenBertumpuk, bisa melenceng

Dua kolom yang menentukan sebagian besar perdebatan adalah “ikut skala ukuran font pengguna” dan “perilaku saat disarangkan”. rem unggul pada keduanya: ia menghormati preferensi pembaca sekaligus tetap dapat diprediksi. em berbagi keuntungan pertama tetapi mengorbankan yang kedua.

Bagaimana tiap satuan dihitung

Matematikanya aritmetika biasa. Yang membuat orang tersandung adalah angka mana yang dipakai untuk membagi atau mengalikan.

rem memakai ukuran font root:

rem = px ÷ root-font-size

Pada root default 16px, 24px ÷ 16 = 1.5rem. Untuk membalik, kalikan: 1.5rem × 16 = 24px. Setiap rem di halaman memakai 16 yang sama itu (atau berapa pun yang Anda tetapkan untuk root), dan itulah persisnya mengapa rem dapat diprediksi.

em memakai ukuran font elemen itu sendiri:

em = px ÷ current-element-font-size

Jika font-size sebuah elemen adalah 20px, maka 1em pada elemen itu adalah 20px, 0.5em adalah 10px, dan padding 1.5em adalah 30px. Ubah ukuran font elemen tersebut maka setiap nilai em yang menempel padanya ikut berubah. Keterkaitan lokal inilah inti dari em, sekaligus jebakannya.

Jebakan penumpukan em

Ketika Anda menyarangkan elemen yang semuanya memakai em untuk ukuran font, nilainya berlipat ganda menuruni pohon (tree). Tiap tingkat mewarisi ukuran font terhitung dari induknya lalu menerapkan faktor em-nya sendiri di atasnya.

.menu      { font-size: 1.2em; } /* induk 16px → 19.2px */
.menu .item { font-size: 1.2em; } /* induk 19.2px → 23.04px */
.menu .item .sub { font-size: 1.2em; } /* induk 23.04px → 27.648px */

Tiap tingkat adalah “120% dari induknya”, yang kedengarannya tidak berbahaya. Namun karena induknya sudah membesar, tingkat ketiga menjadi 1.2 × 1.2 × 1.2 = 1.728em relatif terhadap 16px semula, sekitar 27.6px, bukan 19.2px yang mungkin Anda baca dari aturan itu secara terpisah. Sarangkan sebuah list di dalam list di dalam sebuah komponen, dan teksnya menggelembung dengan cara yang sulit dilacak.

rem menghindari hal ini sepenuhnya. 1.2rem adalah 19.2px baik ia berada di puncak dokumen maupun dua belas tingkat di dalamnya, karena rem selalu mengukur terhadap root, tidak pernah terhadap induk. Ketika sebuah nilai menghasilkan ukuran yang tidak Anda duga, pertanyaan pertama yang perlu diajukan adalah apakah itu em (relatif terhadap induk, bertumpuk) atau rem (relatif terhadap root, stabil). Jika Anda sedang men-debug sebuah rem yang menyimpang dan ingin melihat ukuran pikselnya dengan cepat, konverter rem ke px menyelesaikannya seketika.

Kapan memakai rem

Jadikan rem pilihan default. Ia satuan yang tepat untuk ukuran font, padding, margin, gap, border-radius, dan breakpoint media query, yaitu apa pun yang seharusnya ikut menyesuaikan diri ketika pembaca mengubah ukuran teksnya.

Klausa terakhir itulah argumen aksesibilitasnya, dan ini bukan sekadar hipotesis. Survei pembaca layar (screen reader) dan low-vision dari WebAIM secara konsisten menemukan bahwa sebagian besar pengguna mengubah ukuran font default browser atau OS mereka, banyak di antaranya jauh di atas 16px standar. Tata letak yang diukur dalam rem menghormati perubahan itu: naikkan default ke 20px dan setiap nilai berbasis rem ikut tumbuh secara proporsional. Tata letak yang diukur dalam px mengabaikannya sepenuhnya: teksnya tetap terkunci pada ukuran yang dikodekan keras (hardcoded), tidak peduli seberapa besar pembaca membutuhkannya.

:root {
  font-size: 16px; /* 1rem = 16px */
}

h1   { font-size: 2rem;     } /* 32px, ikut skala preferensi pengguna */
p    { font-size: 1rem;     } /* 16px */
.card { padding: 1.5rem;    } /* 24px */
.card { border-radius: 0.5rem; } /* 8px */

Karena setiap nilai di sini berlabuh pada root yang sama, satu perubahan pada ukuran font root menskalakan ulang seluruh antarmuka secara proporsional. Itu pula yang menjaga sebuah design system tetap koheren: spasi dan tipografi bergerak bersama alih-alih saling melenceng.

Trik 62.5%

Ada jalan pintas populer untuk membuat aritmetika rem jadi sepele. Tetapkan ukuran font root ke 62.5%, yaitu 62.5% × 16px = 10px:

html {
  font-size: 62.5%; /* sekarang 1rem = 10px */
}

body {
  font-size: 1.6rem; /* kembalikan teks body ke 16px yang nyaman dibaca */
}

h1 { font-size: 2.4rem; } /* 24px */
p  { font-size: 1.6rem; } /* 16px */

Dengan root 10px, kalkulasi di kepala menciut menjadi “bagi nilai piksel dengan 10”: 24px → 2.4rem, 12px → 1.2rem. Satu hal yang perlu disetel adalah mengembalikan ukuran body yang nyaman dibaca dengan body { font-size: 1.6rem }, sebab basis 10px mentah membuat teks default jauh terlalu kecil. Memakai 62.5% sebagai persentase, bukan 10px, menjaganya tetap relatif, sehingga pembaca yang menskalakan default browsernya tetap mendapat pertumbuhan yang proporsional. Jika Anda mengadopsi basis ini, atur ukuran font root pada konverter ke 10 agar cocok dengan stylesheet Anda.

Kapan memakai em

Pakai em ketika Anda ingin sebuah nilai ikut menyesuaikan diri dengan ukuran font elemen itu sendiri, bukan root. Kasus klasiknya adalah tombol:

.btn {
  font-size: 1rem;      /* diukur terhadap root */
  padding: 0.75em 1.5em; /* padding mengikuti teks tombol */
}

.btn--large {
  font-size: 1.25rem;   /* satu perubahan mengubah ukuran semuanya */
}

Karena padding-nya dalam em, modifier .btn--large mengubah ukuran teks dan padding-nya bersama-sama dari satu deklarasi, sehingga tombolnya tetap proporsional pada ukuran berapa pun. Logika yang sama berlaku untuk ikon yang diukur dalam em agar cocok dengan baris teks tempatnya berada, atau letter-spacing yang seharusnya tumbuh bersama fontnya.

Strategi yang berhasil dalam praktik adalah rem untuk kerangka global, em untuk proporsi lokal. Tetapkan ukuran font dalam rem agar ia merespons root dan preferensi pengguna; tetapkan segelintir nilai yang seharusnya mengikuti elemen itu dalam em. Hanya saja, jauhkan em dari apa pun yang menyarang dalam, atau jebakan penumpukan tadi merayap kembali.

Kapan memakai px

Sebagian nilai memang benar-benar tidak seharusnya ikut membesar, dan px tepat untuknya: border garis tipis (hairline) 1px, offset box-shadow yang presisi, focus ring 2px. Ini adalah detail rendering, bukan konten. Border yang “ikut membesar” menjadi 1.25px saat pengguna memperbesar teksnya tidak menambah apa pun dan bisa ter-render sebagai garis kabur. px menjaganya tetap tajam.

.divider { border-bottom: 1px solid; }     /* seharusnya tetap 1px */
.card    { box-shadow: 0 2px 4px rgba(0,0,0,0.1); } /* offset tetap */
.input:focus { outline: 2px solid; }       /* focus ring yang tajam */

Ketika px justru lebih ramah aksesibilitas

Bagian ini berlawanan dengan intuisi yang dibangun saran “selalu pakai rem”. Pilihan yang ramah aksesibilitas bukan “rem di mana-mana”, melainkan “skalakan yang seharusnya diskalakan, kunci yang seharusnya tetap”.

Border 1px adalah detail tetap. Memaksanya menjadi rem agar membesar ketika pengguna memperbesar teks tidak membantu keterbacaan; ia hanya membuat garis tipis jadi buram. Untuk properti seperti ini, px adalah pilihan yang lebih ramah aksesibilitas justru karena ia tidak bergeser.

Kesalahan yang benar-benar dilakukan orang adalah kebalikannya: memakai px untuk hal-hal yang seharusnya merespons, seperti ukuran font dan breakpoint. Di situlah px merugikan aksesibilitas. Jadi aturannya bukan soal satuannya, melainkan soal propertinya. Tanyakan apakah nilai itu konten yang berinteraksi dengan pembaca (skalakan, pakai rem) atau detail rendering yang tetap (kunci, pakai px). Satuannya mengikuti jawabannya.

Jebakan media query

Breakpoint media query yang ditulis dalam px tidak merespons zoom ukuran font browser sebagaimana yang Anda harapkan, dan ini cukup sering merusak tata letak nyata.

Bayangkan sebuah breakpoint pada width: 600px tempat sidebar menciut. Seorang pengguna dengan penglihatan terbatas menyetel default browsernya ke 24px agar nyaman membaca. Konten Anda kini butuh ruang horizontal lebih banyak, karena teks yang lebih besar ingin mengalir ulang (reflow) lebih awal. Tetapi breakpoint px tidak tahu bahwa teksnya membesar; ia tetap berpindah persis pada 600px lebar viewport, sehingga tata letak beralih pada saat yang salah dan konten menjadi sempit atau bertumpuk.

Bandingkan kedua pendekatannya:

/* breakpoint px — mengabaikan preferensi ukuran font pengguna */
@media (min-width: 600px) {
  .sidebar { display: block; }
}

/* breakpoint em/rem — merespons ukuran font pengguna */
@media (min-width: 37.5em) {
  .sidebar { display: block; }
}

37.5em adalah 600px pada default 16px (600 ÷ 16 = 37.5). Perbedaannya bersifat perilaku: ketika pengguna menggandakan ukuran font defaultnya, breakpoint em secara efektif ikut berlipat ganda, sehingga tata letak beralih pada lebar viewport yang proporsional terhadap teksnya, persis ketika konten membutuhkannya. Breakpoint px tetap membeku.

Satu keunikan yang patut diketahui: di dalam kondisi media query, em dan rem sama-sama diukur terhadap ukuran font default browser, bukan override html apa pun, sehingga keduanya berperilaku identik di situ. Salah satu satuan dapat memperbaiki bug ini; px yang menyebabkannya.

Tabel keputusan per properti

Ketika Anda ragu, tabel ini menjawabnya tanpa harus menurunkan ulang logikanya tiap kali.

PropertiSatuan yang disarankanAlasan
font-sizeremIkut skala preferensi ukuran font pengguna
padding / marginremSpasi ikut menyesuaikan diri bersama teks
borderpxGaris tipis seharusnya tetap tajam dan tetap
offset box-shadowpxDetail rendering yang presisi, bukan konten
border-radiusremMenjaga kebulatan sudut proporsional terhadap skala
media queryem / remBreakpoint harus merespons zoom ukuran font
width / max-widthrem (sering ch untuk teks)Lebar tata letak yang dapat diskalakan; ch membatasi panjang baris
line-heighttanpa satuanPengali tanpa satuan diwariskan dengan benar

Baris line-height perlu diberi catatan karena ini bug yang umum. Selalu tulis line-height: 1.5, tanpa satuan. Nilai tanpa satuan adalah pengali yang dihitung tiap elemen terhadap ukuran fontnya sendiri, sehingga elemen yang disarangkan tetap terbaca. Tulis line-height: 1.5em atau 24px justru, dan panjang terhitungnya yang diwariskan, yang berarti anak dengan ukuran font lebih besar mempertahankan line height induknya dan teksnya mulai bertabrakan. Tanpa satuan menghindari seluruh masalah itu.

Konversi antara px dan rem

Aritmetikanya cukup kecil untuk dikerjakan di kepala begitu Anda memegang acuannya: 16px = 1rem. Bagi dengan 16 untuk menuju rem, kalikan dengan 16 untuk kembali ke px.

pxrem (basis 16px)
8px0.5rem
12px0.75rem
16px1rem
24px1.5rem
32px2rem

Jika Anda memakai trik 62.5%, basisnya menjadi 10px dan matematikanya bahkan lebih sederhana: cukup bagi atau kalikan dengan 10, sehingga 24px = 2.4rem. Satu-satunya aturan adalah selalu mengonversi terhadap basis yang benar-benar ditetapkan stylesheet Anda.

Untuk selebihnya, seperti nilai-nilai ganjil, root kustom, atau konversi massal sebuah ekspor Figma, lewati kalkulasi di kepala dan pakai konverter px ke rem atau konverter rem ke px. Keduanya memungkinkan Anda menetapkan ukuran font root apa pun dan mengonversi ke arah mana pun secara real time. Dan jika setelahnya Anda sedang merapikan stylesheet yang penuh satuan campuran, formatter CSS akan menormalkan spasi dan indentasinya untuk Anda.

Kesalahan umum

Beberapa pola menyebabkan sebagian besar kerepotan terkait satuan:

Menetapkan ukuran font root dalam px. Menulis html { font-size: 16px } (alih-alih membiarkan default atau memakai 100% / sebuah persentase) menimpa preferensi ukuran font browser pengguna mentah-mentah. Nilai rem tetap dihitung terhadapnya, tetapi pembaca tidak bisa lagi menskalakan seluruh halaman. Biarkan root tetap default, atau pakai persentase.

Mencampur px dan rem tanpa sistem. Sebagian ukuran font dalam px, sebagian dalam rem, spasi terbagi di antara keduanya, dan hasilnya tata letak yang menskalakan tidak merata ketika pengguna mengubah teksnya. Pilih rem sebagai default dan cadangkan px untuk pengecualian yang disengaja dalam tabel keputusan.

Memakai em untuk spasi global. Em pada kontainer yang disarangkan luas memperkenalkan kembali jebakan penumpukan, sehingga padding jauh di dalam pohon menghasilkan sesuatu yang tidak diinginkan siapa pun. Jaga spasi global tetap dalam rem; simpan em untuk nilai lokal yang dicakup ke komponen.

Memberi line-height sebuah satuan. Seperti dibahas di atas, line-height: 24px atau 1.5em diwariskan sebagai panjang terhitung dan rusak pada elemen dengan ukuran font berbeda. Selalu pakai pengali tanpa satuan.

FAQ

Apakah rem lebih baik daripada px?

Untuk sebagian besar ukuran, ya, rem lebih baik daripada px karena ikut menyesuaikan diri dengan preferensi ukuran font browser pengguna, yang diabaikan px. Tetapi “lebih baik” bergantung pada propertinya: px adalah pilihan tepat untuk detail tetap seperti border 1px dan offset bayangan yang seharusnya tetap tajam. Pakai rem untuk ukuran konten, px untuk detail rendering.

Berapa 1rem dalam piksel?

1rem setara dengan ukuran font root dalam piksel, yaitu 16px secara default di hampir semua browser. Jadi 1rem = 16px, 1.5rem = 24px, dan 2rem = 32px pada setelan standar. Jika sebuah stylesheet menimpa html { font-size } (misalnya ke 10px lewat trik 62.5%), maka 1rem setara dengan nilai itu.

Sebaiknya pakai rem atau em untuk font-size?

Pakai rem untuk font-size di hampir semua kasus. Rem diukur terhadap root, sehingga tetap dapat diprediksi tidak peduli seberapa dalam sebuah elemen disarangkan. Em diukur terhadap ukuran font induk, yang bertumpuk menuruni pohon dan membuat teks yang disarangkan menggelembung tak terduga. Cadangkan em untuk nilai lokal yang terikat ke satu komponen.

Kapan sebaiknya pakai px alih-alih rem?

Pakai px untuk nilai yang seharusnya tidak ikut skala dengan ukuran font pengguna: border 1px, offset box-shadow yang presisi, garis focus-ring, dan detail rendering tetap lainnya. Ini adalah detail desain yang tajam, bukan konten, jadi mengunci hal-hal ini dalam px adalah pilihan yang lebih ramah aksesibilitas. Semua yang berkaitan dengan konten tetap sebaiknya pakai rem.

Mengapa media query rusak ketika saya pakai px?

Breakpoint media query dalam px tidak merespons zoom ukuran font browser. Ketika pengguna memperbesar font defaultnya, kontennya butuh ruang lebih banyak, tetapi breakpoint px tetap berpindah pada lebar viewport yang sama, sehingga tata letak beralih pada saat yang salah. Pakai breakpoint em atau rem, yang ikut menyesuaikan diri dengan ukuran font pengguna.

Apa itu trik font-size 62.5%?

Trik 62.5% menetapkan html { font-size: 62.5% }, membuat ukuran font root menjadi 10px (62.5% dari 16). Dengan basis 10px, matematika rem menjadi “bagi dengan 10”: 24px = 2.4rem, 12px = 1.2rem. Developer lalu menetapkan body { font-size: 1.6rem } untuk mengembalikan teks body 16px yang nyaman dibaca.

Apakah boleh mencampur px, rem, dan em?

Ya, mencampur px, rem, dan em itu benar ketika masing-masing mengikuti properti yang cocok dengannya: rem untuk tipografi dan spasi, px untuk detail tetap, em untuk nilai lokal yang dicakup ke komponen. Yang menimbulkan masalah adalah mencampurnya tanpa sistem, misalnya sebagian ukuran font dalam px dan sebagian dalam rem. Pilih rem sebagai default dan perlakukan px serta em sebagai pengecualian yang disengaja.

Satuan apa yang sebaiknya saya pakai untuk padding dan margin?

Pakai rem untuk padding dan margin agar spasi ikut menyesuaikan diri bersama teks ketika pengguna mengubah ukuran fontnya. Ini menjaga tata letak tetap proporsional dan ramah aksesibilitas. Cadangkan em untuk padding yang seharusnya mengikuti ukuran font elemen itu sendiri, seperti tombol yang padding-nya tumbuh bersama teksnya, dan hindari em pada kontainer yang disarangkan dalam tempat ia bertumpuk.

Tag: css rem em frontend accessibility responsive-design

Artikel Terkait

Lihat semua artikel