Самый полный и тщательный анализ принципов BFC в истории
Цзо Пэнфэй 2017.09.21
В этой статье рассказывается о концепции BFC, правилах ограничения BFC, способе инициирования создания нового BFC, применении BFC в макете: предотвращение перекрытия полей (схлопывание, в зависимости от того, что больше), очистка внутренних плавающих элементов, адаптивность макет с двумя (многоколонками).
1. Что такое БФК?
Block fomatting context = block-level box + Formatting Context
Box:
Box — модель коробки;
- блок уровня блока является элементом уровня блока
Элементы, атрибутами отображения которых являются блок, элемент списка и таблица, будут генерировать блоки на уровне блока и участвовать в
block fomatting context;
- поле встроенного уровня является встроенным элементом
Элементы со свойством display inline, inline-block или inline-table будут генерировать поле встроенного уровня. и участвовать
inline formatting context;
Formatting context
Контекст форматирования — это понятие в спецификации W3C CSS2.1. Это область рендеринга на странице, и она имеет набор правил рендеринга, которые определяют, как будут расположены его дочерние элементы, а также взаимосвязь и взаимодействие с другими элементами. Наиболее распространенными контекстами форматирования являются контекст блочного форматирования (сокращенно BFC) и контекст встроенного форматирования (сокращенно IFC).
В CSS2.1 есть только BFC и IFC, а G(grid)FC и F(flex)FC также добавлены в CSS3.
Определение БФК
BFC (контекст форматирования блока) буквально переводится как «контекст форматирования на уровне блока». Это независимая область рендеринга, в которой участвует только блок уровня блока, он определяет, как размещается внутренний блок уровня блока, и не имеет ничего общего с внешней частью этой области.
2. Генерация BFC
Как упоминалось выше, BFC - это область рендеринга, поэтому, где именно находится эта область рендеринга и насколько она велика, они определяются элементом, который генерирует BFC.CSS2.1 предусматривает, что элемент, который удовлетворяет одному из следующих объявлений CSS будет генерировать BFC.
- корневой элемент
- Значение float не равно none
- Значение переполнения не видно
- Значение display: inline-block, table-cell, table-caption.
display: table также считает, что BFC может быть сгенерирован. На самом деле, основная причина здесь в том, что Table по умолчанию будет генерировать анонимную ячейку таблицы. Именно эта анонимная ячейка таблицы генерирует BFC.
- Значение position абсолютное или фиксированное
3. Обязательные правила BFC
- Внутренние ящики будут размещены один за другим в вертикальном направлении.
- Расстояние в вертикальном направлении определяется запасом. (Полное утверждение таково: поля двух соседних блоков, принадлежащих одному и тому же BFC, будут перекрываться (схлопываться) независимо от ориентации.)
- Левое поле каждого элемента касается левой границы содержащего блока (слева направо), даже для плавающих элементов. (Это означает, что нейтронный элемент БТЭ не выйдет за пределы содержащего его блока, а элемент, положение которого является абсолютным, может выйти за границу содержащего его блока)
- Площадь BFC не будет перекрывать площадь элемента поплавка
- При расчете высоты BFC в расчете также участвуют плавающие дочерние элементы
- BFC — это изолированный и независимый контейнер на странице, дочерние элементы внутри контейнера не будут влиять на внешние элементы, и наоборот
Увидев указанные выше ограничения, подумайте о нескольких правилах, когда мы будем изучать css.
- Блочные элементы будут расширяться до той же ширины, что и родительский элемент, поэтому блочные элементы будут выровнены по вертикали.
- Поля двух соседних DIV по вертикали будут перекрываться, но не по горизонтали (это правило не совсем правильное)
- Плавающие элементы будут расположены как можно ближе к верхнему левому (или верхнему правому) краю.
- Установите переполнение: скрытый или плавающий родительский элемент для родительского элемента, и плавающий элемент будет включен
4. Применение BFC в макете
4.1 Предотвратить перекрытие полей (свернуть):
Вертикальные поля двух соседних блоков перекрываются
<style>
p {
color: #f55;
background: #fcc;
width: 200px;
line-height: 100px;
text-align:center;
margin: 100px;
}
</style>
<body>
<p>Haha</p>
<p>Hehe</p>
</body>
скопировать код
Расстояние между двумя P равно 100 пикселям, а поле перекрывается (сворачивается) в зависимости от того, какое значение больше. Если поле первого P равно 80, расстояние между двумя P по-прежнему равно 100, в зависимости от того, что больше.
Согласно второму правилу компоновки BFC:
Box垂直方向的距离由margin决定。属于同一个BFC(上例中是body根元素的BFC)的两个相邻Box的margin会发生重叠
скопировать код
Мы можем обернуть контейнер вокруг p и запустить контейнер для создания нового BFC. Тогда два P не принадлежат одному и тому же BFC, и перекрытия полей не будет.
Код:
<style>
.wrap {
overflow: hidden;// 新的BFC
}
p {
color: #f55;
background: #fcc;
width: 200px;
line-height: 100px;
text-align:center;
margin: 100px;
}
</style>
<body>
<p>Haha</p>
<div class="wrap">
<p>Hehe</p>
</div>
</body>
скопировать код
Горизонтальные поля соседних блоков перекрываются
<!doctype HTML>
<html>
<head>
<style type="text/css">
#green {
margin:10px 10px 10px 10px
}
#blue {
margin:10px 10px 10px 10px
}
#red {
margin:10px 10px 10px 10px
}
body {
writing-mode:tb-rl;
}
</style>
</head>
<body>
<div id="green" style="background:lightgreen;height:100px;width:100px;"></div>
<div id="blue" style="background:lightblue;height:100px;width:100px;"></div>
<div id="red" style="background:pink;height:100px;width:100px;"></div>
</body>
</html>
скопировать код
Вы можете видеть, что горизонтальные поля перекрываются.
Мы можем добавить divdisplay:inline-block, коснитесь каждого контейнера div, чтобы создать BFC. Тогда три DIV не принадлежат одному и тому же BFC (BFC, образованному корневым элементом body), и перекрытия полей не произойдет.
Поля вложенных элементов перекрываются
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!--The viewport meta tag is used to improve the presentation and behavior of the samples
on iOS devices-->
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
<title></title>
<style>
html, body { height: 100%; width: 100%; margin: 0; padding: 0; }
#map{
padding:0;
}
.first{
margin:20px;
background:lightgreen;
width:100px;
height:100px;
}
ul{
/*display:inline-block;*/
margin:10px;
background:lightblue;
}
li{
margin:25px;
}
</style>
</head>
<body class="claro">
<div class="first"></div>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</body>
</html>
скопировать код
В это время расстояние по вертикали между div и ul является максимальным внешним полем между div, ul и li.
Чтобы предотвратить перекрытие полей вложенных элементов, просто позвольте ul сгенерировать BFC (удалите комментарий в приведенном выше примере), чтобы не было перекрытия между div, ul и li.
И li находится в одном и том же BFC, поэтому перекрытие все еще существует.
Установка линейного блока для li для регенерации bfc не будет перекрываться.
нужно знать, это:
Если для ul задано значение border или padding, поле элемента будет содержаться в блочной модели родительского элемента и не будет перекрывать внешний div.
В «Полном руководстве по CSS» упоминается, что для высоты элементов нормального потока на уровне блока задано значение «авто», и есть только подэлементы на уровне блока, а высота по умолчанию будет от внешней границы самого высокого подэлемента на уровне блока. -элемента к внешней границе самого нижнего подэлемента уровня блока.расстояние между. Если элемент блочного уровня имеет верхний правый или нижний отступ или верхнюю или нижнюю границу, его высота равна расстоянию от границы верхнего поля самого высокого дочернего элемента до границы нижнего поля самого нижнего дочернего элемента.
4.2 Очистить внутренний поплавок
<style>
.par {
border: 5px solid #fcc;
width: 300px;
}
.child {
border: 5px solid #f66;
width:100px;
height: 100px;
float: left;
}
</style>
<body>
<div class="par">
<div class="child"></div>
<div class="child"></div>
</div>
</body>
скопировать код
страница:
В соответствии со статьей 6 Правил компоновки BFC:
计算BFC的高度时,浮动元素也参与计算
скопировать код
Чтобы очистить внутреннее плавание, мы можем вызвать par для генерации BFC, тогда, когда par вычисляет высоту, дочерний плавающий элемент внутри par также будет участвовать в вычислении.
.par {
overflow: hidden;
}
скопировать код
4.3 Адаптивная многоколоночная верстка
4.3.1 Адаптивный двухколоночный макет
<style>
body {
width: 300px;
position: relative;
}
.aside {
width: 100px;
height: 150px;
float: left;
background: #f66;
}
.main {
height: 200px;
background: #fcc;
}
</style>
<body>
<div class="aside"></div>
<div class="main"></div>
</body>
скопировать код
В соответствии со статьей 3 Правил компоновки BFC:
每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
скопировать код
Таким образом, несмотря на то, что плавающий элемент смещен, левая сторона main все еще касается левой стороны содержащего блока.
Согласно статье 4 правил компоновки BFC:
BFC的区域不会与float box重叠。
скопировать код
Мы можем добиться адаптивного двухколоночного макета, запустив main для создания BFC.
.main {
overflow: hidden;
}
скопировать код
При запуске main для создания BFC этот новый BFC не будет перекрываться с плавающей стороной. Поэтому он будет автоматически сужен в соответствии с шириной содержащего блока и шириной стороны. Эффект следующий:
4.3.2 Адаптивная двухколоночная верстка
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!--The viewport meta tag is used to improve the presentation and behavior of the samples
on iOS devices-->
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
<title></title>
<style>
html, body { height: 100%; width: 100%; margin: 0; padding: 0; }
.left{
background:pink;
float: left;
width:180px;
}
.center{
background:lightyellow;
overflow:hidden;
}
.right{
background: lightblue;
width:180px;
float:right;
}
</style>
</head>
<body class="claro">
<div class="container">
<div class="left">
<pre>
.left{
background:pink;
float: left;
width:180px;
}
</pre>
</div>
<div class="right">
<pre>
.right{
background:lightblue;
width:180px;
float:right;
}
</pre>
</div>
<div class="center">
<pre>
.center{
background:lightyellow;
overflow:hidden;
height:116px;
}
</pre>
</div>
</div>
</html>
скопировать код
Особенность этой раскладки в том, что ширина левой и правой колонок фиксирована, а средняя колонка может подстраиваться под ширину браузера.
4. Резюме
На самом деле все приведенные выше примеры отражают пятое правило компоновки BFC:
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
скопировать код
Поскольку элементы внутри BFC и элементы снаружи никогда не будут влиять друг на друга, следовательно,
Когда за пределами BFC находится поплавок, это не должно влиять на компоновку Box внутри BFC, и BFC будет сужаться, не перекрывая поплавок. Точно так же, когда внутри BFC есть плавающая точка, чтобы не влиять на компоновку внешних элементов, BFC будет учитывать плавающую высоту при расчете высоты. Избегание перекрытия полей также является причиной.
