퍼블리셔, 프론트엔드 개발자라면 의미가 있는 이미지를 사용할 때 이미지의 대체 텍스트를 반드시 작성해주어야 한다는 말을 들어보았을 것이다. 웹 접근성의 측면에서 개발자는 이미지를 볼 수 없는 환경이나 저시력 사용자, 시각 장애인에게 이미지로 표현된 내용을 알려줄 의무가 있기 때문이다.
그렇다면, 내가 image 태그를 사용하지 않고 background에 이미지를 삽입해야 하는 상황이라면 어떻게 그 대체 텍스트를 작성할 수 있을까? 또는 image 태그의 alt 속성에 작성해야 할 텍스트가 너무 길어지는 상황이라면 의미 전달에 어려움이 있을 텐데 시맨틱하게 의미를 전달 할 방법은 없을까?
오늘은 이런 의문이 들 때 사용할 수 있는 방법 중 하나인 IR 기법에 대해 알아보자.
Image Replacement의 약자로, 이미지를 볼 수 없는 사용자에게 특정 이미지에 대해 추가적인 설명을 제공해야 할 때 등의 상황을 고려하여 사용자에게 대체된 텍스트를 제공하는 기법이다.
WCAG 2.1에서는 인지의 용이성 원칙의 성공기준을 충족시키기 위한 기술로 지정하였다.
text-indent는 문자의 들여쓰기를 적용하는 속성으로, inline이 아닌 다른 display 값을 가진 요소에 적용할 수 있다.
text-indent로 IR 기법을 적용하는 것은 간단하다. 글자가 개행되지 않도록 white-space를 nowrap으로 해주고 자신이 가진 width를 넘어서도록 값을 설정한 뒤 overflow: hidden으로 넘친 글자를 가려주면 된다.
예제를 통해 적용방법을 알아보자.
먼저 "오늘의 발견"을 display:block인 h1 태그로 마크업하고 영역을 확인하기 위해 background-color를 입혀주었다. 그리고 text-indent 속성을 확인하기 위해 들여쓰기 위치가 h2 영역에 걸치도록 text-indent 값을 넣어주었다.
개행되지 않게 하기 위해 모든 텍스트를 한 줄로 정렬하는 white-space: nowrap을 추가하였다.
h2 요소의 영역 밖으로 터져나간 것을 볼 수 있다. 이제 여기에 overflow: hidden으로 영역 밖으로 넘어간 것을 숨긴다.
이번에는 텍스트를 모두 숨길 수 있게 h2 요소의 width를 넘도록 text-indent를 지정해보자.
- 완성! 이렇게 되면 텍스트가 화면에서는 보이지 않지만 보조 기기나 사용자 에이전트에 "오늘의 발견"이라는 내용은 전달될 수 있도록 만들어진 것이다.
이번에는 사이트에 적용된 사례를 살펴보자.
아래 사진은 쿠팡에서 IR 기법을 사용한 부분이다.
쿠팡에서는 위에서 다루었던 적용예제에서 사용한 white-space 대신 직접적으로 height 값을 명시하였다.


개인적인 취향으로는 직접적으로 height값을 작성하는 것을 좋아하지 않는다. font-size나 다른 수정 사항이 있으면 매번 height 값을 찾아 고쳐야 하니 고정된 값 없이 작성하는 것을 좋아한다. 그래도 쿠팡의 사례를 살펴보고 있느니 쿠팡이 작업한 과정을 살펴보면,

"오늘의 발견" 텍스트가 잘 숨었기 때문에 확장프로그램을 사용하여 배경 이미지를 숨겨도 텍스트가 보이지 않는 것을 확인할 수 있다.
text-indent는 포커싱의 이동을 유발한다. 때문에 text-indent를 interactive content인 요소에 사용하게 되면 보조 기기를 이용할 때 포커싱이 이동돼 사용자에게 혼란을 줄 수 있다. 때문에 text-indent를 사용할 때는 적용할 요소가 Interactive content인지 확인하고 사용하자.
WAI-ARIA는 보조 기기나 사용자 에이전트가 html 문서를 이해하기 쉽게 도와주는 보조하는 속성을 포함한 프레임워크이다. 그 중 IR 기법에 활용되는 것으로는 aria-label가 있다. (WAI-ARIA에 대해 자세히 알고싶다면 W3C나 MDN을 참고하자.)
aria-label은 HTML 요소에 이름을 붙여 사용자에게 의미를 전달할 수 있게 도와주는 속성이다.
예제로 에어비앤비 사이트를 살펴보았다.

에어비앤비 홈페이지로 이동될 수 있게 만들어진 로고는 a태그로 감싸져있고 하위의 모든 div는 로고 이미지를 렌더링 하고 있다. 즉, 어떤 HTML의 요소도 로고를 클릭하면 에어비앤비 홈페이지로 이동한다는 것을 텍스트로 알려주지 않았다.
하지만, a 태그를 자세히 보면 aria-label이라는 익숙한 속성이 있고, 그 속성값애 "에어비앤비 홈페이지"가 작성되어 있다는 것을 알 수 있다. 보조기기와 사용자 에이전트에게 에어비앤비 홈페이지로 이동한다는 것을 직접적인 텍스트로 작성한 것이 아니라 aria-label 속성을 이용하여 전달한 것이다.
aria-label은 이렇게 디자인을 위해 생략된 정보를 대신 전달할 수 있다.
position: absolute는 자신의 위치를 벗어나 부유할 수 있는 속성으로, 이를 적용하면 다른 컨텐츠의 레이아웃을 깨뜨리지 않고 숨길 수 있다.
많은 사람들이 IR 기법을 position: absolute 로 사용하려 하면, offset(top, right, bottom, left)과 관련된 속성을 가장 먼저 떠올린다. 넷플릭스를 예로 들어보면,
.screen-reader-text 라는 클래스명으로 지정된 span태그에 "Nextflix" 라고 작성된 요소가 보이고, 요소의 스타일로는 position: absolute; top: -9999px; left: -9999px;이 지정된 것을 볼 수 있다.
text-indent와 동일한 문제로, 포커싱의 이동을 유발하여 보조 기기 사용자에게 혼란을 줄 수 있으니 position: absolute와 함께 offset을 변경할 때는 적용할 요소가 Interactive content인지 확인하고 사용하자.
여러 사이트를 분석해보면 sr-only로 정의된 클래스를 많이 접할 수 있었을 텐데, 이는 부트스트랩이 visually-hidden으로 클래스명을 바꾸기 전에 사용하던 숨김스타일 클래스명이다. 과거에는 부트스트랩에서 스크린리더에게만 보여준다는 뜻으로 sr-only라는 클래스를 사용하여 숨김 스타일을 지정했으나, 다른 보조 기기들을 고려하여 시각적으로 숨기겠다는 visually-hidden으로 클래스명을 변경하여 숨김 스타일을 제공하고 있다.
/* SCSS를 이용하여 정의된 부트스트랩의 숨김 스타일 */
@mixin visually-hidden() {
position: absolute !important;
width: 1px !important;
height: 1px !important;
padding: 0 !important;
margin: -1px !important; // Fix for https://github.com/twbs/bootstrap/issues/25686
overflow: hidden !important;
clip: rect(0, 0, 0, 0) !important;
white-space: nowrap !important;
border: 0 !important;
}
음수 margin은 VoiceOver에서 읽기 순서를 변형하는 이슈가 있다. 감안하여 사용을 지양해야 한다.
IFC(Inline Formatting Context)와 BFC(Block Formatting Context)를 나눠 적용하는 방법이 있다.
formatting의 종류에 따라 나누는 이유는 position: absolute는 BFC를 생성하는데 IFC와 함께 사용되면 하나의 섹션이 아닌 분리된 콘텐츠처럼 따로 읽기 때문이다.
.hidden {
position: absolute;
z-index: -1;
width: 1px;
height: 1px;
border: 0;
overflow: hidden;
clip: rect(1px, 1px, 1px, 1px);
clip-path: inset(50%);
}
.hidden {
overflow: hidden;
display: inline-block;
position: relative;
z-index: -1;
border: 0;
width: 1px;
height: 1px;
clip: rect(1px, 1px, 1px, 1px);
clip-path: inset(50%);
}
앞서 설명한 방법들은 전부 어떠한 상황에서도 화면에 텍스트가 보이지 않게 만드는 것이었다. 이번에는 텍스트를 이미지 뒤에 숨겨서 화면에 보이지 않게 하되, 이미지가 렌더링되지 않는 환경에서는 텍스트가 띄워질 수 있도록 하는 밥법을 알아보자.
h1 태그로 설산을 작성하고, 가상 요소 선택자를 이용하여 background 이미지를 추가한다.li를 기준으로 부유하기 위해 li에 position: relative을 작성하고 h1에 position: absolute 추가한다.h1에 z-index를 -1로 지정하여 이미지 뒤로 보낸다.background-image의 url을 비워보았다.텍스트의 양이 많거나 텍스트의 영역이 더 크면 텍스트가 image 영역을 벗어나 보이게 되는 한계가 있다.
웹 접근성을 준수하기 위한 여러 가지 IR 기법을 알아보았다. 적용 가능한 방법은 많지만, 상황별로 사용할 수 있는 것이 달라 때에 따라 잘 판단하여 적용해야겠다.
IR 기법에 대해 알아보고 이해하는 데는 시간이 오래 걸리지 않았지만, 예시를 찾고 적용해보며 정리하는 것에 오래 걸렸다. 오래 걸린 만큼 더 깊이있게 이해했을 거라 생각하며 포스팅을 마친다!
중간 중간 참고 문서의 링크를 달아두었다. 참고 항목에는 참고 문서의 링크를 달지 못한 것만 모아서 작성했다.