prefers-reduced-motion은 사용자가 운영체제에서 화면 움직임을 줄여 달라고 설정했는지 알려 주는 CSS 미디어 기능(media feature)이다. 값은 no-preference와 reduce 두 가지다. 확대·축소, 패럴랙스, 큰 요소가 화면을 가로지르는 움직임은 전정기관 장애가 있는 사람에게 어지럼증과 메스꺼움을 일으킬 수 있어서 있는 설정이다. 2020년부터 주요 브라우저가 모두 지원한다.
어디서 켜나 (2026 기준)
- macOS: 시스템 설정 → 손쉬운 사용 → 동작(Tahoe부터. 그 전에는 디스플레이) → 동작 줄이기
- iOS: 설정 → 손쉬운 사용 → 동작
- Windows 11: 설정 → 접근성 → 시각 효과 → 애니메이션 효과
- Android: 설정 → 접근성 → 애니메이션 삭제
쓰는 법
.card {
transition: transform 300ms ease;
}
@media (prefers-reduced-motion: reduce) {
.card {
transition: opacity 200ms ease; /* 움직임 대신 서서히 나타나기 */
}
}JS(JavaScript)로 띄우는 애니메이션은 matchMedia로 확인한다. 라이브러리를 동적으로 불러오는 연출이라면, 설정이 켜져 있을 때 import 자체를 건너뛰어 불필요한 다운로드도 막을 수 있다.
const reduce = window.matchMedia('(prefers-reduced-motion: reduce)')
if (!reduce.matches) {
const { default: confetti } = await import('canvas-confetti')
confetti()
}
reduce.addEventListener('change', (e) => { /* 실행 중에 설정이 바뀔 때 */ })없애기보다 줄이기
"reduce"는 "전부 끄라"가 아니다. 위치·크기가 바뀌는 움직임을 페이드나 색 변화로 바꾸거나, 길이를 줄이거나, 자동 재생을 멈추는 쪽이 낫다. 상태 변화를 알려 주던 전환을 통째로 지우면 무슨 일이 일어났는지 알 수 없게 될 수 있다. 반대로 순수한 장식(폭죽, 배경 파티클)은 꺼도 잃는 정보가 없다.
WCAG 기준
- 2.3.3 Animation from Interactions (AAA): 상호작용이 일으키는 움직임 애니메이션은 꺼질 수 있어야 한다. 단, 기능이나 정보 전달에 꼭 필요한 애니메이션은 예외다. 색·투명도·흐림만 바뀌는 건 크기·모양·위치가 달라 보이지 않는 한 "움직임"에 들지 않는다.
prefers-reduced-motion을 쓰는 것이 이 기준을 맞추는 대표 기법(C39, SCR40)이다 - 2.2.2 Pause, Stop, Hide (A): 자동으로 시작해 5초 넘게 움직이는 콘텐츠는 멈추거나 숨길 수 있어야 한다. 사용자의 조작이 아니라 페이지가 스스로 시작하는 움직임에 관한 기준이다
테스트
- Chrome DevTools: Rendering 패널 → Emulate CSS media feature prefers-reduced-motion →
reduce(크롬 개발자 도구 팁) - Playwright:
await page.emulateMedia({ reducedMotion: 'reduce' })를 걸고, 애니메이션 요소가 생기지 않는지와 관련 청크 요청이 없는지를 확인하는 회귀 테스트를 만들 수 있다
움직임 자체를 가볍게 만드는 법은 합성 단계와 transform·opacity과 requestAnimationFrame을 본다.
출처: MDN — prefers-reduced-motion · W3C — Understanding SC 2.3.3 Animation from Interactions · Chrome DevTools — Emulate CSS media features · Playwright — page.emulateMedia