1. 소개
애니메이션 이미지는 ([GIF], [PNG], [WebP] 등에서 지원) 웹에서 널리 사용됩니다. 기본적으로 사용자 에이전트는 이러한 이미지를 자동 재생하며, 이는 사용자에게 당황스러울 수 있습니다. 특히 한 페이지에 여러 이미지가 있는 경우(예: 이미지 갤러리)에서는 더더욱 그러하며, WCAG 2.2 § 성공 기준 2.2.2 일시정지, 중지, 숨기기 를 위반하게 됩니다. 현재는 사이트 작성자가 이를 제어할 수 없습니다.
이로 인해 사용자가 이러한 애니메이션을 제어하고자 하는 요구가 생깁니다. 그러나 사용의 다양성 때문에, 다양한 사용 사례와 원하는 UI, 사용자 경험이 존재하므로, 이를 자동 기능 또는 선택 기능의 사용자 에이전트 설정만으로는 충분하지 않습니다.
최상의 사용자 경험을 제공하기 위해, 웹사이트는 애니메이션 이미지의 각기 다른 사용에 대해 각각 재생 경험을 제어해야 합니다.
이 명세는 작성자가 애니메이션을 제어하고, 이 제어나 관련 UI를 원하는 요소에 할당할 수 있도록 CSS 속성(image-animation) 및 의사 클래스(:animated-image) 를 제안합니다.
2. 이미지 애니메이션 제어: image-animation 속성
| 이름: | image-animation |
|---|---|
| 값: | normal | paused | stopped | running |
| 초깃값: | normal |
| 적용 대상: | 콘텐츠 이미지 및 장식 이미지가 있는 요소 |
| 상속: | yes |
| 백분율: | n/a |
| 계산값: | as specified |
| 정규 순서: | per grammar |
| 애니메이션 타입: | discrete |
이 속성은 작성자가 애니메이션 이미지가 애니메이션 상태로 표시될지, 일시정지될지 제어할 수 있게 합니다.
콘텐츠 이미지와 장식 이미지 모두 이 속성의 영향을 받습니다. 한 요소에 여러 장식 이미지 (예: 여러 배경 이미지나 테두리 이미지)가 있거나, 하나의 콘텐츠 이미지와 하나 이상의 장식 이미지가 있을 경우, 해당 요소의 이 속성 계산값이 모두에 영향을 미칩니다.
참고: 따라서 한 요소의 장식 이미지는 일시정지하고 같은 요소의 콘텐츠 이미지는 애니메이션이 실행되도록 하거나, 그 반대로 하는 것은 불가능합니다.
비애니메이션 이미지의 경우, 이 속성의 값은 아무런 영향을 주지 않습니다. 이 속성은 비디오나 프로그래밍 이미지에는 영향을 주지 않습니다.
이 속성이 루트 요소에 적용되면, 배경 장식 이미지에 대한 효과가 캔버스 배경까지 전파됩니다.
참고: 레거시 이유로,
background 속성은 루트 요소 뿐 아니라,
HTML
body
요소로부터도 전파됩니다.
하지만 image-animation 같은
최신 속성은 오직 루트 요소에만 전파됩니다.
이를
body
에 설정해도 전파되지 않으며,
그곳에 background가 설정되어 있어도 마찬가지입니다.
- normal
-
애니메이션 이미지의 애니메이션은
이미지 포맷과 호스트 언어에 따라 정상적으로 실행됩니다.
또한, 동일한 애니메이션 이미지 (동일한 절대 URL, 동일한 이미지 데이터, image-animation 계산값이 normal) 은 그룹으로서 동일한 타임라인에 동기화되어 렌더링되어야 하며, 그 타임라인은 가장 오래전에 그룹에 추가된 시점에 시작합니다.
참고: 위의 요구조건은 [HTML]의 렌더 기대치에 기반하며, HTML § 15.4.2 Images 에 정의되어 있습니다. [HTML]이 일반적으로 문서를 특정 방식으로 렌더링하는 것을 요구하지 않으므로 이 동작을 규범적으로 요구하지는 않고, 이 명세가 이를 요구합니다.
- stopped
- 애니메이션 이미지는 정적 이미지처럼 렌더링됩니다: 사용자 에이전트는 그 안의 어떤 애니메이션도 실행하면 안 됩니다. 만약 이미지에 커버 프레임이 있다면, 그걸 사용해야 하며, 아니라면 애니메이션의 초기 상태로 이미지를 표시해야 합니다.
- paused
-
사용자 에이전트는
애니메이션 이미지에 포함된
애니메이션을 실행하지 않고,
이 값이 적용되는 시점에 표시 중이던 상태로 이미지를 유지하여,
사실상 애니메이션을 일시정지시킵니다.
이 값 적용 전에 애니메이션이 재생 중이 아니었다면, 동작은 stopped와 같습니다.
- running
-
normal과 마찬가지로,
애니메이션 이미지의
애니메이션이 정상적으로 실행됩니다.
하지만, 애니메이션 타임라인은 요소 기준으로 범위가 한정됩니다: 한 요소의 콘텐츠 이미지와 장식 이미지 간에, 동일한 절대 URL, 이미지 데이터, image-animation 계산값이 running인 애니메이션 이미지끼리는 하나의 그룹으로 동일 타임라인에 동기화되어야 하며, 다른 요소와는 분리된 타임라인이어야 합니다.
계산값이 running일 때 요소에 이미지가 추가되면, 타임라인은 가장 오래전에 추가된 시점에 시작합니다.
요소가 이미지를 가진 채 생성되거나 이전에 display: none이었다가 보이게 되며, image-animation이 이미 running이었다면, 타임라인은 요소가 레이아웃에 포함될 때 시작합니다.
다른 값에서 running으로 전환된다면, 이 타임라인의 시작점은 전환 시점에 표시된 상태로부터 이어지도록 설정됩니다.
img
요소는 계속 애니메이션 상태를 유지합니다.
:root{ /* 상속에 의해 문서 전체 전파 */ image-animation: paused; } img{ image-animation : normal; }
img
요소 여러 개가 있고,
동일 이미지(동일 절대 URL, 동일 이미지 데이터)를 표시하며,
모두 image-animation: normal 스타일이 적용되어 있다고 가정합니다.
이 중 한 요소의 image-animation 속성이 일시적으로 paused로 바뀌면, 해당 요소의 이미지만 애니메이션이 멈추고, 다른 이미지는 영향을 받지 않아 계속 애니메이션됩니다.
나중에 그 image-animation 속성이 running으로 바뀌면, 이 이미지는 다시 애니메이션을 시작하지만, 타 타임라인 위치와 관계 없이, 이제 동기화에서 벗어납니다.
더 나중에는, 해당 요소의 image-animation 속성이 normal로 변경됩니다. 그 시점에는, 다시 이 이미지의 애니메이션이 다른 인스턴스들과 동기화되어 렌더링됩니다.
image-animation 속성은 래스터 이미지 형식뿐만 아니라,
벡터 이미지(예: SVG([SVG2] 참고))
에도 적용됩니다.
단, 이는 콘텐츠 이미지나 장식 이미지로 로드된 별개의 SVG
리소스일 때만 해당합니다.
HTML 문서에 인라인된
svg
요소엔 해당되지 않습니다.
(하지만
svg
요소에 설정하면 상속되어, SVG 내부에서
애니메이션
콘텐츠 이미지
(image
요소로 삽입)
에도 영향을 줍니다.)
3. 애니메이션 이미지 구분: :animated-image 의사 클래스
:animated-image 의사 클래스는 콘텐츠 이미지 요소 중 애니메이션 이미지가 로드된 요소를 나타냅니다. animated-image 의사 클래스가 일치하려면, 이미지는 단지 애니메이션이 가능한 형식이어야 하는 것뿐 아니라, 실제로 애니메이션 이미지여야 합니다.
콘텐츠 이미지를 나타내지 않는 요소에서는, animated-image 의사 클래스가 절대 일치하지 않습니다.
이 단순한 예시에서는, 애니메이션이 가능한 이미지는 처음에 일시정지되며, 흐릿하고 회색으로 보이도록 필터가 적용됩니다. 이미지에 마우스를 올리거나(hover) 포커스하면, 필터가 제거되고 이미지가 재생되도록 허용됩니다.
img : animated-image{ image-animation : paused; filter : grayscale ( 10 % ) contrast ( 50 % ) brightness ( 80 % ); } img:animated-image:hover, img:animated-image:focus{ filter : none; image-animation : running; }
function setImageFocusability( event) { var img= event. target; if ( img. matches( ":animated-image" ) { img. tabIndex= 0 ; } else { img. removeAttribute( "tabindex" ); } } document. querySelectorAll( "img" ). forEach( ( i) => { setImageFocusability({ target: i}); i. addEventListener( 'load' , setImageFocusability); i. addEventListener( 'error' , setImageFocusability); });
:animated-image가 일치하는지는 이미지의 현재 재생 상태에도, image-animation 속성 값에도 영향을 받지 않습니다. 하지만 어떤 사용자 에이전트 설정이 전역적으로 이미지 애니메이션을 비활성화한 경우, 그렇지 않았다면 애니메이션이 가능했을 이미지조차도 정적 이미지로 간주되며, 일치하지 않습니다.
4. 용어
- 정적 이미지
-
단일 프레임이 최종 시청 경험으로
표시되도록 의도된 이미지입니다.
JPEG 이미지는 정적 이미지입니다.
- 애니메이션 이미지
-
여러 프레임이 최종 시청 경험의 일부로
순차적으로 표시되도록 의도된 이미지이며,
반복(loop)될 수도 있고 아닐 수도 있습니다.
애니메이션 PNG 이미지나, 애니메이션 [GIF] 이미지는 애니메이션 이미지입니다.
점진적 렌더링(progressive rendering) 또는 다중 패스 로딩(multi-pass loading)을 지원한다고 해서 이미지가 애니메이션으로 분류되는 것은 아닙니다.
- 콘텐츠 이미지
-
호스트 언어의 요소 중
정적 이미지 또는
애니메이션 이미지를
나타내는 요소이며,
비디오나
프로그래밍 방식
이미지는 제외합니다.
[HTML]의
img요소(또는picture요소 안에 중첩된 경우 포함), [HTML]의object요소(이미지를 표현하는 경우), 또는 [SVG2]의image요소는 콘텐츠 이미지를 나타냅니다.(그리고 오직 그 경우에만) 자신의 포스터 프레임을 표현하는 경우, HTML
video요소는 콘텐츠 이미지로 간주됩니다. - 장식 이미지
-
CSS를 통해 문서 렌더링에 삽입되는 이미지로,
예:
background-image또는border-image같은 속성을 통해 삽입됩니다. - 비디오
-
호스트 언어의 요소 중 움직이는 그림을 나타내는 요소로, 보통(반드시 그런 것은 아니지만) 소리를 동반하며, 보통(반드시 그런 것은 아니지만) 재생/일시정지/탐색/볼륨 제어/전체 화면 표시 등의 상호작용 컨트롤과 함께 제공되고, (반드시 그런 것은 아니지만) 캡션이나 자막을 동반할 수 있습니다.
참고: 개념적 관점에서, 그리고 오직 파일 형식만을 기준으로 보면, 비디오와 애니메이션 이미지는 상당히 겹치며, 원칙적으로 반드시 서로 구분될 수 있는 것은 아닙니다. 여기서의 구분은 문서에서 요소 선택으로 표현되는 작성자의 의도에 기반합니다.
- 프로그래밍 방식 이미지
-
외부 리소스에서 로드되는 이미지가 아니라,
호스트 언어의 API를 통해 프로그래밍 방식으로 생성되는 이미지입니다.
[HTML]의
canvas요소는 프로그래밍 방식 이미지를 나타냅니다. - 커버 프레임
- 일부 애니메이션 이미지 형식은 이미지 제작자가 애니메이션이 실행되지 않을 때 표시할 정적 이미지를 지정할 수 있게 합니다. 이 문서에서는 이를 커버 프레임이라고 부르며, 애니메이션의 초기 상태와는 구별되게 애니메이션이 실행되지 않을 때 표시됩니다.
5. 접근성 고려사항
- 이 명세가 도입하는 기능은 작성자가, 그렇지 않으면 위반이 되었을 WCAG 2.2 § 성공 기준 2.2.2 일시정지, 중지, 숨기기 를 해결할 수 있게 합니다.
-
웹 페이지에는 이미 애니메이션 이미지가 포함될 수 있으며,
적절한
alt텍스트를 제공하는 것이 이미 기대됩니다. 애니메이션의 일시정지/재생을 수용하기 위해 변경이 필요하다고 예상되지도, 필요하지도 않습니다. “떨어지는 모루에 눌리는 만화 코요테”, “귀여운 춤추는 햄스터”, “공사 중”, 또는 “회전하는 로딩 표시기” 같은 설명은 애니메이션이 실행 중이든 아니든 똑같이 적절하고 생생합니다. - 현재 스크린 리더는 보통 애니메이션 이미지를 비애니메이션 이미지와 다르게 선택하여 알리지 않지만, 바람직하다고 판단되면 구현될 수도 있습니다. 마찬가지로, 일시정지되었거나 재생 중인 이미지를 다르게 알릴 것으로 기대되지는 않지만, 바람직하다고 판단되면 구현될 수도 있습니다.
-
§ 3 애니메이션 이미지 구분: :animated-image 의사 클래스에서 논의한 바와 같이,
이미지 애니메이션을 제어하는 UI를 만드는 작성자는
접근 가능한 UI를 만들기 위해
통상적인 주의사항을 취해야 합니다.
CSS만으로는 요소를 직접 포커스 가능하게 만들 수 없으므로,
올바른 키보드 내비게이션을 위해서는
요소 속성도 함께 설정되어야 합니다.
대안으로는,
:animated-image 의사 클래스가 일치하는 요소에
작성자가 직접 UI를 만드는 것 대신(또는 그에 더하여),
적절한 경우 사용자 에이전트가 UI 자체를 제공하도록
작성자가 지시할 수 있게 하는 방법이 있습니다.
예를 들어, image-animation 속성에 추가 controlled 값을 정의할 수 있습니다. 이 값이 지정되면, 처음에는 이미지 애니메이션이 실행되지 않으며, paused가 지정된 것과 같게 됩니다. 또한, 기반이 되는 콘텐츠 이미지가 실제로 애니메이션이라면, 사용자 에이전트가 사용자가 애니메이션을 재생하고 일시정지할 수 있는 어떤 UI를 제공하며, 요소를 포커스 가능하게 만들 수도 있습니다.
필요하다면 이는 이 명세의 이후 버전에 추가될 수 있습니다. 그러나 작성자들이 이것을 널리 사용할지는 불확실합니다. 작성자들은 자주 자신들의 사이트에 맞게 특화된 UI 컨트롤을 직접 설계하는 것을 선호하기 때문입니다. 따라서 이 명세는 작성자 수요가 확인될 때까지 이런 해결책의 복잡성을 다루는 일을 미루기로 했습니다.
6. 개인정보 보호 고려사항
image-animation 속성은
이미지가 실제로 애니메이션 가능한지 여부에 대한 어떤 정보도 누설하지 않으면서,
교차 출처(cross origin) 이미지 애니메이션을 제어할 수 있게 합니다.
계산값은 이 정보에 따라 바뀌지 않습니다.
running 값은 애니메이션 이미지와
정적 이미지에서
눈에 보이는 효과 차이가 있지만,
이러한 차이는 페이지 자체에서 관찰될 수 있는 것은 아닙니다.
하지만 :animated-image 의사 클래스는 콘텐츠 이미지가 애니메이션인지 정적인지 여부를 드러내는데, 이는 교차 출처 상황에서 페이지가 달리 알 수 없었던 정보입니다. 이를 CORS로 제한할 수도 있지만, 이 명세는 다음 이유로 그러한 제한을 두지 않기로 했습니다:
-
이미 알려진 것에서 크게 더 얻을 정보가 없습니다.
-
대상 URL에 이미지가 존재하는지 여부 자체가 사용자에 대한 중요한 정보를 드러낼 수 있지만 (예: 특정 도메인에 로그인했는지 여부), 이는 이미지의 크기만으로도 이미 알 수 있으며, 애니메이션 가능 여부는 이 위험을 의미 있게 더하지 않습니다.
-
실제로는 한 사이트가 같은 URL에서 정적 이미지와 애니메이션 이미지를 모두 제공하고, 사용자 의존적 민감 정보에 따라 어떤 것을 제공할지 선택하여 그 정보가 누설되게 설계될 가능성은 매우 낮습니다.
-
-
비디오에 대해서는 이미 유사한 정보가 공유되고 있습니다: HTML
video요소는 교차 출처 비디오에 대해서도 재생 시간을 노출합니다. 정적 이미지는 재생 시간이 0인 애니메이션 이미지의 특수한 경우라고 볼 수 있으므로, 이 정보를 노출하는 것은 유사합니다. -
<video>요소에서 이미지를 허용하자는 제안이 있습니다. 만약 구현된다면 상황은 단지 유사한 정도가 아니라, 이미지가 애니메이션인지 여부가 어차피 교차 출처에서도 이미 알 수 있게 될 것입니다.
7. 보안 고려사항
이 명세가 새로운 보안 문제를 도입하는 것으로 알려진 바는 없습니다.