현록

CSS display none과 visibility hidden 차이

display: nonevisibility: hidden은 모두 요소를 화면에서 숨긴다.
가장 큰 차이는 숨긴 요소가 레이아웃 공간을 계속 사용하는지에 있다.
display: none은 요소의 box를 없애고 visibility: hidden은 box는 유지한 채 그리기만 중단한다.
숨김 상태에서 필요한 레이아웃을 먼저 정하면 두 속성 중 하나를 선택하기 쉬워진다.

두 숨김 방식의 핵심 차이

display: none을 적용하면 문서는 해당 요소가 없는 것처럼 레이아웃을 계산한다.
요소와 모든 하위 요소의 렌더링도 함께 중단된다.

visibility: hidden을 적용하면 요소는 그려지지 않지만 기존 너비와 높이를 유지한다.
인접한 요소는 숨겨진 요소의 자리로 이동하지 않는다.

.removed {
  display: none;
}

.reserved {
  visibility: hidden;
}

두 속성 모두 DOM에서 요소를 삭제하는 것은 아니다.
JavaScript는 숨긴 요소를 계속 조회할 수 있고 상태를 바꾸어서 다시 표시할 수 있다.

레이아웃 공간의 차이

Flexbox나 Grid의 항목에 display: none을 적용하면 해당 항목이 레이아웃 계산에서 빠진다.
나머지 항목은 남은 공간을 기준으로 다시 배치된다.

visibility: hidden은 항목의 자리를 남겨 두므로 전체 배치를 유지한다.
항목이 잠시 사라져도 주변 UI가 움직이지 않아야 할 때 이 특성이 유용하다.

요소의 block과 inline 배치 방식은 CSS display block inline inline-block 차이에서 함께 확인할 수 있다.

포커스와 접근성

display: none인 요소는 접근성 트리에서 제거되며 스크린 리더가 해당 요소와 하위 콘텐츠를 읽지 않는다.
visibility: hidden인 요소도 접근성 트리에서 제거되며 키보드 탐색으로 포커스를 받을 수 없다.

두 방식은 콘텐츠를 화면에서만 숨기고 보조 기술에는 제공하는 방식이 아니다.
스크린 리더에는 남기고 화면에서만 숨겨야 한다면 접근성용 visually hidden 패턴을 별도로 사용해야 한다.

요소를 숨길 때 현재 포커스가 내부에 있다면 적절한 곳으로 포커스를 이동시키는 상태 관리도 필요하다.

자식 요소의 표시 방식

display: none인 부모 안의 자식은 자신의 display를 다른 값으로 바꾸어도 화면에 나타나지 않는다.
부모가 생성하는 box 전체가 꺼져 있기 때문이다.

visibility는 상속되는 속성이므로 자식이 기본적으로 부모의 hidden을 따른다.
하지만 특정 자식에 visibility: visible을 명시하면 그 자식은 다시 그려질 수 있다.

.parent {
  visibility: hidden;
}

.parent .always-visible {
  visibility: visible;
}

컨테이너 전체를 확실히 숨기려는 의도라면 이 재정의 가능성까지 고려해야 한다.

opacity 0과의 차이

opacity: 0은 요소를 완전히 투명하게 만들 뿐 box와 상호작용을 자동으로 제거하지 않는다.
눈에 보이지 않아도 레이아웃 공간을 차지하고 포인터 이벤트와 키보드 포커스의 대상이 될 수 있다.

.transparent-only {
  opacity: 0;
}

따라서 opacity: 0만으로 버튼이나 링크를 숨기면 눈에 보이지 않는 상호작용 영역이 남을 수 있다.
pointer-events: none은 포인터 이벤트를 막지만 Tab 키를 통한 포커스까지 제거하지는 않는다.
실제 숨김 상태라면 display 또는 visibility, 비활성화 상태, 포커스 관리를 함께 설계해야 한다.

선택 기준

조건부로 패널이나 목록 항목을 숨길 때 자리까지 없애려면 display: none을 사용한다.
요소가 잠시 안 보여도 전체 레이아웃이 움직이지 않아야 하면 visibility: hidden을 사용한다.

점진적인 fade 효과가 필요하면 opacity를 전환하되 애니메이션이 끝난 숨김 상태의 배치와 상호작용은 따로 제어한다.
두 숨김 속성 모두 접근성 트리에서 콘텐츠를 제거하므로 콘텐츠를 누구에게 보여야 하는지도 선택 기준에 포함한다.

핵심은 레이아웃 공간이다.
공간까지 제거하면 display: none, 공간을 남기면 visibility: hidden을 선택한다.

참고 자료

관련 포스트
CSS 가상 클래스와 가상 요소 차이 thumbnail
CSS 가상 클래스와 가상 요소 차이
CSS 가상 클래스와 가상 요소의 선택 대상, 콜론 문법, 상태와 생성 콘텐츠 예제, 접근성 주의점을 정리합니다.
CSS px em rem 차이 thumbnail
CSS px em rem 차이
CSS px, em, rem의 기준값과 중첩 계산 방식, 글꼴 크기와 컴포넌트 간격에 단위를 선택하는 기준을 정리합니다.
CSS position sticky와 fixed 차이 thumbnail
CSS position sticky와 fixed 차이
CSS position sticky와 fixed의 차이를 스크롤 기준, 문서 흐름, 부모 영역, top과 overflow, 고정 헤더 구현 기준으로 정리합니다.
CSS box-sizing content-box와 border-box 차이 thumbnail
CSS box-sizing content-box와 border-box 차이
CSS box-sizing의 content-box와 border-box 차이를 width 계산식, padding과 border, width 100% overflow, 전역 설정 방법으로 정리합니다.
CSS flex justify-content와 align-items 차이 thumbnail
CSS flex justify-content와 align-items 차이
CSS flex의 justify-content와 align-items 차이를 주축과 교차축, flex-direction, 가운데 정렬, 적용되지 않는 원인을 중심으로 정리합니다.
CSS margin과 padding 차이 thumbnail
CSS margin과 padding 차이
CSS margin과 padding의 차이를 박스 모델, 배경색과 클릭 영역, 전체 크기, margin collapsing, 축약형 작성 순서로 정리합니다.
CSS display block inline inline-block 차이 thumbnail
CSS display block inline inline-block 차이
CSS display의 block, inline, inline-block 차이를 줄바꿈, width와 height, margin 동작, 버튼과 태그 UI 선택 기준으로 정리합니다.
CSS position relative와 absolute 차이 thumbnail
CSS position relative와 absolute 차이
CSS position의 기본값, relative와 absolute의 배치 기준, normal flow 유지 여부, containing block, 부모에 position relative를 주는 이유를 초보자 기준으로 정리합니다.
CSS Flexbox와 Grid 차이 thumbnail
CSS Flexbox와 Grid 차이
CSS Flexbox와 Grid의 차이를 1차원과 2차원이라는 기준으로 정리합니다. 줄 바꿈된 Flexbox가 여전히 1차원인 이유와 목록, 카드, 혼합 레이아웃의 선택 기준도 함께 살펴봅니다.
CSS로 글래스모피즘 구현하기 thumbnail
CSS로 글래스모피즘 구현하기
안녕하세요. 오늘은 CSS로 글래스모피즘 디자인을 구현하는 법을 알아보겠습니다. 개인적으로 애플의 디자인 스타일을 좋아해서 좋은 레퍼런스 소재로 구경을 하는데, 오늘 문득 궁금해진 것이 CSS로 어떻게 글래스모피즘을 구현했느냐였습니다.