BFC는 언제 사용해야 하는가?
블록 서식 맥락(block format context)은 웹 페이지를 렌더링하는 시각적 CSS의 일부로서, 블록 박스의 레이아웃이 발생하는 지점과 플로팅 요소의 상호작용 범위를 결정하는 범위입니다.
위는 MDN에 나와있는 정의인데 이것만 보고 정확하게 BFC가 무엇인지는 감이 오지 않아서 BFC의 정의보다는 언제 사용해야 되는 개념인지에 초점을 맞추었다. 일단 내가 대략적으로 이해한 것은 BFC는 미니 레이아웃이라는 것이다. 어떤 요소에 새로운 BFC를 적용하면 하위 요소를 대상으로 한 독립적인 레이아웃이 생성되며 다른 요소들과도 레이아웃 관계를 형성할 수 있다. 이 말도 이해하기 힘들다면 그냥 의도한 것과 다르게 배치되는 레이아웃을 올바르게 잡는 방법으로 BFC를 적용한다고 생각하면 된다.
BFC는 다음과 같은 상황에서 생성된다.
- 문서의 루트 요소
- 플로팅 요소(
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
또는column-width
가auto
가 아닌 경우.column-count: 1
포함).column-span
이all
인 경우. 해당하는 요소가 다열 컨테이너 안에 위치하지 않아도 항상 새로운 블록 서식 맥락을 생성해야 합니다.
일반적인 맥락에서는 다음과 같은 상황들이 발생할 수 있다.
- float된 요소를 부모 요소가 포함하지 못하는 현상
- float된 요소를 글자들이 감싸는 현상
- 마진 겹침 현상
BFC는 주로 위치 설정과 float 해제를 위해 사용되는 것이다.
그럼 지금부터 각 상황마다 BFC가 문제를 어떻게 해결하는 지 알아보자.
🚩 float된 요소 포함하기
사실 float된 요소를 포함하지 못하는 상황은 clearfix로 해결하는 것이 가장 좋다. clearfix는 CSS에 :after
라는 가상요소를 사용해서 HTML문서에 존재하지 않는 새로운 요소를 생성한 후 clear:both
속성을 주어 해결하는 방법이다. clearfix 외에도 float된 요소를 부모가 포함하는 방법은 많았지만 단점이 있기 때문에 좋은 방법은 아니었다. clearfix를 제외한 거의 모든 방법들이 새 BFC를 생성함으로 문제를 해결하는 것이라고 볼 수 있다.
부모 요소에게도 float
를 주는 방법, 부모의 display
를 inline-block
으로 설정하는 방법, 부모의 overflow
를 auto
나 hidden
으로 설정하는 방법, 빈 블록을 생성하는 방법 모두 사실은 BFC를 생성한다. 즉 BFC를 새롭게 만들어 clearing 한 것이다.
이렇게 부모 container가 float된 이미지를 담지 못할 때 부모에게 overflow:hidden
을 주면 자식 요소를 포함할 수 있게 된다. container에 새 BFC를 준 것이다.
.container {
background: #f6e58d;
overflow: hidden; /*new BFC*/
}
img {
float: left;
}
🚩 float된 요소를 글자들이 감싸는 현상 방지
위의 예에서 만약 텍스트의 길이가 더 늘어나면 다음과 같이 글자가 float
된 이미지를 감싸게 된다. 그렇다면 이런 현상이 왜 발생하는 것일까?
p
태그는 검은색 영역인데 float
된 요소 아래에서도 크기를 차지하고 있는 것을 확인할 수 있다. p
태그의 전체 크기는 줄어들지 않고, 텍스트를 포함하는 부분만 float
된 요소를 피해서 흐르는 것이 특징이다. 텍스트가 더 증가한다면 텍스트를 포함한 부분의 넓이가 줄어들지 않아도 되기 때문에 p
태그의 왼쪽부터 다시 흐르기 시작한다. 그래서 글자가 float
된 요소를 감싸는 현상이 발생하는 것이다.
p
태그에 새로운 BFC를 적용한다면 더이상 container의 왼쪽 끝까지 위치를 가지지 않을 것이기 때문에 p
태그에 overflow:hidden
을 사용하고, background
를 주어 크기를 확인했다.
🚩 마진 겹침 현상 제거
마진 겹침 현상(Margin Collapsing)은 block 모델에서 margin
이 겹치는 현상을 말한다. 두 개 이상의 블록이 위 아래로 위치할 때 블록의 각 margin
이 더해지는 것이 아니라 더 큰 margin
으로 설정되는 현상이다.
마진 겹침 현상은 다음과 같은 상황에서 발생할 수 있다.
- 인접 형제 박스 간 상하 마진이 겹칠 때
- 빈 요소의 상하 마진이 겹칠 때
- 부모 박스와 첫 번째(마지막) 자식 박스의 상단(하단) 마진이 겹칠 때
<div class="container">
<p>I am paragraph one and I have a margin top and bottom of 20px;</p>
<p>I am paragraph two and I have a margin top and bottom of 20px;</p>
</div>
.container {
width: 200px;
background: #f7ce00;
margin: 40px 0 40px 0;
}
p {
padding: 0;
width: 200px;
margin: 20px 0 20px 0;
background-color: #0058b5;
color: #fff;
}
이와 같은 코드에서 container의 margin
과 p
태그의 margin
이 합쳐져 60px
이 전체 margin
이 되어야 한다고 생각할 수 있지만 부모 박스와 첫번째 박스의 마진이 겹치기 때문에 마진 겹침 현상이 발생한다. 이때 부모의 margin
이 40px
이고, 자식의 margin
이 20px
이기 때문에 전체 margin
은 40px
로 설정된다.
p
태그의 margin
이 적용된다면 전체 container의 위 아래에도 노란색이 있어야 한다. 그러나 얻은 결과는 그렇지 않다. 만약 container의 margin을 p태그의 margin보다 작게 한다면 container의 위 아래에서 노란색을 볼 수 있을까? 그렇지 않다. 자식 요소의 margin이 부모 요소의 margin보다 더 크든 작든 상관없이 상쇄된 마진은 부모 박스의 바깥으로만 렌더링 되기 때문이다.
이를 해결하기 위해 css를 다음과 같이 수정하여 새로운 BFC를 준다면 해결할 수 있을 것이다.
.container {
width: 200px;
background: #f7ce00;
margin: 40px 0 40px 0;
overflow: hidden; /* New BFC */
}
p {
padding: 0;
width: 200px;
margin: 20px 0 20px 0;
background-color: #0058b5;
color: #fff;
}
그러나 아직 해결되지 않은 문제가 있다 형제 box간의 마진 겹침 현상이 남아있다. 위쪽 파랑색 박스의 margin
도 20px
이고 아래쪽 파랑색 박스의 margin
도 20px
이기 때문에 위 아래의 margin
이 더해져 40px
이 되게 하고픈 상황이 있을 수 있다. 이럴 때도 새로운 BFC를 생성하면 된다.
<div class="container">
<p>I am paragraph one and I have a margin top and bottom of 20px;</p>
<div class="newBFC">
<p>I am paragraph two and I have a margin top and bottom of 20px;</p>
</div>
</div>
.container {
width: 200px;
background: #f7ce00;
margin: 40px 0 40px 0;
overflow: hidden;
}
p {
padding: 0;
width: 200px;
margin: 20px 0 20px 0;
background-color: #0058b5;
color: #fff;
}
.newBFC {
overflow: hidden;
}
새롭게 newBFC를 적용하니 형제들 간의 margin이 더해졌다.
이렇게 새롭게 BFC를 적용하는 것으로 다양한 문제를 해결할 수 있다. 그러나 어떤 방식으로 BFC를 만드냐에 따라 부작용이 발생할 수 있다. 그래서 상황에 맞게 적절히 적용해야 한다.
display:table
: 반응형에 문제를 줄 수 있다.overflow:scroll
: 스크롤바를 생성한다.float:left
: 요소를 왼쪽으로 이동시키며 다른 요소들에게 영향을 준다.overflow:hidden
: 컨텐츠가 숨겨질 수 있다.
출처 및 참고
- https://doodreamcode.tistory.com/203
- https://www.smashingmagazine.com/2017/12/understanding-css-layout-block-formatting-context/
- https://medium.com/@ritz078/block-formatting-contexts-in-css-3a9555355019
- https://developer.mozilla.org/ko/docs/Web/Guide/CSS/Block_formatting_context
- https://velog.io/@raram2/CSS-마진-상쇄Margin-collapsing-원리-완벽-이해
Author And Source
이 문제에 관하여(BFC는 언제 사용해야 하는가?), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@gotaek/BFC는-언제-사용해야-하는가저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)