요소를 안 보이게 만들고 싶을 때, visibility와 opacity 중 어떤 걸 써야 할까요?
비슷해 보이지만 동작 방식이 완전히 다릅니다. 차이를 제대로 알아봅시다!
요소를 보이거나 숨기는 속성입니다.
숨겨도 공간은 그대로 유지됩니다.
visibility: visible; /* 기본값 — 보임 */
visibility: hidden; /* 숨김 — 공간은 유지 */
<div class="box box1">보이는 박스</div>
<div class="box box2">숨겨진 박스</div>
<div class="box box3">보이는 박스</div>
.box {
width: 100px;
height: 100px;
background-color: tomato;
display: inline-block;
margin: 10px;
}
.box2 {
visibility: hidden; /* 안 보이지만 공간은 차지함 */
}
[박스1] [ ] [박스3]
↑
보이지 않지만
이 공간은 비어있음
💡 핵심 —
visibility: hidden은 투명 망토를 입은 것과 같습니다.
눈에는 안 보이지만, 자리는 그대로 차지하고 있습니다!
요소의 투명도를 조절하는 속성입니다.
0(완전 투명) ~ 1(완전 불투명) 사이의 값을 사용합니다.
opacity: 1; /* 기본값 — 완전 불투명 */
opacity: 0.5; /* 반투명 */
opacity: 0; /* 완전 투명 — 공간은 유지 */
<div class="box box1">opacity: 1</div>
<div class="box box2">opacity: 0.5</div>
<div class="box box3">opacity: 0</div>
.box {
width: 100px;
height: 100px;
background-color: steelblue;
display: inline-block;
margin: 10px;
color: white;
text-align: center;
line-height: 100px;
}
.box1 { opacity: 1; } /* 완전히 보임 */
.box2 { opacity: 0.5; } /* 반투명 */
.box3 { opacity: 0; } /* 완전 투명 — 공간 유지 */
[진한 박스] [흐린 박스] [ ]
↑
완전 투명하지만
공간은 차지함
⚠️ 주의 —
opacity는 요소 안의 텍스트, 이미지 등 자식 요소 전체에 함께 적용됩니다.
배경만 투명하게 하고 싶다면background: rgba(0, 0, 0, 0.5)를 사용하세요!
| 비교 | visibility: hidden | opacity: 0 |
|---|---|---|
| 화면에 보임 | ❌ | ❌ |
| 공간 유지 | ✅ | ✅ |
| 클릭/이벤트 반응 | ❌ 안 됨 | ✅ 됨 |
| 자식 요소 개별 제어 | ✅ 가능 | ❌ 불가 |
| transition 애니메이션 | ⚠️ 제한적 | ✅ 부드럽게 가능 |
/* visibility: hidden → 클릭 안 됨 */
.btn {
visibility: hidden;
}
/* opacity: 0 → 눈에 안 보여도 클릭됨! */
.btn {
opacity: 0;
}
⚠️
opacity: 0은 눈에 보이지 않아도 클릭이 됩니다!
사용자가 모르는 채로 버튼을 눌러버리는 상황이 생길 수 있으니 주의하세요.
/* visibility는 자식 요소에서 다시 visible로 되돌릴 수 있음 */
.parent {
visibility: hidden;
}
.child {
visibility: visible; /* ✅ 자식만 다시 보이게 가능 */
}
/* opacity는 자식 요소에서 되돌릴 수 없음 */
.parent {
opacity: 0;
}
.child {
opacity: 1; /* ❌ 부모가 0이면 자식도 무조건 0 */
}
숨기는 방법이 세 가지 있습니다. 차이를 한눈에 비교해봅니다.
| 비교 | display: none | visibility: hidden | opacity: 0 |
|---|---|---|---|
| 화면에 보임 | ❌ | ❌ | ❌ |
| 공간 유지 | ❌ 사라짐 | ✅ 유지 | ✅ 유지 |
| 클릭 이벤트 | ❌ | ❌ | ✅ |
| transition | ❌ 불가 | ⚠️ 제한적 | ✅ 부드럽게 |
| DOM 존재 | ✅ | ✅ | ✅ |
display: none → 아예 없어진 것처럼 (공간도 사라짐)
visibility: hidden → 투명 망토 (공간 유지, 클릭 안 됨)
opacity: 0 → 완전 투명 (공간 유지, 클릭 됨)
| 상황 | 추천 속성 |
|---|---|
| 요소를 완전히 제거하고 공간도 없애고 싶다 | display: none |
| 공간은 유지하면서 숨기고 싶다 | visibility: hidden |
| 부드러운 페이드 인/아웃 효과가 필요하다 | opacity + transition |
| 배경색만 투명하게 하고 싶다 | background: rgba() |
| 자식 요소는 보이고 부모만 숨기고 싶다 | visibility: hidden + 자식에 visibility: visible |
| 속성 | 값 | 공간 유지 | 클릭 이벤트 | 특징 |
|---|---|---|---|---|
visibility | hidden | ✅ | ❌ | 자식 개별 제어 가능 |
opacity | 0 | ✅ | ✅ | transition 애니메이션 가능 |
display | none | ❌ | ❌ | 공간까지 완전히 제거 |
👁️ 보임 → visibility: visible / opacity: 1
🙈 공간 유지 → visibility: hidden / opacity: 0
❌ 공간 제거 → display: none