1. Soalan dan konteks
Halaman kandungan memerlukan bar kemajuan bacaan di bahagian atas, dan kad harus memudar masuk (fade in) apabila ia memasuki bekas tatal. Pasukan pada mulanya menggunakan pendengar acara tatal dan requestAnimationFrame, tetapi peranti berspesifikasi rendah menunjukkan masalah kegagapan (jank) pada benang utama. Reka bentuk semula dengan Animasi Dipacu Tatal CSS (CSS Scroll-driven Animations), terangkan kemajuan tatal berbanding kemajuan paparan, dan rangkumi pelayar yang tidak disokong, pergerakan dikurangkan (reduced motion) serta pengesahan.
2. Perkara yang dinilai oleh penemu duga
- Sama ada anda memahami bahawa animasi CSS boleh mengikut garis masa tatal atau garis masa paparan dan bukannya garis masa berasaskan masa lalai.
- Sama ada anda membezakan scroll() yang menjejaki kedudukan penatal daripada view() yang menjejaki julat keterlihatan elemen di dalam penatal terdekatnya.
- Sama ada anda mengendalikan garis masa dinamakan, julat animasi, prasyarat overflow dan susunan tetapan semula trengkas (shorthand).
- Sama ada keserasian, prestasi, pembacaan papan kekunci, pergerakan dikurangkan dan sandaran tanpa JavaScript adalah sebahagian daripada reka bentuk.
3. Penjelasan yang perlu ditanya sebelum menjawab
- Adakah bar kemajuan harus mengikut dokumen atau penatal artikel dalaman?
- Adakah kad perlu dianimasikan sekali sahaja semasa masuk, atau bergerak ke hadapan dan ke belakang mengikut pecahan keterlihatannya?
- Pelayar manakah yang diperlukan, dan apakah sandaran visual serta fungsi yang boleh diterima?
- Adakah pengguna yang memilih pergerakan dikurangkan masih perlu melihat perubahan kemajuan, dan mungkinkah pergerakan menjejaskan susunan bacaan atau fokus?
4. Rangka kerja jawapan 30 saat
Saya akan mengikat bar bacaan pada garis masa kemajuan tatal penatal dan mengikat kad pada garis masa kemajuan paparan. scroll() mewakili kemajuan dari awal penatal hingga ke akhirnya; view() mewakili elemen yang masuk dan keluar dari julat keterlihatan penatal terdekatnya. Keyframe masih mentakrifkan perubahan visual, manakala animation-timeline membekalkan kemajuan. Bekas mesti mempunyai jarak boleh tatal yang sebenar dan julat animasi mestilah eksplisit. Pelayar yang tidak disokong mengekalkan pembayang kemajuan statik atau menggunakan sandaran JavaScript ringan yang dihadkan (throttled); kandungan teras tidak sekali-kali bergantung pada pergerakan. Saya akan menambah semakan supports, tingkah laku reduced-motion, ujian papan kekunci dan ukuran peranti berspesifikasi rendah.
5. Jawapan mendalam langkah demi langkah
Langkah 1: Menetapkan semantik garis masa
Garis masa kemajuan tatal dipacu oleh kedudukan penatal, biasanya bergerak dari 0% pada permulaan kepada 100% pada penghujung. Garis masa kemajuan paparan dipacu oleh julat keterlihatan elemen sasaran relatif kepada penatal terdekatnya, yang sesuai untuk kad yang masuk dan keluar dari viewport. Kedua-duanya dibina berasaskan model garis masa CSS Animations dan Web Animations API.
Langkah 2: Melaksanakan bar kemajuan bacaan
Jadikan bekas artikel benar-benar melimpah (overflow), namakan garis masa tatalknya, dan halakan animation-timeline elemen kemajuan kepada nama tersebut. Jangan tetapkan animation-timeline tanpa keyframe, dan jangan anggap bekas tanpa julat tatal sebagai garis masa yang boleh digunakan.
.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: Melaksanakan garis masa paparan untuk kad
Kad boleh menggunakan garis masa view() tanpa nama yang menjejaki keterlihatan dalam penatal leluhur terdekat. Untuk kawalan yang lebih ketat, namakannya dengan view-timeline-name dan laraskan sempadan mula dan tamat dengan view-timeline-inset. Julat harus sepadan dengan zon keterlihatan yang dimaksudkan supaya kad tidak menyelesaikan keseluruhan animasinya sebaik sahaja ia menyentuh tepi.
.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: Mengendalikan julat dan perangkap trengkas
Garis masa dinamakan dan tanpa nama memerlukan hubungan penatal yang betul; ketidakpadanan dalam overflow, paksi atau hierarki elemen boleh menyebabkan garis masa tiada kemajuan. Isytiharkan animation-timeline selepas trengkas animation kerana trengkas menetapkan semula komponen garis masa yang ditinggalkan kepada lalainya. Gunakan animation-range atau keyframe julat untuk fasa entry, cover dan exit yang jelas, kemudian uji dalam pelayar sasaran.
Langkah 5: Mereka bentuk sandaran dan pengesahan kebolehcapaian
Gunakan @supports untuk mengesan animation-timeline. Apabila peningkatan tidak tersedia, kekalkan pembayang kemajuan statik, susunan bacaan biasa dan kontras yang boleh dibaca. Jika sandaran dinamik diperlukan, hadkan (throttle) kerja tatal dan elakkan pengiraan susun atur berulang. Di bawah prefers-reduced-motion: reduce, alih keluar translasi dan pergerakan berterusan sambil mengekalkan maklumat kemajuan dan susunan fokus. Uji penatalan papan kekunci, pembaca skrin, penatalan pantas berbalik, penatal bersarang dan masa bingkai pada peranti berspesifikasi rendah.
6. Contoh jawapan berkualiti tinggi
Saya akan mengikat bar bacaan pada garis masa kemajuan tatal penatal artikel dan kad pada garis masa kemajuan paparan dalam penatal terdekatnya. Yang pertama mewakili kedudukan tatal dari 0% hingga 100%; yang kedua mewakili elemen yang masuk, meliputi dan keluar dari julat keterlihatan. Saya akan mengesahkan limpahan sebenar, kemudian mentakrifkan keyframe dan animation-timeline dalam susunan yang menghalang trengkas daripada menetapkan semula garis masa. @supports akan menyediakan sandaran statik, dengan JavaScript yang dihadkan hanya apabila perlu. Reduced-motion akan mengalih keluar translasi dan kesan berterusan sambil mengekalkan kandungan, kemajuan dan fokus. Saya akan mengesahkan penggunaan papan kekunci, pembaca skrin, penatalan bersarang dan masa bingkai peranti berspesifikasi rendah.
7. Kesilapan biasa
- Menganggap scroll() dan view() sebagai kemajuan yang sama → kad tidak mengikut keterlihatan → terangkan kedudukan penatal berbanding keterlihatan elemen terlebih dahulu.
- Mengisytiharkan garis masa tatal pada bekas yang tidak melimpah (overflow) → tiada kemajuan animasi → periksa saiz kandungan, overflow dan paksi.
- Membiarkan trengkas animation menimpa animation-timeline → garis masa lalai dipulihkan → isytiharkan animation-timeline sekali lagi selepas trengkas.
- Menunjukkan kandungan hanya dalam pelayar moden → pelayar lama kehilangan tingkah laku teras → kekalkan pembayang statik dan susunan bacaan biasa.
- Menetapkan opacity sahaja kepada sifar untuk pergerakan dikurangkan → maklum balas hilang → alih keluar translasi dan pergerakan berterusan sambil mengekalkan keadaan semantik dan kelihatan.
8. Soalan susulan dan jawapan
Soalan susulan 1: Bilakah anda menggunakan garis masa tatal berbanding garis masa paparan?
Gunakan garis masa tatal untuk kemajuan merentasi keseluruhan kawasan penatalan. Gunakan garis masa paparan untuk elemen yang masuk, meliputi dan keluar dari penatal. Faktor penentu ialah punca kemajuan, bukan sama ada JavaScript hadir atau tidak.
Soalan susulan 2: Mengapakah animation-timeline diisytiharkan tetapi tidak menghasilkan animasi?
Punca biasa ialah tiada julat tatal sebenar, ketidakpadanan paksi, nama garis masa di luar hubungan leluhur, atau trengkas animation yang diisytiharkan kemudian menetapkan semula garis masa. Semak overflow, hubungan garis masa dan susunan pengisytiharan mengikut urutan tersebut.
Soalan susulan 3: Bagaimanakah anda menurunkan taraf (degrade) untuk pelayar yang lebih lama?
Kekalkan pembayang kemajuan statik dan kandungan yang lengkap. Jika kemajuan dinamik adalah penting, gunakan pendengar tatal yang dihadkan (throttled) untuk kemas kini kecil. Sandaran tidak boleh mengubah susunan bacaan, akses papan kekunci atau tingkah laku fokus.
Soalan susulan 4: Bagaimanakah anda menghormati pergerakan dikurangkan (reduced motion)?
Di bawah prefers-reduced-motion: reduce, alih keluar translasi, penskalaan dan pergerakan yang berjalan lama. Kekalkan kemas kini kemajuan statik atau serta-merta, susunan kandungan dan maklum balas yang boleh dibaca, serta sahkan bahawa penatalan pantas tidak menyembunyikan maklumat.