Dipublikasikan: 26 Februari 2026
Animasi yang didorong scroll telah berkembang dari penerapan JavaScript thread utama yang tidak lancar menjadi pengalaman yang lancar, dapat diakses, dan di luar thread utama menggunakan fitur CSS dan UI modern seperti Linimasa Scroll dan Linimasa Tampilan. Pergeseran ini memungkinkan pembuatan prototipe yang cepat dan animasi berperforma tinggi, sekaligus memungkinkan tim membuat halaman scrollytelling yang rapi seperti yang ditunjukkan dalam artikel ini.
NRK dan bercerita
NRK (Norwegian Broadcasting Corporation) adalah penyiar layanan publik di Norwegia. Tim di balik penerapan yang dijelaskan dalam artikel ini disebut Visuelle Historier dalam bahasa Norwegia, yang secara kasar diterjemahkan menjadi Visual Stories dalam bahasa Inggris. Tim ini menangani desain, grafis, dan pengembangan untuk project editorial TV, radio, dan web, serta mengembangkan identitas visual, grafis konten, artikel utama, dan format bercerita visual baru. Tim ini juga bekerja sama dengan profil desain dan sub-merek NRK, membuat alat dan template untuk mempermudah publikasi konten sesuai dengan identitas merek NRK.
Cara NRK menggunakan animasi berbasis scroll
Animasi yang dipicu scroll dan didorong scroll meningkatkan kualitas artikel penceritaan mereka dengan membuatnya lebih interaktif, menarik, dan berkesan. Pendekatan ini sangat berguna dalam narasi non-fiksi yang hanya memiliki sedikit atau tidak ada gambar.
Animasi ini membantu memperkuat atau menciptakan poin dramaturgis, mendorong cerita ke depan, dan mengembangkan narasi visual kecil yang selaras dengan atau memperkuat teks. Dengan didorong scroll, animasi ini memungkinkan pengguna mengontrol progres narasi melalui scroll mereka.
Meningkatkan pengalaman pengguna
Insight pengguna NRK mengungkapkan bahwa pembaca menghargai cara animasi ini memandu fokus mereka. Dengan menandai teks atau animasi saat mereka men-scroll, pengguna akan lebih mudah mengidentifikasi poin-poin penting dan memahami aspek paling penting dari cerita, terutama saat men-skimming.
Selain itu, animasi grafis dapat menyederhanakan informasi yang kompleks, sehingga memudahkan pengguna memahami hubungan dan perubahan dari waktu ke waktu. Dengan membuat, menambahkan, atau menandai informasi secara dinamis, NRK dapat menyajikan konten dengan cara yang lebih pedagogis dan menarik.
Menyetel suasana hati
Animasi dapat menjadi alat yang efektif untuk menetapkan atau meningkatkan suasana cerita. Dengan menyesuaikan waktu, kecepatan, dan gaya animasi, NRK dapat membangkitkan emosi yang cocok dengan nuansa narasi.
Membagi teks dan memberikan kelegaan visual
NRK sering menggunakan ilustrasi animasi kecil untuk memecah blok teks yang panjang dalam bentuk dinkus sederhana atau ilustrasi kecil, sehingga pembaca dapat berhenti sejenak dari narasi. Banyak pengguna menyukai variasi ini, dengan memperhatikan bahwa variasi ini memecah teks dan membuatnya lebih mudah dicerna. Mereka merasa bahwa jeda tersebut memberikan jeda yang menyenangkan dalam narasi.
Menghormati kebutuhan aksesibilitas dan preferensi pengguna
Halaman publik NRK harus dapat diakses oleh semua warga Norwegia. Oleh karena itu, halaman harus mematuhi preferensi pengguna untuk mengurangi gerakan. Semua konten halaman harus tersedia untuk pengguna yang telah mengaktifkan setelan browser ini.
Mendesain animasi berbasis scroll
NRK telah menyederhanakan alur kerja desain dengan mengembangkan dan mengintegrasikan alat animasi scroll baru langsung ke dalam Sistem Pengelolaan Konten (CMS) Sanity mereka. Dikembangkan melalui kolaborasi antara tim yang mengembangkan dan mengelola situs serta solusi CMS, alat ini memungkinkan desainer membuat prototipe dan menerapkan animasi scroll dengan mudah menggunakan isyarat visual untuk posisi awal dan akhir elemen animasi, serta kemampuan untuk melihat pratinjau animasi secara real time. Inovasi ini memberi desainer kontrol yang lebih besar dan mempercepat proses desain langsung dalam CMS.

Animasi berbasis scroll di browser
Animasi berbasis cerita
Artikel tentang seorang pria yang tetap meninggal di apartemennya selama sembilan tahun ini harus sangat mengandalkan ilustrasi karena kurangnya elemen visual lainnya. Ilustrasi dianimasikan melalui scroll untuk menekankan narasi, seperti dalam animasi saat malam tiba, lampu di gedung bertingkat menyala secara bertahap hingga hanya satu apartemen yang tetap tidak menyala. Animasi dibuat menggunakan alat animasi berbasis scroll internal NRK.
Animasi memudar teks
Artikel ini dimulai dengan pengantar singkat, yang mencerminkan urutan pembuka film. Teks ringkas yang dipadukan dengan visual layar penuh didesain untuk mengisyaratkan konten artikel, sehingga membangun ekspektasi untuk mendorong pembaca mempelajari artikel secara menyeluruh. Halaman judul dibuat agar menyerupai poster film, dengan animasi berbasis scroll yang digunakan untuk memperkuat sensasi ini dengan menganimasikan teks ke atas dan ke luar dengan lancar.
.article-section {
animation: fade-up linear;
animation-timeline: view();
animation-range: entry 100% exit 100%;
}
Tipografi animasi scroll
Tipografi animasi dalam judul artikel—Cuti sakit.
Dengan pengantar "Sjukt sjuke" (yang secara kasar diterjemahkan menjadi "Sickly sick"), NRK ingin menarik pembaca ke artikel tentang meningkatnya rasio cuti sakit di Norwegia. Judul ini dimaksudkan untuk menjadi daya tarik visual yang memberi pembaca petunjuk bahwa ini bukan cerita biasa yang membosankan dan berfokus pada angka yang mungkin mereka harapkan. Tim NRK ingin teks dan ilustrasi sesuai dengan tema karya, menggunakan tipografi dan animasi yang didorong scroll untuk meningkatkan kualitasnya. Artikel ini menggunakan font dan profil desain baru NRK News.
<h1 aria-label="sjuke">
<span>s</span><span>j</span><span>u</span><span>k</span><span>e</span>
<h1>
h1 span {
display: inline-block;
}
if (window.matchMedia('print, (prefers-reduced-motion: reduce)').matches) {
return;
}
const heading = document.querySelector("h1");
const letters = heading.querySelectorAll("span");
const timeline = new ViewTimeline({ subject: heading });
const scales = [/**/];
const rotations = [/**/];
for ([index, el] of letters.entries()) {
el.animate(
{
scale: ["1", scales[index]],
rotate: ["0deg", rotations[index]]
},
{
timeline,
fill: "both",
rangeStart: "contain 30%",
rangeEnd: "contain 70%",
easing: "ease-out"
}
);
}
Menandai item yang di-snap scroll
Pembaca yang telah menyelesaikan artikel sering kali ingin membaca lebih lanjut tentang masalah yang sama. Dalam artikel tentang remaja yang menyalahgunakan zat di lembaga, NRK ingin merekomendasikan satu artikel sebagai bacaan berikutnya, sekaligus memberi pembaca opsi beberapa artikel lainnya jika mereka menginginkannya. Solusi ini adalah navigasi yang dapat digeser yang diterapkan dengan animasi scroll snap dan scroll-driven. Animasi memastikan bahwa elemen aktif berada dalam fokus, sementara elemen lainnya diredupkan.
for (let item of items) {
const timeline = new ViewTimeline({ subject: item, axis: "inline" });
const animation = new Animation(effect, timeline);
item.animate(
{
opacity: [0.3, 1, 0.3]
},
{ timeline, easing: "ease-in-out", fill: "both" }
);
animation.rangeStart = "cover calc(50% - 100px)";
animation.rangeEnd = "cover calc(50% + 100px)";
}
Animasi scroll yang memicu animasi reguler
Dalam artikel tentang anggaran nasional Norwegia ini, NRK bertujuan untuk membuat cerita berbasis angka yang berat dan membosankan menjadi lebih mudah diakses dan dipersonalisasi. Tujuannya adalah untuk menguraikan angka anggaran yang sangat besar dan tidak dapat dipahami serta memberi pembaca gambaran pribadi tentang apa yang dibeli dengan uang pajak mereka. Setiap subbagian berfokus pada item tertentu dalam anggaran nasional. Total kontribusi pajak pembaca dilambangkan dengan batang biru yang dibagi untuk mengungkapkan kontribusi pembaca terhadap setiap item ini. Transisi ini dicapai dengan animasi yang didorong scroll yang memicu setiap item untuk dianimasikan.
const timeline = new ViewTimeline({
subject: containerElement
});
// Setup scroll-driven animation
const scrollAnimation = containerElement.animate(
{
"--cover-color": ["blue", "lightblue"],
scale: ["1 0.2", "1 3"]
},
{
timeline,
easing: "cubic-bezier(1, 0, 0, 0)",
rangeStart: "cover 0%",
rangeEnd: "cover 50%"
}
);
// Wait for scroll-driven animation to complete
await scrollAnimation.finished;
scrollAnimation.cancel();
// Trigger time-driven animations
for (let [index, postElement] of postElements.entries()) {
const animation = postElement?.animate(
{ scale: ["1 3", "1 1"] },
{
duration: 200,
delay: index * 33,
easing: "ease-out",
fill: "backwards"
}
);
}
"Kami telah melakukan animasi berbasis scroll sejak lama. Sebelum Web Animations API ada, kita harus menggunakan peristiwa scroll, yang kemudian digabungkan dengan Intersection Observer API. Hal ini sering kali merupakan tugas yang sangat memakan waktu, dan sekarang menjadi mudah dengan Web Animations dan Scroll-Driven Animations API"—Helge Silset, Front-end Developer di NRK
NRK memiliki banyak Web
Components yang dapat dicolokkan
ke salah satu elemen kustomnya, yang disebut ScrollAnimationDriver
(<scroll-animation-driver>
), yang mendukung animasi berikut:
- Lapisan dengan
[KeyframeEffects](https://developer.mozilla.org/docs/Web/API/KeyframeEffect)
- Animasi Lottie
- mp4
- three.js
<canvas>
Contoh berikut menggunakan lapisan dengan KeyframeEffects
:
<scroll-animation-driver data-range-start='entry-crossing 50%' data-range-end='exit-crossing 50%'>
<layered-animation-effect>
<picture>
<source />
<img />
</picture>
<picture>
<source />
<img />
</picture>
<picture>
<source />
<img />
</picture>
</layered-animation-effect>
</scroll-animation-driver>
Implementasi JavaScript NRK untuk elemen kustom <scroll-animation-driver>
mereka:
export default class ScrollAnimationDriver extends HTMLElement {
#timeline
connectedCallback() {
this.#timeline = new ViewTimeline({subject: this})
for (const child of this.children) {
for (const effect of child.effects ?? []) {
this.#setupAnimationEffect(effect)
}
}
}
#setupAnimationEffect(effect) {
const animation = new Animation(effect, this.#timeline)
animation.rangeStart = this.rangeStart
animation.rangeEnd = this.rangeEnd
if (this.prefersReducedMotion) {
animation.currentTime = CSS.percent(this.defaultProgress * 100)
} else {
animation.play()
}
}
}
export default class LayeredAnimationEffect extends HTMLElement {
get effects() {
return this.layers.flatMap(layer => toKeyframeEffects(layer))
}
}
Performa scroll
NRK memiliki implementasi JavaScript yang berperforma sangat baik sebelum animasi yang didorong scroll digunakan, tetapi sekarang animasi yang didorong scroll memungkinkan mereka memiliki performa yang lebih baik tanpa harus khawatir dengan jank scroll, bahkan di perangkat dengan daya rendah.
- Durasi tugas non-SDA: 1 md.
- Durasi tugas SDA: 0,16 md.

Untuk membaca lebih lanjut perbedaan performa scroll antara penerapan JavaScript dan animasi berbasis scroll, artikel Studi kasus tentang performa animasi berbasis scroll akan menjelaskan lebih mendetail.
Pertimbangan aksesibilitas dan UX
Aksesibilitas memainkan peran penting di halaman publik NRK karena halaman tersebut harus dapat diakses oleh semua warga Norwegia dalam banyak situasi. NRK memastikan animasi scroll dapat diakses dengan beberapa cara:
- Menghormati preferensi pengguna untuk mengurangi gerakan: Menggunakan kueri media
screen and (prefers-reduced-motion: no-preference)
untuk menerapkan animasi sebagai peningkatan progresif. Hal ini juga berguna untuk menangani gaya cetak secara bersamaan. - Mempertimbangkan berbagai perangkat dan presisi input scroll yang bervariasi: Beberapa pengguna mungkin men-scroll secara bertahap (Tombol spasi atau atas/bawah, membuka penanda menggunakan pembaca layar) dan tidak melihat seluruh animasi. Pastikan informasi penting tidak terlewat.
- Berhati-hatilah dengan animasi yang menampilkan atau menyembunyikan konten: Bagi pengguna yang mengandalkan zoom Sistem Operasi (OS), mungkin sulit untuk melihat bahwa konten tersembunyi akan muncul saat mereka men-scroll. Jangan membuat pengguna menelusurinya. Jika perlu menyembunyikan atau menampilkan konten, pastikan konsistensi tempat konten muncul dan menghilang.
- Menghindari perubahan kecerahan atau kontras yang besar dalam animasi: Karena animasi yang didorong scroll bergantung pada kontrol pengguna, pergeseran luminans yang tiba-tiba dapat muncul sebagai berkedip, yang dapat memicu kejang pada beberapa pengguna.
@media (prefers-reduced-motion: no-preference) {
.article-image {
opacity: 0;
transition: opacity 1s ease-in-out;
}
.article-image.visible {
opacity: 1;
}
}
Dukungan browser
Untuk dukungan browser yang lebih luas terhadap ScrollTimeline dan ViewTimeline, NRK menggunakan polyfill open source, yang memiliki komunitas aktif yang berkontribusi padanya.
Saat ini, polyfill dimuat secara kondisional saat ScrollTimeline
tidak
tersedia dan menggunakan versi polyfill yang dihapus tanpa dukungan CSS.
if (!('ScrollTimeline' in window)) {
await import('scroll-timeline.js')
}
Deteksi dan penanganan dukungan browser di CSS:
@supports not (animation-timeline: view()) {
.article-section {
translate: 0 calc(-15vh * var(--fallback-progress));
opacity: var(--fallback-progress);
}
}
@supports (animation-timeline: view()) {
.article-section {
animation: --fade-up linear;
animation-timeline: view();
animation-range: entry 100% exit 100%;
}
}
Pada contoh sebelumnya untuk browser yang tidak didukung, NRK menggunakan variabel CSS,
--fallback-progress
, sebagai pengganti untuk mengontrol linimasa animasi untuk
properti translate
dan opacity
.
Variabel CSS --fallback-progress
kemudian diperbarui dengan pemroses peristiwa scroll
dan requestAnimationFrame
di JavaScript seperti ini:
function updateProgress() {
const end = el.offsetTop + el.offsetHeight;
const start = end - window.innerHeight;
const scrollTop = document.scrollingElement.scrollTop;
const progress = (scrollTop - start) / (end - start);
document.body.style.setProperty('--fallback-progress', clamp(progress, 0, 1));
}
if (!CSS.supports("animation-timeline: view()")) {
document.addEventListener('scroll', () => {
if (!visible || updating) {
return;
}
window.requestAnimationFrame(() => {
updateProgress();
updating = false;
});
updating = true;
});
}
Resource
- Studi kasus animasi yang didorong scroll
- Demo: Animasi yang Dipicu Scroll
- Menganimasikan elemen saat men-scroll dengan animasi Berbasis scroll
- Codelab: Memulai animasi berbasis scroll di CSS
- Ekstensi Chrome: Debugger animasi yang didorong scroll
- Polyfill Scroll-timeline
- Melaporkan bug atau fitur baru? Kami ingin mendengar pendapat Anda.
Terima kasih khusus kepada Hannah Van Opstal, Bramus, dan Andrew Kean Guan dari Google, dan Ingrid Reime dari NRK atas kontribusi berharga mereka dalam pekerjaan ini.