z-index와 스태킹 컨텍스트(쌓임 맥락)
🎯 이 문서를 읽고 난 후의 상태
z-index
와스택 컨텍스트
가 무엇인지 안다.z-index
와스택 컨텍스트
를 활용하여 요소들을 어떻게 배치할 수 있는지 안다.css
에서스택 컨텍스트
가 어떤 역할을 하는 지 이해하고, 화면 구성을 보다 효과적으로 할 수 있다.
📚 계기
캔버스와 네이버 지도 API를 연동하기 위한 과정 에서, 이벤트를 깊게 다룰일이 생겼었다.
이 과정에서, z-index
와 스택 컨텍스트
를 제대로 이해하지 못해, 어려움을 겪게 되었고 이에 대해 공부하게 되었다.
🤔 쌓임 맥락(Stacking Context)란?
z-index
를 이해하기 위해서는 쌓임 맥락(Stacking Context)
를 이해해야 한다.
쌓임 맥락(Stacking Context)이란 특정 요소(Parent Element)와 그 자식 요소(Child
Element)들이 특정 규칙에 따라 겹쳐지는 방식을 정의하는 독립된 렌더링 계층을 쌓임 맥락(Stacking Context)
라고 한다.
쉽게 말하면, 사용자가 모니터를 바라보는 것을 기준으로 가상의 z축을 생성하여 HTML 요소들을 3차원 개념으로 보는 것을 말한다.
조금 더 쉽게 설명하면, 사용자 입장에서 모니터를 보았을 때 화면에 요소들을 어떻게 겹쳐서 배치할까..? 어떻게 쌓아서 겹친 모습을 연출할까? 하는 개념이 쌓임 맥락이라고 볼 수 있다.
결국 쌓임 맥락을 형성한다는 것은 요소들을 쌓는 방법을 결정한다는 것을 의미한다.
🤔 쌓임 맥락(Stacking Context)는 왜 중요할까?
쌓임 맥락(Stacking Context)
은 웹 개발, 특히 CSS에서 요소들이 화면에 어떻게 겹쳐지고 렌더링되는 지를 결정하는 중요한 개념이다.
z-index
속성을 사용하여 요소들을 겹치게 할 때, 쌓임 맥락
이 없다면, 요소들이 어떻게 겹쳐지는 지 예측하기 어렵다.
쌓임 맥락
은 요소들을 겹치는 방법을 결정하며, 이를 통해 요소들이 어떻게 겹쳐지는 지를 예측할 수 있다.
조금 더 자세하게 서술하기 위해 GPT의 힘을 빌렸다. 중요성에 대해서는 아래와 같다.
중요성 | 설명 |
---|---|
레이어 관리의 효율성 | 웹 페이지는 수많은 요소들이 서로 겹쳐져 복잡한 레이아웃을 형성한다. 이때 쌓임 맥락을 이해하면 특정 요소가 다른 요소들 위나 아래에 위치하도록 정밀하게 제어할 수 있다. 예를 들어, 모달 창이나 드롭다운 메뉴와 같은 UI 컴포넌트는 다른 모든 요소들보다 앞에 표시되어야 하는데, 쌓임 맥락을 통해 이를 손쉽게 구현할 수 있다. |
예상치 못한 레이아웃 문제 방지 | 쌓임 맥락을 올바르게 이해하지 못하면, 의도하지 않은 요소들이 서로 겹치거나 숨겨지는 문제가 발생할 수 있다. 특히 복잡한 웹 애플리케이션에서는 여러 개의 스태킹 컨텍스트가 중첩될 수 있어, 각 요소의 z-index와 포지셔닝 속성을 신중하게 관리해야 한다. 이를 통해 레이아웃의 일관성과 예측 가능성을 유지할 수 있다. |
CSS 속성의 효과적인 활용 | 쌓임 맥락은 z-index 외에도 opacity, transform, filter 등의 다양한 CSS 속성과 밀접하게 연관되어 있다. 이러한 속성들은 새로운 스태킹 컨텍스트를 생성하거나 기존의 스태킹 컨텍스트에 영향을 미친다. 이를 통해 복잡한 시각 효과를 구현할 때, 각 요소가 어떻게 렌더링될지를 세밀하게 조정할 수 있다. |
성능 최적화 | 브라우저는 쌓임 맥락 단위로 레이어를 처리하기 때문에, 이를 적절히 활용하면 렌더링 성능을 향상시킬 수 있다. 불필요한 재렌더링을 최소화하고, 복잡한 애니메이션이나 트 랜지션을 부드럽게 구현하기 위해서는 스태킹 컨텍스트의 개념을 이해하고 최적화하는 것이 중요하다. |
접근성과 사용자 경험 향상 | 쌓임 맥락을 통해 중요한 요소를 시각적으로 강조하거나, 사용자 인터페이스의 계층 구조를 명확히 할 수 있다. 이는 사용자 경험을 향상시키고, 인터페이스의 사용성을 높이는 데 기여한다. 예를 들어, 경고 메시지나 알림 배너는 다른 콘텐츠 위에 표시되어 사용자의 주의를 끌 수 있어야 하는데, 이를 효과적으로 구현하기 위해 쌓임 맥락을 활용할 수 있다. |
💡 쌓임 맥락(Stacking Context)의 형성 조건
각각의 쌓임 맥락은 독립적으로 관리되어, 서로 영향을 주지 않으며, 한 쌓임맥락 내에서는 요소들이 z-index
, opacity
, tansform
등의 css
속성에 따라 정렬된다.
쌓임 맥락이 형성되는 조건은 다음과 같다.
스태킹 컨텍스트가 형성되는 조건 | 설명 |
---|---|
루트 요소 | <html> 요소는 항상 기본 스태킹 컨텍스트를 형성한다. |
position 속성 | position 속성이 absolute , relative 이고, z-index 가 auto 가 아닌 경우 스태킹 컨텍스트를 형성한다. |
position 속성 2 | sticky 또는 fixed 가 설정된 경우, z-index 값이 auto 여도 스태킹 컨텍스트를 형성한다. |
opacity 속성 | opacity 값이 1보다 작을 때 스태킹 컨텍스트를 형성한다. |
transform 속성 | transform 속성이 적용되었을 때 스태킹 컨텍스트를 형성한다. |
filter 속성 | filter 속성이 적용되었을 때 스태킹 컨텍스트를 형성한다. |
mix-blend-mode 속성 | mix-blend-mode 속성이 normal 이 아닌 경우 스태킹 컨텍스트를 형성한다. |
clip-path 속성 | clip-path 가 적용되었을 때 스태킹 컨텍스트를 형성한다. |
perspective 속성 | perspective 속성이 설정되었을 때 스태킹 컨텍스트를 형성한다. |
isolation 속성 | isolation: isolate 가 설정되었을 때 스태킹 컨텍스트를 형성한다. |
전부 기억하기 보다는 중요한 몇가지를 기억하자.
position
속성이absolute
,relative
이고,z-index
가auto
가 아닌 경우 스태킹 컨텍스트를 형성한다.sticky
또는fixed
가 설정된 경우,z-index
값이auto
여도 스태킹 컨텍스트를 형성한다.opacity
값이 1보다 작을 때 스태킹 컨텍스트를 형성한다.transform
,filter
속성이 적용되었을 때 스태킹 컨텍스트를 형성한다.
💡 쌓임 맥락(Stacking Context)의 특징
쌓임 맥락은 다음와 2가지 중요한 특징을 갖는다.
쌓임 맥락
은 독립적인 렌더링 계층을 형성한다.(형제 요소와 완전히 독립적이다.)쌓임 맥락
은 다른 쌓임 맥락을 포함할 수 있다.쌓임 맥락
에서 쌓임을 고려하는 것은 오직 자식 요소에 대해서 만이다.
이에 대해서 좀 더 자세히 알기 위해서 다음의 예제를 참고하자
🚀 스태킹 컨텍스트 예제 🚀
예제는 MDN-Stacking Context에서 가져왔다.
<div id="div1">
<h1>Division Element #1</h1>
<code>
position: relative;<br />
z-index: 5;
</code>
</div>
<div id="div2">
<h1>Division Element #2</h1>
<code>
position: relative;<br />
z-index: 2;
</code>
</div>
<div id="div3">
<div id="div4">
<h1>Division Element #4</h1>
<code>
position: relative;<br />
z-index: 6;
</code>
</div>
<h1>Division Element #3</h1>
<code>
position: absolute;<br />
z-index: 4;
</code>
<div id="div5">
<h1>Division Element #5</h1>
<code>
position: relative;<br />
z-index: 1;
</code>
</div>
<div id="div6">
<h1>Division Element #6</h1>
<code>
position: absolute;<br />
z-index: 3;
</code>
</div>
</div>
* {
margin: 0;
}
html {
padding: 20px;
font:
12px/20px Arial,
sans-serif;
}
div {
opacity: 0.7;
position: relative;
}
h1 {
font: inherit;
font-weight: bold;
}
#div1,
#div2 {
border: 1px dashed #696;
padding: 10px;
background-color: #cfc;
}
#div1 {
z-index: 5;
margin-bottom: 190px;
}
#div2 {
z-index: 2;
}
#div3 {
z-index: 4;
opacity: 1;
position: absolute;
top: 40px;
left: 180px;
width: 330px;
border: 1px dashed #900;
background-color: #fdd;
padding: 40px 20px 20px;
}
#div4,
#div5 {
border: 1px dashed #996;
background-color: #ffc;
}
#div4 {
z-index: 6;
margin-bottom: 15px;
padding: 25px 10px 5px;
}
#div5 {
z-index: 1;
margin-top: 15px;
padding: 5px 10px;
}
#div6 {
z-index: 3;
position: absolute;
top: 20px;
left: 180px;
width: 150px;
height: 125px;
border: 1px dashed #009;
padding-top: 125px;
background-color: #ddf;
text-align: center;
}
한번 위의 예제를 보고 어떻게 동작할지 손으로 직접 그려보자.
그리고나서 아래의 결과를 살펴보자.
✅ 결과

이 예제에서는 모든 위치가 지정된 요소가 자체 스태킹 컨텍스트를 생성한다.
이는 위치 지정과 z-index 값 때문이다. 스태킹 컨텍스트의 계층 구조는 다음과 같이 구성된다:
- 루트
- DIV #1
- DIV #2
- DIV #3
- DIV #4
- DIV #5
- DIV #6
DIV #4, DIV #5 및 DIV #6은 DIV #3의 자식 요소이므로, 이러한 요소들의 스태킹은 전부 DIV #3 내에서 해결된다.
DIV #3 내에서 스태킹과 렌더링이 완료되면, 전체 DIV #3 요소는 루트 요소의 스태킹 컨텍스트 내에서 형제 요소인 DIV들과 비교되어 스태킹된다.
DIV #4는 루트 요소의 스태킹 컨텍스트 내에서 z-index가 5인 DIV #1 아래에 렌더링된다.
반면, DIV #4의 z-index는 6이지만 이는 DIV #3의 스태킹 컨텍스트 내에서 유효하다. 따라서 DIV #4는 z-index 값이 더 낮은 DIV #1 아래에 위치하게 된다.
같은 이유로, DIV #2(z-index: 2)는 DIV #3의 자식인 DIV #5(z-index: 1) 아래에 렌더링된다. 이는 DIV #5가 DIV #3의 스태킹 컨텍스트 내에 있기 때문이다.
DIV #3의 z-index는 4이지만, 이는 DIV #4, DIV #5 및 DIV #6의 z-index와는 독립적이다. 이는 이들이 다른 스태킹 컨텍스트에 속하기 때문이다.
z축을 따라 쌓인 요소들의 렌더링 순서를 파악하는 쉬운 방법은 이를 일종의 "버전 번호"로 생각하는 것이다.
여기서 자식 요소들은 부모의 주요 버전 번호 아래의 하위(sub) 버전 번호처럼 동작한다.
이를 통해 z-index가 1인 요소(DIV #5)가 z-index가 2인 요소(DIV #2) 위에 쌓이고, z-index가 6인 요소(DIV #4)가 z-index가 5인 요소(DIV #1) 아래에 쌓이는 방식을 쉽게 이해할 수 있다.
예제를 배경으로 하면 다음과 같다. (최종 렌더링 순서에 따라 정렬된다.):
- 루트
- DIV #2: (z-index: 2)
- DIV #3: (z-index: 4)
- DIV #5: (z-index: 1), 요소(z-index: 4) 아래에 쌓여 렌더링 순서가 4.1이 된다.
- DIV #6: (z-index: 3), 요소(z-index: 4) 아래에 쌓여 렌더링 순서가 4.3이 된다.
- DIV #4: (z-index: 6), 요소(z-index: 4) 아래에 쌓여 렌더링 순서가 4.6이 된다.
- DIV #1: (z-index: 5)
💡 쌓임 맥락(Stacking Context)의 우선순위
쌓임 맥락을 형성하는 요소가 아무것도 없다고 했을 경우 그림의 우선순위로 쌓이게 된다.

브라우저는 자연스러운 흐름에 따라 페이지에 요소를 배치한다.
z-index
등으로 겹치면 브라우저는 어떤 것을 먼저 표기할 지(어떤 요소가 사용자에게 더 가까운지) 결정해야 한다.
웹 페이지와 그 내부의 모든 요소는 좌표계가 존재한다. 위 사진이 바로 그 좌표계를 표시한 것인데, 왼쪽 위를 (0, 0, 0)으로 하는 3차원 좌표계를 갖는다.
이때, x축은 화면 오른쪽을 향하고, y축은 화면 아래쪽을, z 축은 뷰어를 향한다.
브라우저에서는 CSS 속성
으로 지정된 요소를 앞서 말한 3차원 좌표에 기반해서, 특정 순서에 맞추어서 요소를 배치한다.
DOM Tree
에서 먼저 오는 요소가 먼저 배치되고, 그 뒤에 오는 요소가 이전 요소 위에 배치된다.
우리가 일반적으로 알고 있는 block
요소와 inline
요소 등 모두 이러한 규칙을 따른다.
하지만 항상 이렇게 배치되는 것은 아니다.
일반적인 흐름에서 벗어나는 CSS 옵션
을 주거나, 흐름에서 완전히 제거된 요소(예를 들어 display:none
)를 사용하면, 요소들이 다른 순서로 배치될 수 있다.
CSS
에는 요소의 흐름과 위치에 영향을 미치는 대표적인 2가지 방법이 존재한다. (더 많은 요소는 💡 쌓임 맥락(Stacking Context)의 형성 조건
를 참고한다.)
position
속성을 지정 : 기본값이 아닌position
을 가진 요소를위치가 지정된 요소(positioned element)
라고 한다.float
속성을 지정 : 요소를 떠있게 하여 흐름을 변경한다.