Topik wawancara representatif

Wawancara Frontend: Bagaimana Anda mendesain animasi berbasis scroll yang dapat didegradasi dengan CSS?

FrontendSedang
Tim Redaksi Offer.ccDipublikasikan Diperbarui

Pertanyaan

Rancang bilah progres membaca dan efek kemunculan kartu dengan timeline berbasis scroll CSS, serta jelaskan scroll container, view timeline, fallback, dan aksesibilitas.

1. Pertanyaan dan konteks

Sebuah halaman konten membutuhkan bilah progres membaca di bagian atas, dan kartu-kartu harus memudar masuk (fade in) saat memasuki scroll container. Tim awalnya menggunakan event listener scroll dan requestAnimationFrame, tetapi perangkat low-end menunjukkan jank pada main-thread. Rancang ulang dengan CSS Scroll-driven Animations, jelaskan progres scroll versus progres view, serta cakup peramban yang tidak mendukung, reduced motion, dan verifikasi.

2. Apa yang dievaluasi oleh pewawancara

  • Apakah Anda memahami bahwa animasi CSS dapat mengikuti timeline scroll atau timeline view alih-alih timeline berbasis waktu default.
  • Apakah Anda membedakan scroll() yang melacak posisi scroller dari view() yang melacak rentang visibilitas elemen di dalam scroller terdekatnya.
  • Apakah Anda menangani named timeline, rentang animasi, prasyarat overflow, dan urutan reset shorthand.
  • Apakah kompatibilitas, performa, membaca dengan keyboard, reduced motion, dan fallback tanpa JavaScript merupakan bagian dari desain.

3. Klarifikasi yang perlu ditanyakan sebelum menjawab

  1. Apakah bilah progres harus mengikuti dokumen atau scroller artikel bagian dalam?
  2. Apakah kartu harus beranimasi sekali saat masuk, atau bergerak maju dan mundur mengikuti fraksi visibelnya?
  3. Peramban mana saja yang wajib didukung, dan fallback visual serta fungsional seperti apa yang dapat diterima?
  4. Apakah pengguna yang memilih reduced motion tetap harus melihat perubahan progres, dan mungkinkah gerakan memengaruhi urutan membaca atau fokus?

4. Kerangka jawaban 30 detik

Saya akan mengikat bilah baca ke timeline progres scroll milik scroller dan mengikat kartu ke timeline progres view. scroll() merepresentasikan progres dari awal scroller hingga akhirnya; view() merepresentasikan elemen yang masuk dan keluar dari rentang visibel scroller terdekatnya. Keyframe tetap mendefinisikan perubahan visual, sementara animation-timeline menyediakan progresnya. Container harus memiliki jarak scroll yang nyata dan rentang animasi harus eksplisit. Peramban yang tidak mendukung akan mempertahankan petunjuk progres statis atau menggunakan fallback JavaScript ringan yang di-throttle; konten inti tidak pernah bergantung pada gerakan. Saya akan menambahkan pemeriksaan supports, perilaku reduced-motion, pengujian keyboard, dan pengukuran perangkat low-end.

5. Jawaban mendalam langkah demi langkah

Langkah 1: Menetapkan semantik timeline

Timeline progres scroll digerakkan oleh posisi scroller, biasanya bergerak dari 0% di awal hingga 100% di akhir. Timeline progres view digerakkan oleh rentang visibel elemen target relatif terhadap scroller terdekatnya, yang cocok untuk kartu yang masuk dan keluar dari viewport. Keduanya dibangun di atas model timeline CSS Animations dan Web Animations API.

Langkah 2: Mengimplementasikan bilah progres membaca

Buat container artikel benar-benar overflow, beri nama pada timeline scroll-nya, dan arahkan animation-timeline elemen progres ke nama tersebut. Jangan menetapkan animation-timeline tanpa keyframe, dan jangan memperlakukan container tanpa rentang scroll sebagai timeline yang dapat digunakan.

css
.article-scroller {
  overflow-y: auto;
  scroll-timeline-name: --article-scroll;
  scroll-timeline-axis: block;
}

.reading-progress {
  transform-origin: left center;
  animation: grow-progress linear;
  animation-timeline: --article-scroll;
}

@keyframes grow-progress {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

Langkah 3: Mengimplementasikan view timeline untuk kartu

Sebuah kartu dapat menggunakan timeline view() anonim yang melacak visibilitas di scroller leluhur terdekat. Untuk kontrol yang lebih ketat, beri nama dengan view-timeline-name dan sesuaikan batas awal dan akhir dengan view-timeline-inset. Rentang tersebut harus sesuai dengan zona visibel yang diinginkan agar kartu tidak menyelesaikan seluruh animasinya begitu menyentuh tepi.

css
.card {
  animation: reveal-card linear both;
  animation-timeline: view(block 15% 15%);
}

@keyframes reveal-card {
  entry 0% { opacity: 0; transform: translateY(1rem); }
  cover 45% { opacity: 1; transform: translateY(0); }
  exit 100% { opacity: 0.6; }
}

Langkah 4: Menangani rentang dan jebakan shorthand

Timeline bernama dan anonim memerlukan hubungan scroller yang benar; ketidakcocokan pada overflow, sumbu (axis), atau hierarki elemen dapat menyebabkan timeline tidak memiliki progres. Deklarasikan animation-timeline setelah shorthand animation karena shorthand akan mereset komponen timeline yang diabaikan ke nilai defaultnya. Gunakan animation-range atau keyframe rentang untuk fase entry, cover, dan exit yang eksplisit, lalu uji di peramban target.

Langkah 5: Mendesain fallback dan verifikasi aksesibilitas

Gunakan @supports untuk mendeteksi animation-timeline. Jika peningkatan visual tidak tersedia, pertahankan petunjuk progres statis, urutan membaca normal, dan kontras yang mudah dibaca. Jika fallback dinamis diperlukan, terapkan throttle pada pekerjaan scroll dan hindari layout berulang. Di bawah prefers-reduced-motion: reduce, hapus translasi dan gerakan terus-menerus sambil tetap mempertahankan informasi progres dan urutan fokus. Uji scrolling keyboard, pembaca layar (screen reader), scrolling cepat berlawanan arah, scroller bersarang, dan waktu frame pada perangkat low-end.

6. Contoh jawaban berkualitas tinggi

Saya akan mengikat bilah baca ke timeline progres scroll pada scroller artikel dan kartu ke timeline progres view pada scroller terdekatnya. Yang pertama merepresentasikan posisi scroll dari 0% hingga 100%; yang kedua merepresentasikan elemen yang masuk, menutupi, dan keluar dari rentang visibel. Saya akan memverifikasi overflow nyata, lalu mendefinisikan keyframe dan animation-timeline dalam urutan yang mencegah shorthand mereset timeline. @supports akan menyediakan fallback statis, dengan JavaScript yang di-throttle hanya jika diperlukan. Reduced-motion akan menghapus translasi dan efek berkelanjutan sambil mempertahankan konten, progres, dan fokus. Saya akan memverifikasi penggunaan keyboard, pembaca layar, scrolling bersarang, dan frame time perangkat low-end.

7. Kesalahan umum

  • Memperlakukan scroll() dan view() sebagai progres yang sama → kartu tidak mengikuti visibilitas → jelaskan posisi scroller versus visibilitas elemen terlebih dahulu.
  • Mendeklarasikan scroll timeline pada container yang tidak overflow → tidak ada progres animasi → periksa ukuran konten, overflow, dan sumbu.
  • Membiarkan shorthand animation menimpa animation-timeline → timeline default dipulihkan → deklarasikan kembali animation-timeline setelah shorthand.
  • Menampilkan konten hanya di peramban modern → peramban lama kehilangan perilaku inti → pertahankan petunjuk statis dan urutan membaca normal.
  • Hanya menyetel opacity ke nol untuk reduced motion → umpan balik visual hilang → hapus translasi dan gerakan terus-menerus sambil mempertahankan status semantik dan visibel.

8. Pertanyaan lanjutan dan jawabannya

Pertanyaan lanjutan 1: Kapan Anda menggunakan scroll timeline versus view timeline?

Gunakan scroll timeline untuk progres di seluruh wilayah scroll. Gunakan view timeline untuk elemen yang masuk, menutupi, dan keluar dari scroller. Faktor penentunya adalah sumber progres, bukan apakah JavaScript ada atau tidak.

Pertanyaan lanjutan 2: Mengapa animation-timeline dideklarasikan tetapi tidak menghasilkan animasi?

Penyebab umumnya adalah tidak ada rentang scroll nyata, ketidakcocokan sumbu, nama timeline di luar hubungan leluhur, atau shorthand animation yang dideklarasikan belakangan mereset timeline. Periksa overflow, hubungan timeline, dan urutan deklarasi dalam urutan tersebut.

Pertanyaan lanjutan 3: Bagaimana cara mendegradasi untuk peramban yang lebih lama?

Pertahankan petunjuk progres statis dan konten lengkap. Jika progres dinamis sangat penting, gunakan listener scroll yang di-throttle untuk pembaruan kecil. Fallback tidak boleh mengubah urutan membaca, akses keyboard, atau perilaku fokus.

Pertanyaan lanjutan 4: Bagaimana cara menghormati reduced motion?

Di bawah prefers-reduced-motion: reduce, hapus translasi, penskalaan, dan gerakan berdurasi panjang. Pertahankan pembaruan progres statis atau instan, urutan konten, dan umpan balik yang mudah dibaca, serta verifikasi bahwa scroll cepat tidak menyembunyikan informasi.

Sumber publik

Pertanyaan terkait