1. Perintah dan konteks
Sebuah dialog disembunyikan dengan display: none. Tim produk menginginkannya memudar masuk dan keluar (fade in and out), serta baru meninggalkan tata letak setelah animasi selesai. Tim hanya mentransisikan opacity, sehingga animasi masuk tidak terlihat dan saat keluar langsung menghilang seketika. Jelaskan properti diskret, rancang CSS-nya, dan cakup fallback browser, manajemen fokus, serta prefers-reduced-motion.
2. Apa yang diuji oleh pewawancara
- Apakah Anda mengetahui bahwa properti diskret seperti
displaydancontent-visibilitytidak memiliki nilai perantara yang kontinu. - Apakah Anda dapat menggunakan
transition-behavior: allow-discreteatau bentuk singkatnya (shorthand) dengan benar alih-alih memperlakukannya sebagai durasi. - Apakah Anda memahami bahwa waktu pergantian (flip timing) berbeda untuk masuk dan keluar, serta bahwa
@starting-stylemenetapkan gaya awal. - Apakah Anda menyertakan kompatibilitas, aksesibilitas, fokus, pengurangan gerakan (reduced motion), dan pengujian rendering nyata.
3. Pertanyaan klarifikasi sebelum menjawab
- Apakah ini elemen normal, dialog bawaan (native dialog), atau popover top-layer?
- Haruskah elemen tersebut meninggalkan tata letak dan tidak dapat difokuskan, atau sekadar melewati proses paint sudah cukup?
- Versi browser apa saja yang didukung, dan apa fallback-nya tanpa transisi diskret?
- Bagaimana perilaku fokus, tombol Escape, klik backdrop, dan preferensi reduced-motion selama animasi berlangsung?
4. Kerangka jawaban 30 detik
display bersifat diskret, sehingga tidak melakukan interpolasi secara default. Gunakan transition-behavior: allow-discrete untuk mengaktifkannya dalam transisi dan berikan juga durasi non-nol untuk opacity atau transform. Saat masuk, beralihlah ke nilai terlihat cukup awal untuk keseluruhan durasi animasi; saat keluar, pertahankan elemen tetap terlihat hingga akhir. Gunakan @starting-style untuk frame pertama yang disisipkan. Browser yang lebih lama dapat mengabaikan peningkatan ini sambil tetap mempertahankan fallback kontinu; fokus, semantik tersembunyi, dan reduced motion tetap memerlukan penanganan eksplisit.
5. Jawaban mendalam langkah demi langkah
Langkah 1: Pisahkan properti kontinu dan diskret
opacity dan transform dapat menghasilkan nilai perantara yang kontinu; display hanya beralih antar nilai. Tanpa allow-discrete, browser mengubah display secara instan, sehingga elemen yang menutup akan dihapus sebelum transisi opacity-nya sempat terlihat dan elemen yang membuka tidak memiliki frame awal yang terlihat. transition-behavior hanya mengizinkan transisi diskret; transition-property dan transition-duration bernilai non-nol tetap diperlukan.
Langkah 2: Bangun transisi panel dua arah
Deklarasikan fallback kontinu terlebih dahulu, kemudian deklarasi yang disempurnakan dengan allow-discrete. Selama keluar, display harus berganti mendekati 100% sehingga konten tetap terlihat; selama masuk, nilainya harus beralih ke nilai terlihat lebih awal. Jangan hanya mendeklarasikan transition-behavior dan melupakan target opacity atau status transform.
.panel {
opacity: 0;
transform: translateY(-0.5rem);
display: none;
transition: opacity 180ms ease, transform 180ms ease;
transition: opacity 180ms ease, transform 180ms ease, display 180ms allow-discrete;
}
.panel[data-open="true"] {
opacity: 1;
transform: translateY(0);
display: block;
}Langkah 3: Tangani penyisipan pertama dan popover
Ketika sebuah elemen disisipkan secara dinamis atau popover dibuka untuk pertama kalinya, mungkin tidak ada gaya terlihat sebelumnya untuk dibandingkan. @starting-style menyediakan opacity dan transform awal. Popover native juga masuk ke top layer, sehingga display dan overlay perlu disertakan dalam transisi diskret, jika tidak, elemen yang keluar akan dihapus secara instan. Uji kombinasi ini pada versi browser target.
Langkah 4: Rancang fallback dan deteksi fitur
Browser lama mengabaikan nilai allow-discrete yang tidak dikenal, tetapi harus tetap mempertahankan transisi opacity/transform dasar. Letakkan aturan peningkatan di balik @supports (transition-behavior: allow-discrete) jika diperlukan, daripada menyembunyikan seluruh gaya dasar. Fallback harus tetap dapat membuka, menutup, menerima fokus, dan mengekspos semantik tersembunyi yang benar.
Langkah 5: Aksesibilitas, performa, dan verifikasi
Animasi bukanlah status aksesibilitas. Saat ditutup, sinkronkan hidden, aria-hidden, atau status native dialog dan kembalikan fokus ke pemicu; saat dibuka, pindahkan fokus ke dalam dan dukung tombol Escape. Kurangi atau hilangkan durasi di bawah prefers-reduced-motion: reduce. Uji tata letak, paint, fokus keyboard, pembaca layar, pengalihan cepat (rapid toggles), transisi yang terputus, dan biaya tata letak/compositing pada perangkat berspesifikasi rendah.
6. Contoh jawaban berkualitas tinggi
displaybersifat diskret dan tidak memiliki nilai perantara kontinu seperti opacity. Saya akan mempertahankan transisi opacity/transform dasar, kemudian mengikutsertakan display ke jalur yang disempurnakan menggunakantransition-behavior: allow-discrete; saat masuk, nilainya berganti ke terlihat lebih awal, sedangkan saat keluar, nilainya tetap terlihat hingga akhir.@starting-stylemenyediakan frame pertama, dan popover juga memerlukan penanganan display dan overlay top-layer. Browser lama akan mengabaikan peningkatan ini tetapi tetap mempertahankan animasi dasar. Saya juga akan menyinkronkan fokus, Escape, semantik tersembunyi, dan reduced motion, kemudian memverifikasi perilakunya di berbagai browser dan alur keyboard.
7. Kesalahan umum
- Hanya mentransisikan opacity → display langsung berubah seketika → tambahkan allow-discrete sambil mempertahankan properti kontinu.
- Memperlakukan
transition-behaviorsebagai durasi → properti diskret tetap tidak bertransisi → deklarasikan properti tersebut dan juga durasi non-nol. - Mengubah display menjadi none di awal animasi keluar → efek fade tidak terlihat → sejajarkan pergantian diskret dengan akhir durasi keluar.
- Mengabaikan penyisipan pertama → pembukaan pertama tidak memiliki animasi masuk → tentukan frame awal dengan
@starting-style. - Hanya menguji dengan mouse dan browser modern → status keyboard, pembaca layar, atau fallback gagal → sertakan pemeriksaan fallback supports, fokus, dan reduced-motion.
8. Pertanyaan lanjutan dan tanggapan
Mengapa display harus beralih di akhir animasi keluar?
Jika langsung beralih ke none seketika, elemen akan keluar dari tata letak dan rendering, sehingga tidak ada konten terlihat selama sisa durasi opacity. Pertahankan elemen tetap terlihat mendekati 100%, lalu masuk ke status tersembunyi.
Apakah allow-discrete menginterpolasi display di setiap frame?
Tidak. Properti ini hanya mengizinkan nilai diskret untuk berpartisipasi dalam transisi, tetapi nilainya tetap berganti pada titik tertentu yang telah ditentukan. Perubahan visual yang kontinu berasal dari opacity, transform, atau properti lain yang dapat diinterpolasi.
Bagaimana cara menjaga browser lama tetap dapat digunakan?
Deklarasikan transisi dasar tanpa allow-discrete terlebih dahulu, kemudian tingkatkan dengan @supports atau deklarasi setelahnya. Jika fitur penyempurnaan tidak tersedia, terima pergantian display seketika sambil mempertahankan perilaku tombol, fokus, dan semantik tersembunyi.
Bagaimana cara menangani preferensi reduced motion?
Di bawah prefers-reduced-motion: reduce, persingkat durasi secara substansial atau atur ke nol sambil tetap mempertahankan sinkronisasi status, perpindahan fokus, dan kontrol penutupan. Jangan hanya menyembunyikan animasi dan meninggalkan elemen tak terlihat yang masih dapat difokuskan.