녕후킴

접근성을 곁들인 요소 숨기기

0 views

요소를 숨기는데 다섯 가지 방법이 존재한다.

  1. (react) conditional rendering
  2. display: none
  3. visibility: hidden
  4. opacity: 0
  5. hidden attribute

display: none은 요소가 DOM 트리에 포함되지 않는다. 고로 layout도 차지하지 않는다. 리플로우, 리페인트가 발생할 수 있다. hidden attribute는 요소가 DOM 트리에 포함된다. 하지만 layout은 차지하지 않는다. 당연히 interact가 불가하다. 리플로우, 리페인트가 발생할 수 있다. visibility: hidden은 요소가 DOM 트리에 포함된다. layout도 차지하고 있다. 그리고 interact가 불가하다. 리페인트만 발생한다. opacity: 0은 요소가 DOM 트리에 포함된다. layout도 차지하고 있다. 그리고 interact가 가능하다. 리페인트만 발생한다. conditional rendering과 'display: none`의 차이는 이 문서를 참고하자.

display: nonehidden은 거의 동일하다. 단, 사용해야 하는 때는 다음과 같이 구분할 수 있다. hidden은 숨기려는 요소가 현재 페이지 컨텐츠의 일부가 아닐 때 사용(semantic한 관점)하고, display: none은 숨기려는 요소가 현재 페이지 컨텐츠의 일부일 때 사용한다.

예를들면 폼을 작성하는 와중에 유저가 잘못 기입했을 때 보여져야하는 에러 메세지나 혹은 폼을 작성하고나서 보여져야하는 성공 메세지는 hidden이 적합하다. 에러 메세지든 성공 메세지든 실제 조건이 충족되지 않는다면 보여지지 않기 때문에 페이지 컨텐츠의 일부로 보기 어렵기 때문이다.

반면에 뷰포트 등의 제약으로 특정 문단을 숨겨놨다가 토글 버튼을 눌렀을 때 보여주거나, 혹은 유저가 어떤 요소를 Hover 했을 때 보여줘야 하는 경우에는 display: none이 적합하다.

주의할 점은, hiddendisplaycss를 override하지 못한다는 것이다. display: block이 존재하는 경우 hidden을 적용해도 요소가 사라지지 않는다.

display: none은 기본적으로 스크린 리더가 읽어주지 않지만 간혹가다 읽어주는 경우도 존재한다고 한다.

opacity: 0의 경우 읽어주는 경우도 존재하고 읽어주지 않는 경우도 존재하고, visibility: hidden은 스크린 리더가 읽어주지 않는 듯 하다.

이렇게 스크린 리더에 따라서 케이스 바이 케이스가 존재한다면, aria-hidden은 항상 같이 따라다니는 편이 좋을 것 같다. 예를들면 tab panel을 설계한다면 display: none을하고 여기에 aria-hidden=true를 이용하여 엣지 케이스에도 스크린 리더가 제대로 동작하도록.

참고 문헌

Will the CSS property "opacity" only hide content from screen readers if exactly 0?

What is the difference between the hidden attribute (HTML5) and the display:none rule (CSS)?

hidden-attribute-ignored

Using the hidden attribute vs conditionally rendering a component

CSS display:none and visibility:hidden – What's the Difference?