D
P
0

HTML & CSS

Panel Accordion `max-height: 0` Masih Bocorkan Sesempil Konten? Padding yang Nyelip Lewat `overflow: hidden`

11 Juli 2026·3 menit baca
Panel Accordion `max-height: 0` Masih Bocorkan Sesempil Konten? Padding yang Nyelip Lewat `overflow: hidden`

Saya lagi menyelesaikan blok FAQ di landing page sebuah klien, jenis accordion klasik: klik pertanyaan, jawaban meluncur turun. Saya bangun dengan pendekatan CSS yang paling saya percaya untuk animasi tinggi: max-height yang dianimasikan, plus overflow: hidden supaya isinya tidak tumpah saat lagi tertutup. Buka-tutupnya mulus. Selesai, pikir saya.

Lalu klien mengirim screenshot. Di antara pertanyaan-pertanyaan yang tertutup ada sesempil teks yang mengintip, garis tipis di mana seharusnya tidak ada apa-apa. Dan lebih menyebalkan lagi, tiap item tertutup itu masih memakan ruang vertikal yang tidak seharusnya. Panel yang saya kira sudah 0 tinggi ternyata tidak benar-benar 0.

Refleks pertama saya salah. Saya kira max-height-nya tidak benar-benar 0, jadi saya buka DevTools dan cek computed value. Betul-betul max-height: 0px. Saya kira ada baris jawaban yang lolos animasi. Bukan. Elemennya benar tertutup, computed max-height-nya nol, tapi kotaknya masih punya tinggi. Itu kombinasi yang aneh dan justru itu petunjuknya.

Kenapa ini terjadi

Kesalahpahamannya ada di satu asumsi yang selama ini saya bawa: bahwa overflow: hidden memotong tepat di tepi elemen. Tidak. overflow: hidden memotong di padding-box, bukan content-box. Artinya padding elemen itu sendiri berada di dalam area yang di-clip, bukan di luarnya.

Jadi begitu panel jawaban saya punya padding vertikal, misalnya padding: 1rem 0 yang saya set di satu aturan supaya jawaban tampil rapi saat terbuka, padding itu tidak ikut hilang saat max-height jadi 0. max-height: 0 membatasi tinggi content-box menjadi nol, tapi padding atas dan bawah tetap ada di luar content-box dan tetap dirender. overflow: hidden tidak menolongnya karena padding ada di dalam padding-box, area yang justru dianggap "aman" oleh clip. Hasilnya: total tinggi kotak jadi padding-top + 0 + padding-bottom, bukan nol. Dan karena content-box-nya cuma dipepet ke nol, bukan benar-benar dikosongkan, sesempil baris teks paling atas masih sempat terlihat di celah padding itu sebelum ter-clip.

Begitu cara berpikir ini klik, semuanya masuk akal. Panelnya tidak pernah benar-benar nol karena saya cuma menolkan salah satu dari dua komponen tinggi. Yang bocor bukan konten yang lolos, tapi padding yang memang saya suruh tetap ada.

Perbaikannya

Solusinya bukan mengganti overflow: hidden. Solusinya adalah memastikan tidak ada apa pun yang tersisa di dalam area clip saat panel tertutup, dan itu berarti padding-nya juga harus nol di state collapse. Bukan cuma max-height.

Jadi saya pindahkan padding ke state terbuka saja. Saat tertutup, padding: 0. Saat terbuka, padding baru muncul bersama max-height:

.faq-item .answer {
  max-height: 0;
  overflow: hidden;
  padding: 0;
  transition: max-height 0.3s ease, padding 0.3s ease;
}
 
.faq-item.open .answer {
  max-height: 500px;
  padding: 1rem 0;
}

Kuncinya ada di dua hal. Pertama, padding: 0 di state default, bukan cuma di max-height. Kedua, padding ikut dianimasikan bersama max-height di properti transition, supaya saat toggle keduanya bergerak barengan dan tidak ada lompatan padding yang muncul mendadak sebelum tinggi menyusul. Begitu saya deploy ini, garis tipis yang mengintip hilang, dan tiap item tertutup benar-benar tidak memakan ruang vertikal lagi. Kotaknya betul-betul nol.

Kalau mau lebih rapi lagi dan tidak mau menebak angka 500px, sekarang saya sering pindah ke grid-template-rows: 0fr ke 1fr untuk animasi tinggi otomatis. Tapi jebakan padding-nya sama persis: apa pun yang punya padding vertikal di dalam track yang di-clip tetap harus dinolkan saat tutup. Prinsipnya tidak berubah, cuma mekanismenya.

Pelajaran

overflow: hidden itu bukan "sembunyikan semua yang melebihi tepi elemen", tapi "potong di padding-box". Selama masih ada padding vertikal di elemen yang saya kira sudah nol, kotak itu tidak akan pernah benar-benar nol, dan konten paling atas bisa mengintip lewat celah padding sebelum ter-clip. Kalau kamu menganimasikan max-height untuk collapse, nolkan juga padding-nya di state tertutup dan animasikan keduanya bersama. Sejak itu, tiap kali saya bikin accordion, saya berhenti cuma memikirkan tinggi konten dan mulai bertanya: apa lagi yang masih nyempil di dalam area clip ini?