Menghormati Preferensi Gerakan Pengguna
Diterbitkan: 2022-03-10prefers-reduced-motion
memiliki dukungan yang sangat baik di semua browser modern sejak beberapa tahun yang lalu. Dalam artikel ini, Michelle Barker menjelaskan mengapa tidak ada alasan untuk tidak menggunakannya hari ini untuk membuat situs Anda lebih mudah diakses.Saat bekerja dengan gerakan di web, penting untuk mempertimbangkan bahwa tidak semua orang mengalaminya dengan cara yang sama. Apa yang mungkin terasa halus dan licin bagi sebagian orang mungkin mengganggu atau mengganggu orang lain — atau lebih buruk lagi, menyebabkan perasaan sakit, atau bahkan menyebabkan kejang. Situs web dengan banyak gerakan mungkin juga memiliki dampak yang lebih tinggi pada masa pakai baterai perangkat seluler, atau menyebabkan lebih banyak data digunakan (memutar video secara otomatis, misalnya, akan membutuhkan lebih banyak data pengguna daripada gambar statis). Ini hanyalah beberapa alasan mengapa situs yang banyak bergerak mungkin tidak diinginkan untuk semua orang.
Sebagian besar sistem operasi baru memungkinkan pengguna untuk mengatur preferensi gerakan mereka dalam pengaturan tingkat sistem mereka. Kueri media prefers-reduced-motion
preferensi (bagian dari spesifikasi Kueri Media Level 5) memungkinkan kami mendeteksi preferensi gerakan tingkat sistem pengguna, dan menerapkan gaya CSS yang sesuai dengan itu.
Dua opsi untuk prefers-reduced-motion
adalah reduce
atau no-preference
. Kita dapat menggunakannya dengan cara berikut di CSS kita untuk mematikan animasi elemen jika pengguna secara eksplisit menetapkan preferensi untuk gerakan yang dikurangi :
.some-element { animation: bounce 1200ms; } @media (prefers-reduced-motion: reduce) { .some-element { animation: none; } }
Sebaliknya, kita dapat mengatur animasi hanya jika pengguna tidak memiliki preferensi gerakan. Ini memiliki keuntungan dalam mengurangi jumlah kode yang perlu kita tulis, dan berarti kecil kemungkinan kita akan lupa untuk memenuhi preferensi gerakan pengguna:
@media (prefers-reduced-motion: no-preference) { .some-element { animation: bounce 1200ms; } }
Keuntungan tambahan adalah bahwa browser lama yang tidak mendukung prefers-reduced-motion
akan mengabaikan aturan dan hanya menampilkan elemen asli kami yang bebas gerakan.
Aturan yang mana?
Tidak seperti kueri media min-width
dan max-width
, di mana konsensus yang kurang lebih ditetapkan adalah mobile-first (oleh karena itu mendukung min-width
), tidak ada satu pun cara yang "benar" untuk menulis gaya gerak rendah Anda. Saya cenderung menyukai contoh kedua (menerapkan animasi hanya jika prefers-reduced-motion: no-preference
bernilai benar), untuk alasan yang tercantum di atas. Tatiana Mac menulis artikel luar biasa ini yang mencakup beberapa pendekatan yang mungkin dipertimbangkan pengembang, juga banyak poin hebat lainnya, termasuk pertanyaan kunci untuk ditanyakan saat mendesain dengan gerakan di web.
Seperti biasa, komunikasi tim dan strategi yang konsisten adalah kunci untuk memastikan semua basis tercakup dalam hal aksesibilitas web.
Penggunaan Praktis: Menerapkan prefers-reduced-motion
Untuk Menggulir Perilaku
prefers-reduced-motion
memiliki banyak aplikasi selain menerapkan (atau tidak menerapkan) animasi atau transisi keyframe. Salah satu contohnya adalah pengguliran yang mulus. Jika kami mengatur scroll-behaviour: smooth
pada elemen html
kami, ketika pengguna mengklik tautan jangkar dalam halaman, mereka akan digulir dengan lancar ke posisi yang sesuai di halaman ( saat ini tidak didukung di Safari ):
html { scroll-behavior: smooth; }
Sayangnya, di CSS kami tidak memiliki banyak kendali atas perilaku itu sekarang. Jika kami memiliki halaman konten yang panjang, halaman akan bergulir sangat cepat, yang bisa menjadi pengalaman yang sangat tidak menyenangkan bagi seseorang dengan sensitivitas gerakan. Dengan membungkusnya dalam kueri media, kami dapat mencegah perilaku tersebut diterapkan dalam kasus di mana pengguna memiliki preferensi reduced-motion
:
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
Katering Untuk Preferensi Gerak Dalam Javascript
Terkadang kita perlu menerapkan gerakan dalam JavaScript daripada CSS. Kami juga dapat mendeteksi preferensi gerakan pengguna dengan JS, menggunakan matchMedia
. Mari kita lihat bagaimana kita dapat menerapkan perilaku gulir halus secara kondisional dalam kode JS kita:
/* Set the media query */ const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)') button.addEventListener('click', () => { /* If the media query matches, set scroll behavior variable to 'auto', otherwise set it to 'smooth' */ const behavior = prefersReducedMotion.matches ? 'auto' : 'smooth' /* When the button is clicked, the user will be scrolled to the top */ window.scrollTo({ x: 0, y: 0, behavior }) })
Prinsip yang sama dapat digunakan untuk mendeteksi apakah akan mengimplementasikan UI yang kaya gerakan dengan pustaka JS — atau bahkan apakah akan memuat pustaka itu sendiri.
Dalam cuplikan kode berikut, fungsi kembali lebih awal jika pengguna lebih suka mengurangi gerakan, menghindari impor ketergantungan besar yang tidak perlu — kinerja menang bagi pengguna. Jika mereka tidak memiliki preferensi gerakan yang disetel, maka kita dapat mengimpor perpustakaan animasi Greensock secara dinamis dan menginisialisasi animasi kita.
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)') const loadGSAPAndInitAnimations = () => { /* If user prefers reduced motion, do nothing */ if (prefersReducedMotion.matches) return /* Otherwise, import the GSAP module and initialize animations */ import('gsap').then((object) => { const gsap = object.default /* Initialize animations with GSAP here */ }) } loadGSAPAndInitAnimations()
reduced-motion
Bukan Berarti Tidak Ada Gerakan
Saat menata gaya untuk preferensi gerakan yang dikurangi, penting bagi kami untuk tetap memberikan indikator yang bermakna dan dapat diakses kepada pengguna tentang kapan suatu tindakan telah terjadi. Misalnya, saat menonaktifkan status melayang yang mengganggu atau intensif gerak untuk pengguna yang lebih suka mengurangi gerakan, kita harus berhati-hati untuk memberikan gaya alternatif yang jelas saat pengguna mengarahkan kursor ke elemen.
Demo berikut menunjukkan transisi yang rumit saat pengguna mengarahkan atau berfokus pada item galeri jika mereka tidak memiliki preferensi gerakan yang disetel. Jika mereka lebih suka gerakan yang dikurangi, transisinya lebih halus, namun masih dengan jelas menunjukkan status melayang:
Gerakan yang dikurangi tidak berarti menghapus semua transformasi dari halaman web kami juga. Misalnya, tombol yang memiliki ikon panah kecil yang menggerakkan beberapa piksel saat mengarahkan kursor tidak akan menimbulkan masalah bagi seseorang yang lebih menyukai pengalaman gerakan yang dikurangi, dan memberikan indikator perubahan status yang lebih berguna daripada warna saja.
Terkadang saya melihat pengembang menerapkan gaya gerakan yang dikurangi dengan cara berikut, yang menghilangkan semua transisi dan animasi pada semua elemen:
@media screen and (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; scroll-behavior: auto !important; } }
Ini bisa dibilang lebih baik daripada mengabaikan preferensi gerakan pengguna, tetapi tidak memungkinkan kami untuk dengan mudah menyesuaikan elemen untuk memberikan transisi yang lebih halus bila diperlukan.
Dalam cuplikan kode berikut, kami memiliki tombol yang tumbuh dalam skala di hover . Kami sedang mentransisikan warna dan skala, tetapi pengguna dengan preferensi untuk mengurangi gerakan tidak akan mendapatkan transisi sama sekali:
button { background-color: hotpink; transition: color 300ms, background-color 300ms, transform 500ms cubic-bezier(.44, .23, .47, 1.27); } button:hover, button:focus { background-color: darkviolet; color: white; transform: scale(1.2); } @media screen and (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; scroll-behavior: auto !important; } button { /* Even though we would still like to transition the colors of our button, the following rule will have no effect */ transition: color 200ms, background-color 200ms; } button:hover, button:focus { /* Preventing the button scaling on hover */ transform: scale(1); } }
Lihat demo ini untuk melihat efeknya. Ini mungkin tidak ideal, karena pergantian warna yang tiba-tiba tanpa transisi bisa terasa lebih menggelegar daripada transisi beberapa ratus milidetik. Ini adalah salah satu alasan mengapa, secara keseluruhan, saya biasanya lebih suka gaya untuk gerakan yang dikurangi berdasarkan kasus per kasus.
Jika Anda tertarik, ini adalah demo yang sama yang di-refactored untuk memungkinkan penyesuaian transisi bila perlu. Ini menggunakan properti khusus untuk durasi transisi, yang memungkinkan kita untuk mengaktifkan dan menonaktifkan transisi skala tanpa harus menulis ulang seluruh deklarasi.
Saat Menghapus Animasi Lebih Baik
Eric Bailey mengemukakan poin bahwa "tidak setiap perangkat yang dapat mengakses web juga dapat membuat animasi, atau membuat animasi dengan lancar" dalam artikelnya, "Meninjau kembali lebih suka-gerakan yang dikurangi, kueri media gerakan yang dikurangi." Untuk perangkat dengan kecepatan refresh rendah, yang dapat menyebabkan animasi tersendat, sebenarnya lebih baik menghapus animasi . Fitur media update
dapat digunakan untuk menentukan ini:
@media screen and (prefers-reduced-motion: reduce), (update: slow) { * { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; } }
Pastikan untuk membaca artikel lengkap untuk rekomendasi Eric, karena dia adalah orang kelas satu yang harus diikuti di bidang aksesibilitas.
Jumlah Semua Bagian
Sangat penting untuk mengingat desain halaman secara keseluruhan saat berfokus begitu ketat pada CSS tingkat komponen. Apa yang mungkin tampak sebagai animasi yang cukup tidak berbahaya di tingkat komponen dapat memiliki dampak yang jauh lebih besar bila diulang di seluruh halaman, dan merupakan salah satu dari banyak bagian yang bergerak.
Dalam artikel Tatiana, dia menyarankan untuk mengatur animasi (dengan prefers-reduced-motion
) dalam satu file CSS, yang dapat dimuat hanya jika (prefers-reduced-motion: no-preference)
bernilai benar. Melihat jumlah total dari semua animasi kami dapat memiliki manfaat tambahan untuk membantu kami memvisualisasikan pengalaman mengunjungi situs secara keseluruhan, dan menyesuaikan gaya gerak yang dikurangi.
Beralih Gerakan Eksplisit
Meskipun prefers-reduced-motion
berguna, itu memang memiliki kelemahan karena hanya melayani pengguna yang mengetahui fitur dalam pengaturan sistem mereka. Banyak pengguna tidak memiliki pengetahuan tentang pengaturan ini, sementara yang lain mungkin menggunakan komputer pinjaman, tanpa akses ke pengaturan tingkat sistem. Namun, yang lain mungkin senang dengan gerakan untuk sebagian besar situs, tetapi menemukan situs dengan penggunaan gerakan yang berat sulit untuk ditanggung.
Mungkin menjengkelkan karena harus menyesuaikan preferensi sistem Anda hanya untuk mengunjungi satu situs. Untuk alasan ini, dalam beberapa kasus, mungkin lebih baik untuk memberikan kontrol eksplisit pada situs itu sendiri untuk mengaktifkan dan menonaktifkan gerakan . Kita bisa mengimplementasikan ini dengan JS.
Demo berikut memiliki beberapa lingkaran melayang di sekitar latar belakang. Gaya animasi awal ditentukan oleh preferensi sistem pengguna (dengan prefers-reduced-motion
), namun, pengguna memiliki kemampuan untuk mengaktifkan atau menonaktifkan gerakan melalui tombol. Ini menambahkan kelas ke body
, yang dapat kita gunakan untuk mengatur gaya tergantung pada preferensi yang dipilih. Sebagai bonus, pilihan preferensi gerakan juga disimpan di penyimpanan lokal — sehingga "diingat" saat pengguna mengunjungi berikutnya.
Properti Khusus
Salah satu fitur dalam demo adalah bahwa sakelar menyetel properti khusus, --playState
, yang dapat kita gunakan untuk memutar atau menjeda animasi. Ini bisa sangat berguna jika Anda perlu menjeda atau memutar beberapa animasi sekaligus. Pertama-tama, kami mengatur status pemutaran ke paused
:
.circle { animation-play-state: var(--playState, paused); }
Jika pengguna telah menetapkan preferensi untuk mengurangi gerakan di pengaturan sistem mereka, kami dapat mengatur status putar ke running
:
@media (prefers-reduced-motion: no-preference) { body { --playState: running; } }
Catatan: Menyetel ini pada body
, sebagai lawan dari elemen individual, berarti properti kustom dapat diwarisi.
Saat pengguna mengklik tombol, properti kustom diperbarui pada body
, yang akan mengaktifkan setiap instance di mana properti tersebut digunakan:
// This will pause all animations that use the `--playState` custom property document.body.style.setProperty('--playState', 'paused')
Ini mungkin bukan solusi ideal dalam semua kasus, tetapi satu keuntungannya adalah animasi berhenti sejenak ketika pengguna mengklik tombol alih, daripada melompat kembali ke keadaan awalnya, yang bisa sangat mengejutkan.
Terima kasih khusus ditujukan kepada Scott O'Hara atas rekomendasinya untuk meningkatkan aksesibilitas sakelar. Dia membuat saya sadar bahwa beberapa pembaca layar tidak mengumumkan teks tombol yang diperbarui, yang berubah ketika pengguna mengklik tombol, dan menyarankan role="switch"
pada tombol sebagai gantinya, dengan aria-checked
on
atau off
saat klik.
Komponen Video
Dalam beberapa kasus, gerakan beralih di tingkat komponen mungkin merupakan pilihan yang lebih baik. Ambil halaman web dengan latar belakang video yang diputar otomatis. Kami harus memastikan bahwa video tidak diputar secara otomatis untuk pengguna dengan preferensi untuk mengurangi gerakan, tetapi kami tetap harus menyediakan cara bagi mereka untuk memutar video hanya jika mereka memilih . (Beberapa orang mungkin berpendapat bahwa kita harus menghindari pemutaran otomatis video berhenti total, tetapi kita tidak selalu memenangkan pertempuran itu!) Demikian juga, jika video disetel ke pemutaran otomatis untuk pengguna tanpa preferensi yang disebutkan, kita juga harus menyediakan cara bagi mereka untuk jeda video.
Demo ini menunjukkan bagaimana kami dapat menyetel atribut putar otomatis saat pengguna tidak memiliki preferensi gerakan yang dinyatakan, menerapkan tombol putar/jeda khusus untuk memungkinkan mereka juga beralih pemutaran, apa pun preferensinya:
(Saya kemudian menemukan posting ini oleh Scott O'Hara, merinci kasus penggunaan yang tepat ini.)
Menggunakan Elemen <picture>
Chris Coyier menulis artikel menarik yang menggabungkan beberapa teknik untuk memuat sumber media yang berbeda tergantung pada preferensi gerakan pengguna. Ini cukup keren, karena itu berarti bagi pengguna yang lebih menyukai gerakan yang dikurangi , file GIF yang jauh lebih besar bahkan tidak akan diunduh. Kelemahannya, sejauh yang saya bisa lihat, adalah setelah file diunduh, tidak ada cara bagi pengguna untuk beralih kembali ke alternatif bebas gerak.
Saya membuat versi demo yang dimodifikasi yang menambahkan opsi ini. (Aktifkan reduced-motion
di preferensi sistem Anda untuk melihatnya beraksi.) Sayangnya, ketika beralih antara opsi animasi dan bebas gerakan di Chrome, tampaknya file GIF diunduh lagi setiap kali, yang tidak terjadi di browser lain:
Namun, teknik ini tampaknya merupakan cara yang lebih terhormat untuk menampilkan GIF, yang dapat menjadi sumber frustrasi bagi pengguna.
Dukungan Browser Dan Pemikiran Terakhir
prefers-reduced-motion
memiliki dukungan yang sangat baik di semua browser modern beberapa tahun yang lalu. Seperti yang telah kita lihat, dengan mengambil pendekatan pengurangan gerakan pertama, browser yang tidak mendukung hanya akan mendapatkan mundur reduced-motion
. Tidak ada alasan untuk tidak menggunakannya hari ini untuk membuat situs Anda lebih mudah diakses.
Toggle khusus pasti memiliki tempat, dan dapat sangat meningkatkan pengalaman bagi pengguna yang tidak mengetahui pengaturan ini, atau apa fungsinya. Kelemahan bagi pengguna adalah inkonsistensi — jika setiap pengembang dipaksa untuk menemukan solusi mereka sendiri, pengguna perlu mencari sakelar gerakan di tempat yang berbeda di setiap situs web.
Rasanya seperti lapisan yang hilang di sini adalah browser . Saya ingin melihat browser menerapkan sakelar reduced-motion
, di suatu tempat yang mudah diakses oleh pengguna, sehingga orang tahu di mana menemukannya terlepas dari situs yang mereka jelajahi. Ini mungkin mendorong pengembang untuk menghabiskan lebih banyak waktu untuk memastikan aksesibilitas gerakan juga.
Sumber Daya Terkait
- Spesifikasi Media Query Level 5, World Wide Web Consortium (W3C)
-
prefers-reduced-motion
, MDN Web Docs, Mozilla - Desain Dengan Gerakan yang Dikurangi Untuk Sensitivitas Gerakan, Val Head, Smashing Magazine
- Mengambil Pendekatan No-Motion-First Untuk Animasi, Tatiana Mac
- Teknik Gambar Bergerak yang Dikurangi, Ambil 2, Chris Coyier, Trik-CSS
- Meninjau kembali prefers
prefers-reduced-motion
, The Reduced Motion Media Query, Eric Bailey, CSS-Tricks - Mengurangi Gerakan Untuk Meningkatkan Aksesibilitas, Lindsey Kopacz