CSS display none과 visibility hidden 차이
display: none과 visibility: 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을 선택한다.
참고 자료









