Preferreds-reducedmotion: 때로는 적은 움직임이 더 효과적일 수 있습니다.

Preferreds-Reduced 모션 미디어 쿼리는 사용자가 운영체제에 사용하는 애니메이션 또는 모션의 양을 최소화하도록 요청했는지 감지합니다.

모든 사람이 장식용 애니메이션이나 전환을 좋아하는 것은 아니며, 일부 사용자는 시차 스크롤, 확대/축소 효과 등이 발생할 때 멀미를 경험합니다. 사용자 환경설정 미디어 쿼리 prefers-reduced-motion를 사용하면 이러한 환경설정을 표현한 사용자를 위해 사이트의 모션 감소 버전을 디자인할 수 있습니다.

브라우저 지원

  • 74
  • 79
  • 63
  • 10.1

소스

실제 및 웹에서 움직임이 너무 많음

얼마 전 아이들과 아이스 스케이팅을 했습니다. 날씨가 좋았고, 햇살이 반짝이고, 아이스링크는 늘 사람들로 가득했습니다 ⛸, 문제가 있었어요. 사람이 너무 많아도 견딜 수가 없었어요. 움직이는 대상이 너무 많아서 무엇에 집중하지 못하고 결국 길을 잃고 완전히 시각적 과부하가 느껴집니다. 마치 개미핥기 멍청이를 쳐다보는 것 같아요 🐜.

아이스 스케이팅을 하는 사람들 무리
실제 생활에서의 시각적 과부하

때로는 웹에서도 이와 같은 일이 발생할 수 있습니다. 플래시 광고, 화려한 시차 효과, 깜짝 공개 애니메이션, 동영상 자동재생 등을 사용하면 웹이 굉장히 부담스러울 수 있습니다... 다행히 현실과는 달리 이를 해결할 수 있는 방법이 있습니다. 개발자는 CSS 미디어 쿼리 prefers-reduced-motion를 사용하여 모션 줄이기를 선호하는 사용자를 위한 대안 페이지를 만들 수 있습니다. 여기에는 동영상 자동재생을 사용하지 않는 것부터 순전히 장식용 특정 효과를 사용 중지하는 것, 특정 사용자를 위해 페이지를 완전히 재설계하는 것까지 무엇이든 구성될 수 있습니다.

기능을 자세히 알아보기 전에 한 걸음 물러서서 웹에서 어떤 애니메이션이 사용되는지 생각해 보겠습니다. 원한다면 배경 정보를 건너뛰고 아래의 기술 세부정보로 바로 이동할 수도 있습니다.

웹의 애니메이션

애니메이션은 사용자에게 의견을 제공하는 데 자주 사용됩니다. 예를 들어 작업이 수신되어 처리 중임을 사용자에게 알립니다. 예를 들어 쇼핑 웹사이트에서 제품을 애니메이션으로 보여 가상 장바구니로 '날아가는' 애니메이션으로 사이트의 오른쪽 상단에 아이콘으로 표시할 수 있습니다.

또 다른 사용 사례로는 모션을 사용하여 스켈레톤 화면, 컨텍스트 메타데이터, 저화질 이미지 미리보기를 함께 사용하여 사용자 인식을 해킹하는 것입니다. 이를 통해 사용자의 많은 시간을 차지하고 전체 환경이 더 빨라진 느낌으로 느껴집니다. 이 개념은 사용자에게 향후 상황에 관한 컨텍스트를 제공하고 그 동안 가능한 한 빨리 항목을 로드하는 것입니다.

마지막으로 애니메이션 그라데이션, 시차 스크롤, 배경 동영상 등과 같은 장식 효과가 있습니다. 많은 사용자가 이러한 애니메이션을 좋아하지만 일부 사용자는 애니메이션으로 인해 주의가 산만하거나 느려진다고 느끼기 때문에 애니메이션을 싫어합니다. 최악의 경우 사용자가 실제 경험인 것처럼 멀미를 겪을 수도 있으므로 이러한 사용자의 경우 애니메이션을 줄이는 것이 의료적 필요입니다.

움직임으로 인한 전정관 스펙트럼 장애

일부 사용자는 애니메이션 콘텐츠에서 주의 분산 행동이나 메스꺼움을 경험합니다. 예를 들어 스크롤 애니메이션은 스크롤과 관련된 기본 요소 이외의 요소가 많이 움직이는 경우 전관 장애를 유발할 수 있습니다. 예를 들어 시차 스크롤 애니메이션은 백그라운드 요소가 포그라운드 요소와 다른 속도로 움직이기 때문에 전관 장애를 일으킬 수 있습니다. 전정관 (내이) 장애 반응에는 현기증, 메스꺼움, 편두통이 있으며 회복을 위해 침대에서 휴식을 취해야 하는 경우도 있습니다.

운영체제에서 모션 삭제

많은 운영체제에는 오랜 시간 동안 축소된 움직임에 대한 환경설정을 지정하는 접근성 설정이 있었습니다. 아래 스크린샷은 macOS Mojave의 모션 줄이기 환경설정과 Android Pie의 애니메이션 삭제 환경설정을 보여줍니다. 선택하면 이러한 환경설정으로 인해 운영체제에서 앱 실행 애니메이션과 같은 장식 효과를 사용하지 않습니다. 애플리케이션 자체도 이 설정을 준수할 수 있고 준수해야 하며 불필요한 애니메이션을 모두 삭제해야 합니다.

'모션 줄이기' 체크박스가 선택된 macOS 설정 화면의 스크린샷
'애니메이션 삭제' 체크박스가 선택된 Android 설정 화면의 스크린샷

웹에서 모션 삭제하기

미디어 쿼리 수준 5는 움직임이 적은 사용자 환경설정을 웹에도 적용합니다. 미디어 쿼리를 사용하면 작성자가 렌더링되는 문서와 관계없이 사용자 에이전트 또는 디스플레이 기기의 값이나 기능을 테스트하고 쿼리할 수 있습니다. 미디어 쿼리 prefers-reduced-motion는 사용자가 사용하는 애니메이션 또는 모션의 양을 최소화하기 위해 운영체제 환경설정을 설정했는지를 감지하는 데 사용됩니다. 다음 두 가지 값을 사용할 수 있습니다.

  • no-preference: 사용자가 기본 운영체제에서 환경설정을 지정하지 않았음을 나타냅니다. 이 키워드 값은 불리언 컨텍스트에서 false로 평가됩니다.
  • reduce: 사용자가 운영체제 환경설정을 지정했음을 나타냅니다. 즉, 인터페이스가 이동이나 애니메이션을 최소화해야 함을 나타냅니다(필요하지 않은 움직임이 모두 제거되는 지점까지 권장됨).

CSS 및 JavaScript 컨텍스트에서 미디어 쿼리 작업하기

모든 미디어 쿼리와 마찬가지로 prefers-reduced-motion는 CSS 컨텍스트 및 JavaScript 컨텍스트에서 확인할 수 있습니다.

두 가지를 모두 설명하기 위해 사용자가 클릭하기를 바라는 중요한 가입 버튼이 있다고 가정해 보겠습니다. 시선을 사로잡는 '진동' 애니메이션을 정의할 수도 있지만, 훌륭한 웹 시민으로서 애니메이션에 명시적으로 괜찮은 사용자에게만 재생하겠습니다. 애니메이션을 선택 해제한 사용자나 미디어 쿼리를 이해하지 못하는 브라우저를 사용하는 사용자일 수 있습니다.

/*
  If the user has expressed their preference for
  reduced motion, then don't use animations on buttons.
*/
@media (prefers-reduced-motion: reduce) {
  button {
    animation: none;
  }
}

/*
  If the browser understands the media query and the user
  explicitly hasn't set a preference, then use animations on buttons.
*/
@media (prefers-reduced-motion: no-preference) {
  button {
    /* `vibrate` keyframes are defined elsewhere */
    animation: vibrate 0.3s linear infinite both;
  }
}

JavaScript로 prefers-reduced-motion를 사용하는 방법을 설명하기 위해 Web Animations API로 복잡한 애니메이션을 정의했다고 가정해 보겠습니다. 사용자 환경설정이 변경되면 브라우저에서 CSS 규칙이 동적으로 트리거되지만, JavaScript 애니메이션의 경우 변경사항을 직접 수신 대기한 다음 실행 중일 수 있는 애니메이션을 수동으로 중지하거나 사용자가 허용하는 경우 다시 시작해야 합니다.

const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
mediaQuery.addEventListener('change', () => {
  console.log(mediaQuery.media, mediaQuery.matches);
  // Stop JavaScript-based animations.
});

실제 미디어 쿼리를 괄호로 묶어야 합니다.

부적절한 예
window.matchMedia('prefers-reduced-motion: reduce');
의견을 제시하지
window.matchMedia('(prefers-reduced-motion: reduce)');

<picture> 컨텍스트에서 미디어 쿼리 작업

흥미로운 사용 사례는 media 속성에 종속된 애니메이션 AVIF, WebP 또는 GIF를 재생하는 것입니다. (prefers-reduced-motion: no-preference)true로 평가되면 애니메이션 버전을 표시하고 그 외의 경우에는 정적 버전을 표시해도 안전합니다.

<picture>
  <!-- Animated versions. -->
  <source
    srcset="nyancat.avifs"
    type="image/avif"
    media="(prefers-reduced-motion: no-preference)"
  />
  <source
    srcset="nyancat.gif"
    type="image/gif"
    media="(prefers-reduced-motion: no-preference)"
  />
  <!-- Static versions. -->
  <img src="nyancat.png" alt="Nyan cat" width="250" height="250" />
</picture>

아래 예를 참고하세요. 기기의 모션 환경설정을 전환하여 차이를 확인해 보세요.

냥고양이

요청 시 사용자의 선호도 탐색

Sec-CH-Prefers-Reduced-Motion 클라이언트 힌트 헤더를 사용하면 사이트에서 요청 시 선택적으로 사용자의 모션 환경설정을 가져올 수 있으므로 서버가 성능상의 이유로 올바른 CSS를 인라인으로 추가할 수 있습니다.

데모

저는 Rogério Vicente의 🐈 HTTP 상태 고양이를 기반으로 한 작은 데모를 만들었습니다. 먼저 농담에 귀를 기울이세요. 재밌는 얘기일 뿐이니 잠시 기다리겠습니다. 이제 돌아왔으니 데모를 소개하겠습니다. 아래로 스크롤하면 각 HTTP 상태 항목이 오른쪽 또는 왼쪽에 번갈아 표시됩니다. 부드러운 60FPS 애니메이션이지만 위에서 설명한 대로 일부 사용자가 이를 좋아하거나 멀미가 날 수 있으므로 데모는 prefers-reduced-motion를 준수하도록 프로그래밍되었습니다. 이는 동적으로 작동하므로 사용자가 새로고침할 필요 없이 즉시 환경설정을 변경할 수 있습니다. 사용자가 모션 감소를 선호한다면 불필요한 표시 애니메이션은 사라지고 일반적인 스크롤 모션만 남습니다. 아래 스크린캐스트는 실제 데모를 보여줍니다.

prefers-reduced-motion 데모 앱 동영상

결론

최신 웹사이트에서는 사용자 선호도를 존중하는 것이 핵심이며 브라우저는 웹 개발자가 그렇게 할 수 있도록 점점 더 많은 기능을 노출하고 있습니다. 또 다른 출시된 예로 prefers-color-scheme이 있습니다. 이 예는 사용자가 밝은 색 구성표와 어두운 색 구성표를 선호하는지 감지합니다. prefers-color-scheme에 대한 모든 내용은 Hello Darkness, My Old Friend에서 확인할 수 있습니다.

현재 CSS 실무 그룹은 prefers-reduced-transparency(사용자가 투명도 감소를 선호하는지 감지), prefers-contrast (사용자가 시스템에 인접한 색상 간의 대비를 늘리거나 줄이도록 요청했는지 감지), inverted-colors (사용자가 반전 색상을 선호하는지 감지)와 같은 더 많은 사용자 환경설정 미디어 쿼리를 표준화하고 있습니다.

(보너스) 모든 웹사이트에서 움직임 감소 강제 적용

모든 사이트에서 prefers-reduced-motion를 사용하는 것은 아니며, 취향에 비해 크게 다르지 않을 수도 있습니다. 어떤 이유로든 모든 웹사이트에서 모션을 중지하고 싶은 경우 그렇게 할 수 있습니다. 이를 위한 한 가지 방법은 방문하는 모든 웹페이지에 다음 CSS가 포함된 스타일시트를 삽입하는 것입니다. 이를 허용하는 여러 브라우저 확장 프로그램이 있습니다 (사용자 책임 하에 사용).

@media (prefers-reduced-motion: reduce) {
  *,
  ::before,
  ::after {
    animation-delay: -1ms !important;
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    background-attachment: initial !important;
    scroll-behavior: auto !important;
    transition-duration: 1ms !important;
    transition-delay: 1ms !important;
  }
}

작동 방식은 위의 CSS가 모든 애니메이션 및 전환의 지속 시간을 더 이상 눈에 띄지 않는 짧은 시간으로 재정의하는 것입니다. 일부 웹사이트에서는 올바르게 작동하기 위해 애니메이션을 실행해야 하므로 (아마도 특정 단계가 animationend 이벤트 실행에 종속되기 때문) 급진적인 animation: none !important; 접근 방식은 작동하지 않습니다. 위의 해킹이 모든 웹사이트에서 반드시 성공하는 것은 아니므로 (예: Web Animations API를 통해 시작된 모션을 중지할 수 없음) 손상이 발견되면 비활성화하세요.

감사의 말씀

Chrome에서 prefers-reduced-motion를 구현한 스티븐 맥그루어롭 도슨과 함께 이 문서를 검토한 분께 깊은 감사를 전합니다. 히어로 이미지: 한나 카우헤프(Unsplash)