컨테이닝 블록의 모든 것 (All about the containing block)

요소들의 크기와 위치는 컨테이닝 블록(containing block)에 의해 영향을 받곤한다. 대부분의 경우, 컨테이닝 블록은 요소의 가장 근접 조상의 콘텐츠 영역(content area)이나 항상 그렇지는 않다.

사용자 유저에이전트(예:브라우저)가 문서를 그리면, 모든 요소에 대해 박스를 생성하며, 각 박스는 네가지 영역으로 나뉜다.

  1. Content area
  2. Padding area
  3. Border area
  4. Margin area

많은 개발자들이 요소의 컨테이닝 영역(containing block)이 항상 그 부모의 콘텐트 영역(content area)라고 믿고 있지만 그렇지 않다! 다음을 읽어보자.

컨테이닝 블록을 식별하는 것이 왜 중요한가?

요소의 크기와 위치는 종종 컨테이닝 블록에 영향을 받는다. aboslute성 요소(position속성이  absolute 혹은 fixed인)의 width, height, padding, marginoffset 속성은 요소의 컨테이닝 블록에 의해 계산된다.

컨테이닝 블록(contaning block)은 어떻게 식별 가능한가?

컨테이닝 블록의 식별 과정은 position 속성에 따라 완전히 달라진다.

  1. position 속성이 static 이나 relative이면, 컨테이닝 블록은 블록 콘테이너(block container)인(예:inline-block, block 이나 list-item 요소) 가장 가까운 조상 content box에 의해 형성되거나 서식 문맥(formatting context)(예: table, flex, grid 콘테이너, 블록 콘테이너 그 자신)을 설정하는 것으로 형성된다.
  2. position 속성이 absolute인 경우, 컨테이닝 블록은 position 속성 값이 static 이외의 값 (fixed, absolute, relative, or sticky)을 가지는 가장 아까운 조상 요소의 padding boxedge에 의해 형성된다.
  3. position 속성이 fixed인 경우, 컨테이닝 블록은 viewport나 페이지 영역에 의해 결정된다.
  4. position 속성이 absolute나 fixed인 경우, 컨테이닝 블록은 다음의 경우들에 가장 가까운 조상의 padding boxedge에 형성될 수 있다.
    1. transform 혹은 perspective 속성이 none이 아닌 경우
    2. transform 혹은 perspective 속성이 will-change인 경우
    3. filter 의 속성이 none 이 아니거나  filter의 값이 will-change인 경우(Firefox만 동작)

노트: 루트 엘리먼트 (<html>)의 컨테이닝 블록은 초기 컨테이닝 블록(initial containing block)이라고 하는 사각형이다. 이는 viewport 혹은 page 영역의 범위를 가진다.

컨테이닝 블록으로부터 퍼센트 값 계산하기

앞서 노트와 같이 퍼센트값이 속성값으로 부여되었을때, 연산된 값은 요소의 컨테이닝 블록에 의해 결정된다. 그 값은 박스 모델과 offset에 영향을 준다. 

  1.  height, top, 그리고 bottom값은 컨테이닝 블록의 height의 영향을 받는다. 만약 컨테이닝 블록의 높이가 해당 내용에 따라 달라진다면, 이 값은 컨테이닝 블록의 positionrelative거나 static일때 0이 된다.
  2. width, left, right, padding, 그리고 margin 속성의 퍼센트 값은 컨테이닝 블록의 width값에 의해 결정된다.

 

모든 예제의 HTML코드는 다음과 같다:

<body>
  <section>
    <p>This is a paragraph!</p>
  </section>
</body>

Example 1

예제에서 문장은 고정 위치이며, 따라서 콘테이닝 블록은 section이다. 그 이유는 그것이 가장 가까운 블록 콘테이너 조상이기 때문이다.

body {
  background: beige;
}

section {
  display: block;
  width: 400px;
  height: 160px;
  background: lightgray;
}

p {
  width: 50%;   /* == 400px * .5 = 200px */
  height: 25%;  /* == 160px * .25 = 40px */
  margin: 5%;   /* == 400px * .05 = 20px */
  padding: 5%;  /* == 400px * .05 = 20px */
  background: cyan;
}

Example 2

다음 예제에서 문장의 컨테이닝 블록은 <body>요소이다. <section>은 블록 컨테이너가 아니고, 서식 문맥(formatting context)이 아니기 때문이다.

body {
  background: beige;
}

section {
  display: inline;
  background: lightgray;
}

p {
  width: 50%;     /* == half the body's width */
  height: 200px;  /* Note: a percentage would be 0 */
  background: cyan;
}

Example 3

다음 예제에서 P태그의 컨테이닝 블록은 <section>이며, 섹션의 positionabsolute이기 때문이다. P태그의 퍼센트 값은 컨테이닝 블록의 padding에 영향을 받는다. 컨테이닝 블록의 box-sizing 값이 border-box라면 예외이다.

body {
  background: beige;
}

section {
  position: absolute;
  left: 30px;
  top: 30px;
  width: 400px;
  height: 160px;
  padding: 30px 20px;
  background: lightgray;
}

p {
  position: absolute;
  width: 50%;   /* == (400px + 20px + 20px) * .5 = 220px */
  height: 25%;  /* == (160px + 30px + 30px) * .25 = 55px */
  margin: 5%;   /* == (400px + 20px + 20px) * .05 = 22px */
  padding: 5%;  /* == (400px + 20px + 20px) * .05 = 22px */
  background: cyan;
}

Example 4

다음 예제에서는 p태그positionfixed이다. 그 결과 콘테이닝 블록은 초기 컨테이닝 블록(initial containing block)(viewport)이다. 결과적으로 문장의 영역은 브라우저 창의 사이즈에 의존한다.

body {
  background: beige;
}

section {
  width: 400px;
  height: 480px;
  margin: 30px;
  padding: 15px;
  background: lightgray;
}

p {
  position: fixed;
  width: 50%;   /* == (50vw - (width of vertical scrollbar)) */
  height: 50%;  /* == (50vh - (height of horizontal scrollbar)) */
  margin: 5%;   /* == (5vw - (width of vertical scrollbar)) */
  padding: 5%;  /* == (5vw - (width of vertical scrollbar)) */
  background: cyan;
}

Example 5

다음 예제는 positionabsolute이다. 따라서 컨테이닝 블록은 <section>이다. 가장 가까운 조상이 transform속성이 none이외의 값을 가지고 있기 때문이다.

body {
  background: beige;
}

section {
  transform: rotate(0deg);
  width: 400px;
  height: 160px;
  background: lightgray;
}

p {
  position: absolute;
  left: 80px;
  top: 30px;
  width: 50%;   /* == 200px */
  height: 25%;  /* == 40px */
  margin: 5%;   /* == 20px */
  padding: 5%;  /* == 20px */
  background: cyan;
}

문서 태그 및 공헌자

 이 페이지의 공헌자: nyxchung
 최종 변경: nyxchung,