이번 시간에는 블록 포매팅 컨텍스트에 대해 알아보겠습니다. BFC라고 줄여서 부르겠습니다. 명시적인 특성이 아니라서 많은 분들이 빠뜨립니다.
MDN에는 다음과 같은 상황에 블록 포매팅 컨텍스트가 생긴다고 나와 있는데요. 외우지 마세요.
- 문서의 루트 요소(
<html>
). - 플로팅 요소(
float
이none
이 아님). - 절대 위치를 지정한 요소(
position
이absolute
또는fixed
). - 인라인 블록(
display
가inline-block
). - 표 칸(
display
가table-cell
, HTML 표 칸의 기본값). - 표 주석(
display
가table-caption
, HTML 표 주석의 기본값). display
가table
,table-row
,table-row-group
,table-header-group
,table-footer-group
(HTML 표에서, 각각 표 전체, 행, 본문, 헤더, 푸터의 기본값) 또는inline-table
인 요소가 암시적으로 생성한 무명 칸.overflow
가visible
이 아닌 블록 요소.display
가flow-root
.contain
이layout
,content
,paint
.- 스스로 플렉스, 그리드, 테이블 컨테이너가 아닌 경우의 플렉스 항목(
display
가flex
또는inline-flex
인 요소의 바로 아래 자식) - 스스로 플렉스, 그리드, 테이블 컨테이너가 아닌 경우의 그리드 항목(
display
가grid
또는inline-grid
인 요소의 바로 아래 자식) - 다열 컨테이너(
column-count
(en-US) 또는 (column-width
(en-US)가auto
가 아닌 경우.column-count: 1
포함). column-span
(en-US)이all
인 경우. 해당하는 요소가 다열 컨테이너 안에 위치하지 않아도 항상 새로운 블록 서식 맥락을 생성해야 합니다. (명세 변경, Chrome 버그)
위의 항목들이 중요한 것이 아니라, 얘네들을 언제, 왜 쓰는지가 중요합니다. 보통 마진 콜랩싱이나 float과의 상호작용 처리를 위해 사용합니다.
아래 예제를 보시죠. float: left를 사용하는 경우, 부모 태그(normal-wrapper)는 float: left인 자식 태그를 감싸지 못합니다. 이럴 때 부모 태그에 BFC를 주는 겁니다. overflow: auto를 주거나, 부모 태그도 float: left로 만들거나, display: inline-block을 주는(너비가 100%가 아니어도 되는 경우) 등, 위에 나온 항목을 사용해서 하시면 됩니다.
다만 overflow: auto나 float: left, display: inline-block 등은 각자 특성이 있으므로 부모를 뭘로 할지는 여러분이 판단하셔야겠죠. 보통 대부분은 display: inline-block을 줍니다.
마진 콜랩싱
마진 콜랩싱(겹침) 현상도 알아보고, BFC로 해결해봅시다. CSS에는 잘 이해되지 않는 특성이 있는데, 인접한 두 태그의 상하 마진이 겹치는 현상이 있습니다.
예를 들어 위 태그의 margin-bottom이 100px, 아래 태그의 margin-top이 50px이면 합쳐서 150px의 공간이 남는게 아니라 둘이 겹쳐져서 100px의 공간만 남게 됩니다.
딱 봐도 100px 공간이 비어있죠? 왜 그렇냐고 물어보시면... 그냥 특성이라서 외워야한다고 말씀드려야겠습니다. 심지어 중간에 다른 div들이 있는데도 마진이 겹칩니다.
어쨌든 저희가 의도한 대로 150px의 공간을 남기길 원한다면 어떻게 해야 할까요?
두 태그 사이에 BFC를 생성해주면 됩니다. 명심하세요. 두 태그 사이에 새로운 태그에 BFC를 줘야 합니다. 두 태그를 각각 BFC로 만들어서는 소용 없습니다.