BFC는 블록 박스의 레이아웃이 발생하고, float가 다른 요소와 상호작용하는 영역이다.
Formatting context는 레이아웃에 영향을 미치지만, 일반적으로 레이아웃을 수정하는 목적보다는 float를 배치하고 clear하기 위한 목적으로 새로운 BFC를 만든다,
왜냐하면 새 BFC를 만든 엘리먼트들은 다음의 역할을 수행할 수 있기 때문이다.
contain internal floats.
exclude external floats.
suppress margin collapsing.
Flex/Grid 컨테이너는 BFC가 아니라 BFC와 유사한 Flex/Grid formatting context 를 만든다.
Flex/Grid 컨테이너 안에는 floating 자식들이 없어서 위의 "contain internal floats" 역할을 수행하진 않지만 "exclude external floats" 와 "suppress margin collapsing" 을 위해 사용된다.
각각의 역할을 살펴보자.
다음 예제에서는 테두리가 적용된 부모 엘리먼트 내부에 floated 엘리먼트와 일반 엘리먼트가 있다.
floated 엘리먼트는 다른 엘리먼트들과 겹쳐 보이는데 다만, 일반 엘리먼트의 content(텍스트)와는 겹치지 않고 나란히 떠있다.
이는 초창기 웹 문서에서 이미지를 텍스트 중간에 넣기위해 개발된 것이기 때문이다.
floated 엘리먼트의 크기가 일반 엘리먼트의 content보다 크기 때문에 부모 엘리먼트의 보더는 floated 엘리먼트를 통과한다.
floated 엘리먼트는 flow에서 제거되므로 부모 엘리먼트의 배경과 보더에는 일반 엘리먼트만 포함된다.
<div class="box">
<div class="float">I am a floated box!</div>
<p>I am content inside the container.</p>
</div>
overflow
프로퍼티의 값으로 visible
과 clip
을 제외한 나머지 값으로 설정하면 새 BFC가 생성된다.
이제 부모 엘리먼트의 inner display로 기존의 레이아웃과는 별개인 새로운 레이아웃이 만들어진다.
다만, flex 나 grid 같은 새로운 동작방식의 레이아웃이 아닌 기존의 block inline 레이아웃 동작방식을 따른다. (그래서 block fommating context 이다)
BFC는 float를 포함하는 영역이므로 floated 엘리먼트가 부모 엘리먼트 내부에 위치된다.
<div class="box" style="overflow:auto">
<div class="float">I am a floated box!</div>
<p>I am content inside the <code>overflow:auto</code> container.</p>
</div>
하지만 using overflow: auto
방법으로 BFC를 생성하는 것은 바람직 하지 않다.
overflow
프로퍼티는 오버플로되는 content를 처리하는 방법을 브라우저에게 알려주기 위한 프로퍼티이지 BFC 생성이 목적인 프로퍼티는 아니다.
따라서 BFC의 생성으로는 적합하지 않다.
이 속성을 순수하게 BFC를 만드는 데 사용하면 원치 않는 스크롤 막대나 잘린 그림자가 나타나 버그를 초래할 수 있다.
또한, 프로퍼티의 이름과 무관하게 쓰였기 때문에 다른 개발자가 이해하기 어려워서 주석을 추가해야 하는 불편함이 있다.
잠재적인 문제를 일으키지 않으면서 새 BFC를 만들수 있는 display
프로퍼티의 값이 있다.
바로 flow-root
이다.
flow-root
는 root 엘리먼트( <html>
)처럼 내부의 flow 레이아웃에 새 컨텍스트를 만든다는 관점에서 비슷하다는 이유로 네이밍 되었다.
<div class="box" style="display:flow-root">
<div class="float">I am a floated box!</div>
<p>I am content inside the <code>display:flow-root</code> container.</p>
</div>
normal flow에 속해있는 엘리먼트가 새 BFC를 생성하면 그 엘리먼트와 동일 레벨에 있는 floated 엘리먼트와 겹치지 않는다.
<section>
<div class="float">Try to resize this outer float</div>
<div class="box"><p>Normal</p></div>
</section>
<section>
<div class="float">Try to resize this outer float</div>
<div class="box" style="display:flow-root">
<p><code>display:flow-root</code></p>
</div>
</section>
BFC의 마지막 역할은 마진 충돌을 방지이다.
마진 충돌이 일어나는 엘리먼트를 포함하는 새 <div>
를 만들고 BFC를 적용해보자.
<div class="blue"></div>
<div class="outer">
<div class="red"></div>
</div>
.blue,
.red {
height: 50px;
margin: 10px 0;
}
.blue {
background: blue;
}
.red {
background: red;
}
.outer {
overflow: hidden;
background: transparent;
}
마진 충돌이 일어나면 두 박스 사이의 거리가 20px이 아닌 10px이 된다.
[참고] : MDN