Positioned layout/Stacking context

김동현·2026년 3월 21일

mdn 학습 번역 - CSS

목록 보기
134/190

안녕하세요! 프론트엔드 개발자 취업 준비에 박차를 가하고 계시군요.

이번에 가져오신 '쌓임 문맥(Stacking context)' 문서는 프론트엔드 개발자라면 실무에서 무조건, 정말 수십 번은 마주치게 될 아주 중요한 개념입니다. "어? 왜 z-index를 9999나 줬는데도 이 요소가 위로 안 올라오지?"라는 멘붕을 겪어보셨다면, 이 문서가 바로 그 해답입니다. 면접에서도 단골로 나오는 질문이니 완벽하게 내 것으로 만들어봅시다.

자, 공식 문서의 모든 내용을 빠짐없이, 제 실무 팁과 함께 구어체로 알기 쉽게 번역해 드릴게요!


쌓임 문맥 (Stacking context)

쌓임 문맥(Stacking context)은 뷰포트(화면)나 웹페이지를 바라보고 있는 사용자를 기준으로, 가상의 Z축을 따라 HTML 요소들을 3차원으로 개념화한 것입니다. 쌓임 문맥은 Z축을 따라 요소들이 서로 어떻게 포개어지는지(화면의 "깊이" 차원이라고 생각하시면 됩니다)를 결정합니다. 즉, 콘텐츠가 겹칠 때 어떤 순서로 시각적으로 렌더링될지를 결정하는 것이 바로 쌓임 문맥입니다.

특정 쌓임 문맥 안에 있는 요소들은 그 쌓임 문맥 바깥에 있는 요소들과 완전히 독립적으로 쌓입니다. 다시 말해, 하나의 쌓임 문맥 안에 있는 요소들이 다른 쌓임 문맥 안에 있는 요소들의 쌓임 순서에 간섭하지 못하도록 보장합니다. 각각의 쌓임 문맥은 형제(sibling) 쌓임 문맥들과 완전히 독립적이며, 쌓임(stacking)을 처리할 때는 오직 자신의 자손(descendant) 요소들만 고려합니다.

각각의 쌓임 문맥은 독립적으로 완결된(self-contained) 형태를 띱니다. 어떤 요소의 내부 콘텐츠들이 모두 쌓이고 나면, 그 요소 전체는 부모의 쌓임 문맥 안에서 마치 '단일 유닛(하나의 덩어리)'처럼 취급되어 쌓임 순서가 결정됩니다.

쌓임 문맥 안에서 자식 요소들은 모든 형제 요소들의 z-index 값에 따라 쌓이게 됩니다. 여기서 주의할 점은, 이 중첩된 자식 요소들의 쌓임 문맥은 오직 자신의 부모 안에서만 의미가 있다는 것입니다. 쌓임 문맥들은 부모 쌓임 문맥 안에서 원자적(atomically)으로, 즉 쪼개질 수 없는 단일 유닛으로 처리됩니다. 쌓임 문맥은 다른 쌓임 문맥 안에 포함될 수 있으며, 이것들이 모여 쌓임 문맥의 계층 구조(hierarchy)를 만듭니다.

모든 HTML 요소가 쌓임 문맥을 생성하는 것은 아니기 때문에, 쌓임 문맥의 계층 구조는 HTML 요소 계층 구조의 부분집합(subset)이라고 할 수 있습니다. 자신만의 쌓임 문맥을 생성하지 않는 요소들은 부모 쌓임 문맥에 동화(assimilated)되어 처리됩니다.

💡 강사의 실무 팁 1
여기서 가장 중요한 문장은 "자식 요소들의 z-index는 부모 안에서만 의미가 있다"입니다.
예를 들어, 부모 A의 z-index가 1이고 부모 B의 z-index가 2라면, 부모 A 안에 있는 자식의 z-index를 99999로 주더라도 부모 B(또는 B의 자식들) 위로 절대로 올라갈 수 없습니다! 부모 덩어리째로 순서가 이미 결정 나버렸기 때문이죠.


이 문서의 목차 (In this article)


쌓임 문맥을 생성하는 속성들 (Features creating stacking contexts)

문서 내의 어느 곳에서든, 다음 시나리오 중 하나에 해당하는 요소는 새로운 쌓임 문맥을 형성합니다.

💡 강사의 실무 팁 2
"어? 나는 z-index를 건드린 적이 없는데 왜 갑자기 요소가 다른 걸 덮어버리지?"
실무에서 가장 흔하게 실수하는 포인트가 바로 transform이나 opacity입니다. 멋진 애니메이션을 넣으려고 transform: translateY(-10px)이나 opacity: 0.9를 주는 순간, 그 요소는 새로운 쌓임 문맥을 생성하면서 기존의 레이어 질서를 무시하고 위로 툭 튀어나오게 됩니다. 이 목록을 잘 기억해두시면 나중에 버그를 잡을 때 큰 도움이 됩니다!


중첩된 쌓임 문맥 (Nested stacking contexts)

쌓임 문맥은 다른 쌓임 문맥 안에 포함될 수 있으며, 이들이 함께 모여 쌓임 문맥의 계층 구조(hierarchy)를 만들 수 있습니다.

문서의 루트 요소(<html>)는 가장 기본이 되는 쌓임 문맥입니다. 대부분의 경우 이 안에는 중첩된 쌓임 문맥들이 들어있고, 그 문맥들은 또다시 추가적인 쌓임 문맥들을 포함하게 됩니다. 각각의 쌓임 문맥 안에서 자식 요소들은 z-index 사용하기에서 설명한 규칙에 따라 쌓입니다.

중요한 점은, 자식 쌓임 문맥의 z-index 값은 오직 부모의 쌓임 문맥 안에서만 의미를 가진다는 것입니다. 쌓임 문맥들은 부모 쌓임 문맥 안에서 하나의 원자적인 단위(단일 유닛)로 처리됩니다.

Z축을 따라 쌓인 요소들의 렌더링 순서를 쉽게 파악하려면, 각 인덱스 값을 일종의 "버전 번호(version number)"라고 생각해보세요. 자식 요소들의 값은 부모의 주 버전(major version) 번호 아래에 있는 부버전(minor version) 번호가 됩니다.

각 요소의 쌓임 순서가 조상(부모) 쌓임 문맥의 쌓임 순서에 어떻게 참여하는지 보여주기 위해, 6개의 컨테이너 요소가 있는 예제 페이지를 살펴보겠습니다. 여기에는 3개의 형제 <article> 요소가 있습니다. 마지막(세 번째) <article> 안에는 3개의 형제 <section> 요소가 들어있으며, 이 세 번째 article의 <h1><code> 요소는 첫 번째와 두 번째 <section> 형제 요소 사이에 나타납니다.

<article id="container1">
  <h1>Article element #1</h1>
  <code>
    position: relative;<br />
    z-index: 5;
  </code>
</article>

<article id="container2">
  <h1>Article Element #2</h1>
  <code>
    position: relative;<br />
    z-index: 2;
  </code>
</article>

<article id="container3">
  <section id="container4">
    <h1>Section Element #4</h1>
    <code>
      position: relative;<br />
      z-index: 6;
    </code>
  </section>

  <h1>Article Element #3</h1>
  <code>
    position: absolute;<br />
    z-index: 4;
  </code>

  <section id="container5">
    <h1>Section Element #5</h1>
    <code>
      position: relative;<br />
      z-index: 1;
    </code>
  </section>

  <section id="container6">
    <h1>Section Element #6</h1>
    <code>
      position: absolute;<br />
      z-index: 3;
    </code>
  </section>
</article>

모든 컨테이너 요소는 1 미만의 opacity 값을 가지고 있거나 (이로 인해 쌓임 문맥이 생성됨), position 값이 relative 또는 absolute로 설정되어 있습니다 (요소에 auto가 아닌 z-index 값이 있으므로 쌓임 문맥이 생성됨).

(간결함을 위해 색상, 폰트, 정렬, 박스 모델과 관련된 CSS 코드는 생략되었습니다.)

section,
article {
  opacity: 0.85;
  position: relative;
}
#container1 {
  z-index: 5;
}
#container2 {
  z-index: 2;
}
#container3 {
  z-index: 4;
  position: absolute;
  top: 40px;
  left: 180px;
}
#container4 {
  z-index: 6;
}
#container5 {
  z-index: 1;
}
#container6 {
  z-index: 3;
  position: absolute;
  top: 20px;
  left: 180px;
}

위 예제에서 쌓임 문맥의 계층 구조를 트리 형태로 보면 다음과 같습니다:

Root (루트, html)
│
├── ARTICLE #1 (버전 5.0)
├── ARTICLE #2 (버전 2.0)
└── ARTICLE #3 (버전 4.0)
  │
  ├── SECTION #4 (버전 4.6)
  ├────  ARTICLE #3 내부의 일반 콘텐츠들
  ├── SECTION #5 (버전 4.1)
  └── SECTION #6 (버전 4.3)

3개의 <section> 요소는 ARTICLE #3의 자식입니다. 따라서 이 section 요소들의 쌓임 순서는 전적으로 ARTICLE #3 안에서만 해결(결정)됩니다. ARTICLE #3 내부의 쌓임과 렌더링이 모두 완료되고 나면, 이 완성된 ARTICLE #3 요소 전체 덩어리가 다른 형제 <article> 요소들과의 순서를 겨루기 위해 부모(루트 요소)에게 전달됩니다.

z-index를 "버전 번호"와 비교해 보면, 왜 z-index가 1인 요소(SECTION #5)가 z-index가 2인 요소(ARTICLE #2)보다 더 위에 쌓이는지, 그리고 왜 z-index가 6인 요소(SECTION #4)가 z-index가 5인 요소(ARTICLE #1)보다 아래에 쌓이는지 명확하게 이해할 수 있습니다.

SECTION #4는 ARTICLE #1보다 아래에 렌더링됩니다. 왜냐하면 ARTICLE #1의 z-index(5)는 루트 요소의 쌓임 문맥 안에서 유효한 반면, SECTION #4의 z-index(6)은 ARTICLE #3(z-index: 4)의 쌓임 문맥 안에서만 유효하기 때문입니다.
결과적으로 SECTION #4는 ARTICLE #3에 속해있고, ARTICLE #3의 z-index 값(4)이 ARTICLE #1의 값(5)보다 작기 때문에 SECTION #4는 ARTICLE #1 밑에 깔리게 됩니다. (버전 4.6은 버전 5.0보다 낮습니다!)

같은 이유로 ARTICLE #2(z-index: 2)는 SECTION #5(z-index: 1) 밑에 렌더링됩니다. SECTION #5는 ARTICLE #3(z-index: 4)에 속해있고, ARTICLE #3이 ARTICLE #2보다 z-index 값이 더 크기 때문입니다. (버전 2.0은 버전 4.1보다 낮습니다!)

ARTICLE #3의 z-index는 4지만, 이 값은 그 안에 중첩된 3개의 section들의 z-index와는 완전히 무관합니다. 왜냐하면 이 section들은 루트와는 다른, ARTICLE #3이라는 별개의 쌓임 문맥에 속해있기 때문입니다.

우리 예제의 최종 렌더링 순서(아래에서 위로 쌓이는 순서)를 정리하면 다음과 같습니다:

  • Root
    • ARTICLE #2: (z-index: 2) -> 렌더링 버전: 2.0 (가장 아래)
    • ARTICLE #3: (z-index: 4) -> 렌더링 버전: 4.0
      • SECTION #5: (z-index: 1, 부모는 4) -> 렌더링 버전: 4.1
      • SECTION #6: (z-index: 3, 부모는 4) -> 렌더링 버전: 4.3
      • SECTION #4: (z-index: 6, 부모는 4) -> 렌더링 버전: 4.6
    • ARTICLE #1: (z-index: 5) -> 렌더링 버전: 5.0 (가장 위)

💡 강사의 실무 팁 3
이 버전 번호 비유(소프트웨어 버전처럼 생각하는 것)가 정말 기가 막히게 좋은 비유입니다!
1.9.9.9 버전이 아무리 마이너 숫자가 높아도, 2.0.0.0 버전을 이길 수 없죠.
CSS 요소가 위로 안 올라온다면, 그 요소의 z-index를 올릴 게 아니라, 그 요소를 감싸고 있는 부모들 중 누가 쌓임 문맥을 형성했고, 그 부모의 랭킹(z-index)이 몇 위인지를 먼저 확인하셔야 합니다! 브라우저 개발자 도구(F12)의 'Layers(레이어)' 탭을 활용하시면 이걸 3D로 시각화해서 볼 수 있으니 꿀팁으로 활용해보세요!


추가 예제 (Additional examples)

다음에 나오는 링크들을 통해 추가적인 예제를 확인할 수 있습니다.


함께 보기 (See also)


MDN 향상에 도움 주기 (Help improve MDN)


프론트엔드 포트폴리오를 만드실 때 모달(Modal) 창이나 드롭다운 메뉴, 알림(Toast) 메시지 등을 구현하시게 될 텐데, 이때 이 '쌓임 문맥' 개념을 정확히 이해하고 계시면 스타일 꼬임 없이 아주 깔끔하게 구조를 잡으실 수 있을 거예요! 읽어보시고 헷갈리는 부분이 있다면 언제든지 질문해주세요.

profile
프론트에_가까운_풀스택_개발자

0개의 댓글