요소를 숨기기 위한 다양한 방법들 (with Lotto 미션)

jiny·2024년 3월 3일
5

css

목록 보기
1/1
post-thumbnail

요소를 숨기는 방법

이번 미션에서 modal을 숨길 때 아래의 3가지 스타일 속성을 고려해볼 수 있었다.

  1. opacity : 0
  2. display : none
  3. visiblity : hidden

나는 결론만 말하자면 미션 구현에선 visiblity 속성을 사용했지만 접근성 문제가 있다는 것을 알게 되었고 다른 방법 들을 찾아보게 되었다.

지금 부터 그 이유에 대해 살펴보자.

opacity : 0

opacity의 경우 요소의 투명도를 낮추기만 하기 때문에, 이벤트 적용이 가능하다는 단점이 있다.

예시를 통해 살펴보자.

// ...

class WinningStatisticsModal extends BaseComponent {
  // ...

  setEvent() {
    this.on({ target: this, eventName: 'click' }, () => {
      alert('hi');
    });
  }

  // ...
}

customElements.define('winning-statistics-modal', WinningStatisticsModal);

modal을 클릭했을 때 click 이벤트를 걸어 alert를 띄우는 로직을 추가해보았다.

위와 같이 모달이 없는 상태에서도 이벤트가 적용되기 때문에 선택지에서 먼저 제외하게 되었다.

display : none

레이아웃에 영향을 주지 않도록 요소의 표시를 제거합니다.(요소가 없는 것처럼 문서가 렌더링됨). 모든 하위 요소도 표시를 제거합니다. - 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에서 제거된 것 처럼 레이아웃이 제거된다.

visiblity : hidden

visibility CSS 속성은 문서의 레이아웃을 변경하지 않고 요소를 보이거나 숨깁니다. - mdn -

즉, 해당 속성을 적용한 element는 개발자 도구 상에서도 남아 있으며, 레이아웃 또한 유지되는 특징이 있다.

.close {
  visibility: hidden;
}

.visible {
  visibility: visible;
}

visiblity 속성의 경우 레이아웃이 유지되기 때문에, 개발자 도구 상의 요소와 일치하는 것을 알 수 있다.

즉, 나는 visiblity를 통해 요소를 직관적으로 확인하는 것이 혼란을 방지할 수 있다 생각해 visiblity 속성을 사용하여 modal을 구현했다.

display와 visiblity의 문제

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 처럼 레이아웃이 유지되기 위한 방법이 필요해진다면 그 때 더 고민해봐야 할 거 같다.

레퍼런스

2개의 댓글

comment-user-thumbnail
2024년 3월 3일

요소를 숨기는 방법에 대해서 재밌게 보았네요 ㅎㅎ

1개의 답글