이번 미션에서 modal을 숨길 때 아래의 3가지 스타일 속성을 고려해볼 수 있었다.
opacity : 0
display : none
visiblity : hidden
나는 결론만 말하자면 미션 구현에선 visiblity
속성을 사용했지만 접근성 문제가 있다는 것을 알게 되었고 다른 방법 들을 찾아보게 되었다.
지금 부터 그 이유에 대해 살펴보자.
opacity의 경우 요소의 투명도를 낮추기만 하기 때문에, 이벤트 적용이 가능하다는 단점이 있다.
예시를 통해 살펴보자.
// ...
class WinningStatisticsModal extends BaseComponent {
// ...
setEvent() {
this.on({ target: this, eventName: 'click' }, () => {
alert('hi');
});
}
// ...
}
customElements.define('winning-statistics-modal', WinningStatisticsModal);
modal을 클릭했을 때 click 이벤트를 걸어 alert를 띄우는 로직을 추가해보았다.
위와 같이 모달이 없는 상태에서도 이벤트가 적용되기 때문에 선택지에서 먼저 제외하게 되었다.
레이아웃에 영향을 주지 않도록 요소의 표시를 제거합니다.(요소가 없는 것처럼 문서가 렌더링됨). 모든 하위 요소도 표시를 제거합니다. - mdn -
즉, 해당 속성을 적용한 element는 개발자 도구 상에선 요소가 존재하지만 레이아웃이 변경되는 특징이 있다.
예시를 통해 살펴보자.
<!DOCTYPE html>
<html lang="ko">
<style>
body {
height: 1000px;
display: flex;
align-items: center;
justify-content: center;
}
.container {
border: 1px solid black;
display: flex;
width: 1200px;
height: 200px;
justify-content: space-around;
align-items: center;
}
.first {
width: 300px;
height: 100px;
background-color: black;
}
.second {
width: 300px;
height: 100px;
background-color: green;
}
.third {
width: 300px;
height: 100px;
background-color: blue;
}
</style>
<body>
<div class="container">
<div class="first box visible">1</div>
<div class="second box close">2</div>
<div class="third box visible">3</div>
</div>
</body>
</html>
다음과 같은 html이 있다고 가정해보자. (close와 visible 스타일은 일단 제외)
.close {
display: none;
}
.visible {
display: block;
}
만약 display로 요소를 숨길 경우, 개발자 도구 상에는 요소가 남아있지만, 실제로 찍어보면 마치 요소가 dom에서 제거된 것 처럼 레이아웃이 제거된다.
visibility CSS 속성은 문서의 레이아웃을 변경하지 않고 요소를 보이거나 숨깁니다. - mdn -
즉, 해당 속성을 적용한 element는 개발자 도구 상에서도 남아 있으며, 레이아웃 또한 유지되는 특징이 있다.
.close {
visibility: hidden;
}
.visible {
visibility: visible;
}
visiblity 속성의 경우 레이아웃이 유지되기 때문에, 개발자 도구 상의 요소와 일치하는 것을 알 수 있다.
즉, 나는 visiblity를 통해 요소를 직관적으로 확인하는 것이 혼란을 방지할 수 있다 생각해 visiblity 속성을 사용하여 modal을 구현했다.
visiblity와 display 속성은 아래와 같은 단점이 있다는 사실을 알게 되었다.
visibility 값을 hidden으로 설정한 요소는 접근성 트리에서 제외됩니다. 즉 해당 요소와, 그 모든 자손 요소는 스크린 리더가 읽지 않습니다. - mdn -
display 값을 none으로 설정한 요소는 설정하면 접근성 트리에서 해당 요소가 제거됩니다. 즉 해당 요소와, 그 모든 자손 요소는 스크린 리더가 읽지 않습니다. - mdn -
그렇다면 접근성을 고려하기 위해선 어떤 속성을 사용해야 할까?
네이버 뉴스 페이지에서 해답을 찾아볼 수 있었다.
네이버는 blind라는 class를 통해 요소를 숨기는 것을 알 수 있었다.
.blind {
overflow: hidden;
position: absolute;
clip: rect(0, 0, 0, 0);
clip-path: polygon(0 0, 0 0, 0 0);
width: 1px;
height: 1px;
margin: -1px;
}
blind를 살펴보면 다음과 같은 속성으로 이루어져 있는 것을 알 수 있다.
각 속성을 확인해보자.
position: absolute
- 레이아웃에 영향을 주지 않도록 한다.
overflow: hidden
- 요소의 크기를 벗어나는 콘텐츠를 숨긴다.
clip-path: polygon(0 0, 0 0, 0 0)
- 요소가 화면에 보이는 영역을 0으로 지정한다.
width, height: 1px
- 넓이와 높이 값을 최소(1px)로 하여, 스크린리더가 인식할 수 있도록 한다.
margin: -1px
- 요소의 크기 만큼 역마진을 주어, 요소가 차지하는 공간을 제거한다.
이전 html에 해당 속성을 적용해보자.
.close {
overflow: hidden;
position: absolute;
clip-path: polygon(0 0, 0 0, 0 0);
width: 1px;
height: 1px;
margin: -1px;
}
마치 display : none
처럼 레이아웃은 유지되지 않지만 요소가 잘 숨겨지는 것을 알 수 있다.
Lotto 애플리케이션 또한 적용해볼 때 크게 문제가 없는 것을 알 수 있었다.
단, visiblity : hidden
처럼 레이아웃이 유지되기 위한 방법이 필요해진다면 그 때 더 고민해봐야 할 거 같다.
요소를 숨기는 방법에 대해서 재밌게 보았네요 ㅎㅎ