전체 목록
CSSMedium#081

BFC(Block Formatting Context)란 무엇이며 어떤 상황에서 생성되나요?

#CSS#BFC#레이아웃#렌더링

답변 포인트

float 해제나 margin 겹침 문제 해결과 관련이 있습니다.

정답 및 해설

빠른 요약

BFC는 블록 레벨 요소들이 렌더링되는 독립된 레이아웃 컨텍스트입니다. BFC 내부 요소들은 외부 요소와 독립적으로 배치됩니다.

BFC(Block Formatting Context)는 블록 레벨 요소들이 독립적으로 렌더링되는 레이아웃 컨텍스트입니다. BFC 내부의 요소들은 외부 요소와 완전히 격리되어 독자적인 레이아웃 규칙이 적용됩니다. Float 정리, 마진 병합 방지, 요소 겹침 방지 등 CSS 레이아웃에서 발생하는 여러 문제를 해결하는 핵심 개념입니다.

BFC의 특성

BFC가 생성되면 다음과 같은 규칙이 해당 영역 내에 적용됩니다.

  1. BFC 내부의 블록 요소들은 수직으로 쌓입니다
  2. BFC 내부 요소와 외부 요소 간의 마진 병합이 발생하지 않습니다
  3. BFC는 내부의 float 요소를 포함합니다 (높이 붕괴 방지)
  4. BFC 영역은 float 요소와 겹치지 않습니다

BFC 생성 조건

CSS
/* 1. overflow: hidden / scroll / auto (visible 제외) */
.bfc-overflow {
    overflow: hidden;
}

/* 2. display: flex / grid / inline-block / table-cell / table-caption */
.bfc-flex {
    display: flex;
}
.bfc-grid {
    display: grid;
}
.bfc-inline-block {
    display: inline-block;
}

/* 3. position: absolute / fixed */
.bfc-absolute {
    position: absolute;
}
.bfc-fixed {
    position: fixed;
}

/* 4. float 요소 (none이 아닌 값) */
.bfc-float {
    float: left;
}

/* 5. contain: layout / content / paint */
.bfc-contain {
    contain: layout;
}

/* 6. display: flow-root (명시적 BFC 생성, 부작용 없음) */
.bfc-flow-root {
    display: flow-root; /* 가장 권장되는 방법 */
}

활용 1: Float 부모 높이 붕괴 방지

문제 상황

float 요소는 일반 문서 흐름에서 벗어나기 때문에, 부모 요소가 float 자식의 높이를 인식하지 못합니다.

HTML
<div class="container">
    <div class="float-item">Float </div>
    <div class="float-item">Float </div>
</div>
<p> </p>
CSS
/* 문제 발생 */
.container {
    border: 2px solid red;
    /* 부모의 높이가 0이 됨! */
}

.float-item {
    float: left;
    width: 100px;
    height: 100px;
    background: lightblue;
}
CSS
   container ( 0)
       
  float1    float2       
       

  float  

해결 방법 비교

CSS
/* 방법 1: clearfix (전통적 방법) */
.container::after {
    content: "";
    display: block;
    clear: both;
}

/* 방법 2: overflow: hidden (BFC 생성) */
.container {
    overflow: hidden; /* BFC 생성 → float 포함 */
}

/* 방법 3: display: flow-root (권장, 부작용 없음) */
.container {
    display: flow-root; /* 명시적으로 BFC 생성 */
}
CSS
/* display: flow-root 적용 후 */

          container float 
  float1    float2       
       

    

활용 2: 마진 병합(Margin Collapse) 방지

인접한 블록 요소 간 마진 병합

HTML
<div class="box1">1 (margin-bottom: 30px)</div>
<div class="box2">2 (margin-top: 20px)</div>
CSS
/* 마진 병합 발생: 두 박스 사이 간격은 50px이 아닌 30px */
.box1 { margin-bottom: 30px; }
.box2 { margin-top: 20px; }
/* 결과: max(30px, 20px) = 30px (병합됨) */
CSS

  box1  

   30px   50px  30px 

  box2  

BFC로 마진 병합 방지

HTML
<div class="box1">1</div>
<div class="bfc-wrapper">
    <div class="box2">2</div>
</div>
CSS
.box1 { margin-bottom: 30px; }
.bfc-wrapper {
    overflow: hidden; /* BFC 생성 → 내부 box2의 마진이 외부로 나오지 않음 */
}
.box2 { margin-top: 20px; }
/* 결과: box1과 box2 사이 간격 = 30px + 20px = 50px */

부모-자식 마진 병합

HTML
<div class="parent">
    <div class="child"> </div>
</div>
CSS
/* 문제: 부모에 border/padding이 없으면 자식의 margin-top이 부모 밖으로 튀어나옴 */
.parent { background: lightgray; }
.child { margin-top: 30px; } /* 부모까지 함께 내려감 */

/* 해결 1: 부모에 padding 추가 */
.parent { padding-top: 1px; }

/* 해결 2: 부모에 border 추가 */
.parent { border-top: 1px solid transparent; }

/* 해결 3: 부모에 BFC 생성 */
.parent { display: flow-root; }

활용 3: Float 요소와 겹침 방지

문제: 일반 블록 요소가 float 요소 아래로 파고듦

HTML
<div class="float-box">Float </div>
<div class="content">  ...   float  .</div>
CSS
.float-box {
    float: left;
    width: 150px;
    height: 100px;
    background: lightblue;
    margin-right: 20px;
}

/* 문제: content가 float 아래로 파고듦 */
.content {
    background: lightyellow;
    /* 텍스트는 float를 피하지만 배경색이 float 아래에 깔림 */
}
CSS

    ...    
   float           
    box                
  float          
 content  float        

BFC로 해결

CSS
/* BFC 생성으로 float 요소와 겹침 방지 */
.content {
    overflow: hidden; /* 또는 display: flow-root */
    background: lightyellow;
}
CSS

     
   float      content (BFC)          
    box              
           
                 

display: flow-root vs overflow: hidden

CSS
/* overflow: hidden의 부작용 */
.container {
    overflow: hidden; /* BFC 생성 */
    /* 문제: 자식 요소가 영역 밖으로 나가면 잘림 */
    /* 드롭다운 메뉴, 툴팁 등이 잘릴 수 있음 */
}

/* display: flow-root: 부작용 없음 (권장) */
.container {
    display: flow-root; /* 명시적 BFC, 오버플로 영향 없음 */
}

브라우저 지원

CSS
/* display: flow-root 미지원 브라우저를 위한 폴백 */
.container {
    overflow: hidden; /* 폴백 */
}

@supports (display: flow-root) {
    .container {
        overflow: initial;
        display: flow-root;
    }
}

현대 CSS에서의 BFC

Flexbox와 Grid 컨테이너는 자동으로 BFC를 생성합니다.

CSS
/* Flexbox: 자동으로 BFC 생성 */
.flex-container {
    display: flex;
    /* float 포함, 마진 병합 방지 등 BFC 특성 자동 적용 */
}

/* Grid: 자동으로 BFC 생성 */
.grid-container {
    display: grid;
}

/* 따라서 현대 레이아웃에서는 BFC 문제가 덜 발생 */
/* float 기반 레거시 코드를 다룰 때 특히 중요 */

실전 예제: 미디어 오브젝트 패턴

HTML
<div class="media">
    <img class="media-image" src="avatar.png" alt="프로필">
    <div class="media-body">
        <h3> </h3>
        <p>   .      UI .</p>
    </div>
</div>
CSS
.media {
    display: flow-root; /* BFC 생성 → float 포함 */
}

.media-image {
    float: left;
    width: 60px;
    height: 60px;
    margin-right: 16px;
}

.media-body {
    overflow: hidden; /* BFC 생성 → 이미지와 겹침 방지 */
    /* 또는: display: flow-root */
}

요약 표

특성설명해결하는 문제
Float 포함BFC 내 float 요소의 높이를 포함부모 높이 붕괴
마진 격리BFC 내부/외부 마진 병합 방지예상치 못한 마진 병합
Float 겹침 방지BFC 영역은 float와 겹치지 않음콘텐츠가 float 아래로 파고듦
BFC 생성 방법부작용권장도
display: flow-root없음최우선 권장
display: flex / grid자식 레이아웃 변경레이아웃 목적이면 OK
overflow: hidden콘텐츠 잘림 가능신중히 사용
overflow: auto/scroll스크롤바 생성 가능필요시 사용
position: absolute/fixed문서 흐름에서 벗어남BFC 목적으로는 비권장
float문서 흐름에서 벗어남BFC 목적으로는 비권장

관련 질문

같은 카테고리/태그 기준