Halo, Habr!
Saya ingin berbagi cara lain untuk membuat transisi css dari properti
height
dari
0px
ke
auto
.
Menghadapi masalah ini ketika mengembangkan komponen Web TreeView dan DataGrid. Di TreeView, saya memutuskan untuk membuat perluasan / keruntuhan node yang mulus, dan di DataGrid - baris dengan konten tambahan. Setelah membaca Internet, saya menemukan beberapa metode implementasi, yang utama melalui properti
max-height
dan dalam javascript. Implementasi javascript dikesampingkan - ada css dengan dukungan untuk transisi dan animasi. Tetap
max-height
, Terutama dalam contoh dengan menu drop-down semuanya berfungsi.
Di TreeView, setiap node memiliki sarang tak terbatas, sehingga Anda tidak dapat langsung menentukan ketinggian maksimum kontennya, dan bahkan jika Anda mengatur
max-height
ke sangat besar, akan ada masalah dengan animasi transisi. Juga, jika Anda memperluas simpul anak, ketinggian induk akan meningkat dan mungkin tumpang tindih
max-height
. Suka atau tidak suka,
max-height
tidak cocok. DataGrid memiliki masalah yang sama - bisa ada konten tambahan dalam satu baris. Perlu
height:auto
!
Jadi, mari kita mulai menerapkan transisi pada properti
height
dari
0px
ke
auto
. Pertimbangkan contoh sederhana.
Biarkan:
elBlock: HTMLDivElement
- blok yang akan elBlock: HTMLDivElement
/ diciutkan;elToggle: HTMLButtonElement
- tombol untuk beralih status.
Tentukan kelas css untuk blok tempat kami mengatur pemangkasan konten dan transisi itu sendiri:
.block { overflow: hidden; transition: height 500ms ease; }
Kami menjelaskan
onClick
event
onClick
untuk
elToggle
:
elToggle.addEventListener("click", () => { if (elBlock.style.height === "0px") { elBlock.style.height = `${ elBlock.scrollHeight }px` } else { elBlock.style.height = `${ elBlock.scrollHeight }px`; window.getComputedStyle(elBlock, null).getPropertyValue("height"); elBlock.style.height = "0"; } });
Tetap menambahkan
height:auto
kembali
height:auto
setelah transisi:
elBlock.addEventListener("transitionend", () => { if (elBlock.style.height !== "0px") { elBlock.style.height = "auto" } });
Nah, itu saja, sekarang perluasan / keruntuhan blok berfungsi sebagaimana mestinya dan tidak tergantung pada ukuran konten.
Gambar 1 - Contoh memperluas / menciutkan node dalam TreeViewPerlu diperhatikan kelemahan dari pendekatan ini:
- menggunakan javascript, saya hanya ingin css;
- selama transisi, konten (tingginya,
scrollHeight
) dapat berubah dan setelah selesai, jika auto
kembali, ketinggian blok akan berubah secara dramatis dalam satu arah atau yang lain. Untuk menghindari efek ini, Anda perlu melacak perubahan pada scrollHeight
dan mengubah height
. Seperti yang diperlihatkan oleh praktik, biasanya memperluas / menutup transisi masing-masing membutuhkan 0,5 detik, dan selama waktu ini pengguna tidak mungkin punya waktu untuk mengubah sesuatu di dalamnya, misalnya, dalam kasus TreeView, perluas node anak.
Terima kasih atas perhatian anda!