Post

[CSS] 웹 접근성을 고려한 .blind .hidden 처리

[CSS] 웹 접근성을 고려한 .blind .hidden 처리

스크린리더와 브라우저별, 그리고 매해 업데이트 되는 내용들 때문에 여간 웹 접근성을 지키며 블라인드 처리하기가 쉽지 않다. 그래서 ‘이 방법 으로 해결될 수 있습니다~’ 라는 방법은 아직 없다고 봐야 한다.

이 글에서 잘못 쓰이고 있는 blind 처리 방법들과, 해외의 훌륭하신 분들이 다수의 리딩 테스트를 거쳐 공개한 코드들을 소개한다.

대체 텍스트(숨긴 텍스트)는 언제 사용할까?

  • 화면상에는 나타나지 않지만 구조성 숨겨진 제목을 넣어줘야 하는 경우
  • 디자인상 아이콘을 사용하면서 적절한 대체 텍스트(숨긴 텍스트)를 제공해줘야 하는 경우

잘못된 방법

1. 화면상 영역을 지니지 않게 하는 방법

1
2
3
4
5
6
7
8
.hidden {
  display: none;
}

/* 또는 */
.hidden {
  visibility: hidden;
}

우선, 기본적으로 display: nonevisivility: hidden, font-size: 0; line-height: 0; width: 0; height: 0; 과 같이 화면상 영역을 지니지 않게 하는 속성들은, 스크린 리딩 시 화면에 없는 영역으로 판단해 스킵한다.
따라서 blind 처리 시 위 요소 중 단 한 개라도 들어가서는 안된다.

이 방법은 접근성에 대해서 전혀 모르는 사람들이 사용하는 방법일 것 같다.
display: none은 정보를 보지 않겠다는 의미이기 때문에 스크린 리더기 역시 해당 내용을 읽어 주지 않는다. 다시 말해 쓴 의미가 전혀 없다는 것이다. visibility: hidden 역시 같은 의미로 스크린 리더기가 읽어주지 않는다.

2. :focus를 고려하지 않은 방법

1
2
3
.hidden {
  text-indent: -9999px;
}

한 줄 안에 들어가는 내용은 text-indent:-9999px 로 처리하기도 하는데, link나 form의 경우 :focus 될 때 보이는 화면에 위치하지 않기 때문에 정확한 위치 판단이 되지 않고, 한글과 달리 오른쪽에서 왼쪽으로 적는 언어(RTL)의 경우 문제가 된다. (예: 아랍어)
또한 보이는 화면상에 위치하지 않기 때문에, 없는 영억으로 판단하여 스킵하는 리더기도 있다.

text-indent를 -로 줘서 텍스트를 화면 밖으로 내보내는 방법은 예전에 많이 사용하던 방법이다. 아직도 많이 사용되고 있는 방법인 것 같다.
하지만 text-indent를 이용한 방법은 화면 초점 역시 화면 밖으로 나가는 문제가 생긴다.

3. position 으로 날리는 방법

position: absolute; top: -9999px로 처리하는 방법도 있으나, 위의 text-indent와 동일한 문제를 가졌다.

H5BP에서 채택한 방법

다음은, 다수의 리딩테스트를 거쳐 살아남은 코드이다.

1
2
3
4
5
6
7
8
9
10
11
12
/* H5BP */
.hidden {
  position: absolute;
  overflow: hidden;
  height: 1px;
  width: 1px;
  border: 0;
  clip: rect(1px, 1px, 1px, 1px);
  clip-path: inset(50%);
  word-break: initial;
  word-wrap: initial;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
/* 수정 */
.hidden {
  position:absolute;
  width:1px;
  height:1px;
  padding:0;
  margin:-1px;
  border:0;
  clip:rect(0 0 0 0);
  clip-path:inset(50%);
  overflow:hidden;
  white-space:nowrap;
}

위의 방법도 문제가 생기는 부분이 있다고 한다.

position: absolute로 처리 할 경우 해당 요소를 block formatting context로 변경되기 때문에 스크린 리더기로 읽을 경우 div 요소로 묶은 것처럼 끊어서 읽어준다는 것이다.
그래서 이 방법은 타이틀 같이 끊어서 읽어줘도 상관 없을 때는 괜찮지만, inline 요소로 문장 중간에 대체 텍스트(숨긴 텍스트)가 들어가야 할 경우에는 아래와 같이 수정해서 쓰는 것을 추천한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
.hidden {
  position: relative;
  z-index: -1;
  display: inline-block;
  overflow: hidden;
  height: 1px;
  width: 1px;
  border: 0;
  clip: rect(1px, 1px, 1px, 1px);
  clip-path: inset(50%);
  word-break: initial;
  word-wrap: initial;
}

또는

1
2
3
4
5
6
7
8
.blind {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: polygon(0 0,0 0,0 0)
}


참고
This post is licensed under CC BY 4.0 by the author.