Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

쌓임 맥락(stacking context) 이야기

« CSS « CSS z-index 이해하기

쌓임 맥락(stacking context) 이야기

이전 예제에서(z-index 적용) 특정 DIV의 렌더링 순서는 z-index 속성 값에 영향을 받는다는것을 알았다. 이 현상은 DIV들이 가진 특별한 속성 때문에 그렇다. 바로 쌓임 맥락(stacking context)을 형성한다는 것이다. 

쌓임 맥락은 다음 엘리먼트들에 의해 만들어진다. 

  • html 뿌리 엘리먼트
  • position 속성이 지정되고(absolute든 relative든 상관없이) z-index 속성이 auto 이외의 값을 가지는 엘리먼트들
  • z-index값이 auto가 아닌 다른 값을 가진 flex 요소
  • 투명도가 1보다 적게 지정된 엘리먼트들(opacity) (투명도 명세를 보라)
  • 모바일 웹킷과 크롬 22이상에서는 z-index가 auto여도 position: fixed 이면 항상 새로운 쌓임 맥락이 만들어진다.(이 내용을 보라)

쌓임 맥락 안에서는 자식 엘리먼트들이 이전 예제에서 설명된 규칙들에 의해 쌓인다. 자식 엘리먼트들의 z-index 속성 값은 오로지 부모안에서만 의미를 가진다. 쌓임 맥락은 부모 엘리먼트의 쌓임 맥락을 구성하는 하나의 단위이다. 

요약하자면 

  • position 속성 값을 지정하고 z-index 속성 값을 지정한 엘리먼트는 쌓임 맥락을 만든다(1이 아닌 투명도를 지정하거나)
  • 쌓임 맥락은 다른 쌓임 맥락 안에 포함될 수 있다. 따라서 쌓임 맥락들이 모여서 계층 구조를 이룬다. 
  • 부모 쌓임 맥락들은 자손 쌓임 맥락과는 완전히 독립되어있다. 오로지 자손 쌓임 맥락만이 부모 쌓임 맥락의 영향을 받는다. 
  • 일단 자식 쌓임 맥락들이 그들의 순서대로 쌓이고 나면 전체는 부모의 쌓임 순서를 따른다. 
Note: 쌓임 맥락의 계층구조는 HTML 엘리먼트들의 계층구조의 부분집합이다. 왜냐하면 특정 엘리먼트만이 쌓이 맥락을 만들기 때문이다. 따라서 자신만의 쌓임 맥락을 만들지 않는 엘리먼트들에 대해 '부모 쌓임 맥락에 의해 동화된다.'라 할수 있겠다.

예제

Example of stacking rules modified using z-index

이 예제에서는 모든 엘리먼트들이 쌓임 맥락을 형성한다. 왜냐하면 모든 엘리먼트가 position 속성 값과 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 #4는 DIV #1보다 z-index 속성 값이 더 크지만 DIV #1보다 아래에 렌더링 되었다. 왜냐하면 DIV #1의 z-index 속성 값인 5는 뿌리 엘리먼트의 쌓임 맥락 안에서 유효하나 DIV #4의 z-index 속성 값인 6은 DIV #3의 쌓임 맥락 안에서만 유효하기 때문이다. DIV #4는 자신이 속하는 DIV #3의 z-index 속성 값이 3이므로 DIV #1 아래에 쌓였다.
  • 같은 이유로 DIV #2는 DIV #5 아래에 렌더링 되었다. DIV #5는 DIV #2보다 z-index 값이 작지만 뿌리 엘리먼트의 쌓임 맥락안에서 유효한 DIV #5가 속한 DIV #3의 z-index 값이 DIV #2의 z-index 값 보다 더 크기 때문이다. 
  • DIV #3의 z-index 속성 값인 4는 DIV #4, DIV #5, DIV #6의 z-index 속성값과 독립적이다. 왜냐하면 다른 쌓임 맥락에 속해있기 때문이다. 
  • 렌더링 순서를 이해하는 쉬운 방법은 z-index를 "버전 번호" 처럼 생각하는 것이다. 자식 엘리먼트는 부모 엘리먼트 버전 번호의 마이너 버전이다. 이 방법은 왜 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

예제 소스 코드

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="https://www.w3.org/1999/xhtml" xml:lang="en">
  <head>

    <title>Understanding CSS z-index: The Stacking Context: Example Source</title>

    <style type="text/css">
      * {
        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;
        }
    </style>

  </head>
  <body>

    <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>

  </body>
</html>

Division Element #1

     position: relative;
      z-index: 5;

Division Element #2

     position: relative;
      z-index: 2;

Division Element #4

       position: relative;
        z-index: 6;

Division Element #3

     position: absolute;
      z-index: 4;

Division Element #5

       position: relative;
        z-index: 1;

Division Element #6

       position: absolute;
        z-index: 3;

See also

Original Document Information

문서 태그 및 공헌자

 이 페이지의 공헌자: mixed80, teoli, jaemin_jo
 최종 변경: mixed80,