Animasi membuat antarmuka terasa hidup, tetapi gerakan layar yang besar atau berulang dapat menimbulkan ketidaknyamanan — pusing hingga mual bagi pengguna dengan gangguan vestibular. Karena itu sistem operasi menyediakan pengaturan “kurangi gerakan”, dan CSS membaca preferensi tersebut lewat media query prefers-reduced-motion . Dengan satu blok @media, seluruh animasi halaman dapat menurunkan intensitasnya atau berhenti sesuai pilihan pengguna. Pada Chapter ini kita mempelajari dua nilai media query, dua pola penulisan, dan alternatif yang layak untuk tiap jenis gerakan.

Dua Nilai dan Dua Pola #

prefers-reduced-motion menyediakan dua nilai: no-preference (tidak ada permintaan khusus — nilai default) dan reduce (pengguna meminta gerakan dikurangi). Preferensi ini diwariskan dari sistem operasi ke browser, sehingga tidak ada yang perlu dikonfigurasi di halaman — CSS cukup membaca dan menanggapi. Dari sini muncul dua pola penulisan. Pola pertama membungkus animasi di dalam @media (prefers-reduced-motion: no-preference), sehingga animasi hanya menyala bagi pengguna yang tidak memintanya dikurangi. Pola kedua menuliskan animasi seperti biasa, lalu menenangkannya di dalam @media (prefers-reduced-motion: reduce):

css
/* Pola 1: bungkus — animasi hanya bagi yang tidak meminta pengurangan */
@media (prefers-reduced-motion: no-preference) {
  .kartu-halus {
    animation: mengambang 2.4s ease-in-out infinite;
  }
}

/* Pola 2: tulis lalu tenangkan pada reduce */
.animasi-denyut {
  animation: denyut 1.6s ease-in-out infinite;
  border: 1px solid rgb(148, 163, 184);
}

@media (prefers-reduced-motion: reduce) {
  .animasi-denyut {
    animation: none;
    border-color: rgb(220, 38, 38);
  }
}
  1. Baris 2–4 (pola 1): .kartu-halus hanya beranimasi bila preferensi pengguna adalah no-preference; pada reduce, animasi tidak pernah dideklarasikan.
  2. Baris 7–10 (.animasi-denyut): animasi denyut ditulis seperti biasa, lengkap dengan border abu sebagai keadaan dasar.
  3. Baris 12–16 (pola 2): pada reduce, animation: none menghentikan denyutan. Border sengaja diubah merah sebagai penanda visual — cara cepat memastikan pola sedang berjalan ketika menguji dengan pengaturan sistem.

Hasil di Browser:

text
Harness headless memakai preferensi default (no-preference), sehingga:
.animasi-denyut mencatat animation-name denyut, animation-duration 1.6s,
dan border rgb(148, 163, 184) — blok reduce belum aktif.
.kartu-halus mencatat animation-name mengambang dan animation-duration 2.4s
karena dibungkus no-preference. Tombol transisi memakai durasi 0,15 detik.

Alternatif untuk Tiap Jenis Gerakan #

Tidak semua animasi harus berhenti total pada reduce; yang perlu diatur adalah intensitasnya. Bagi gerakan dekoratif kecil, transisi singkat sering menjadi pengganti yang layak: alih-alih elemen berdenyut tanpa henti, cukup transisi 0,15 detik saat keadaannya berubah — umpan balik tetap terasa tanpa gerakan berulang. Untuk gerakan besar seperti parallax, korsel otomatis, atau scroll-driven animation, jalur yang tepat adalah menghentikannya pada reduce dan menyediakan tampilan statis yang tetap terbaca.

Sifat halaman lain pun perlu diperiksa: scroll-behavior: smooth pada html termasuk gerakan yang ditonton pengguna, sehingga pola yang sama berlaku — bungkus deklarasi itu di dalam @media (prefers-reduced-motion: no-preference) agar pengguliran halus berhenti pada reduce. Kebiasaan serupa diterapkan pada video yang berjalan sendiri tanpa suara dan korsel yang berpindah slide tanpa diminta. Tim yang memakai utility class kerap menetapkan penamaan internal seperti motion-safe dan motion-reduce; nama bebas ditentukan sendiri, tetapi isinya selalu blok media query yang sama.

css
.tombol-santai {
  background-color: rgb(37, 99, 235);
  color: rgb(255, 255, 255);
  padding: 10px 18px;
  border-radius: 8px;
  transition: background-color 0.15s ease;
}

.tombol-santai:hover {
  background-color: rgb(29, 78, 216);
}

Menguji Preferensi Sistem #

Keadaan reduce tidak dapat disetel oleh harness — browser headless berjalan dengan preferensi default — sehingga probe memeriksa gaya dasar, dan keadaan reduce diuji manual:

  1. Buka pengaturan aksesibilitas sistem: pada Windows, Settings > Accessibility > Visual effects > Animation effects; pada macOS, System Settings > Accessibility > Display > Reduce motion.
  2. Aktifkan pengurangan gerakan, lalu muat ulang demo — denyutan berhenti dan border kartu .animasi-denyut berubah merah, menandai blok reduce sedang berlaku.
  3. Matikan lagi pengaturan tersebut dan muat ulang — animasi menyala kembali dan border kembali abu.

Demo chapter ini (reduced-motion.html) membawa kartu beranimasi dari kedua pola, tombol transisi singkat, dan enam pemeriksaan data-expected pada properti animation-name, animation-duration, border-color, dan transition-duration.