Причина
Проблема в том, что плавающие элементы вне потока :
Элемент называется вне потока , если он является плавающим, абсолютно
позиционируется или является корневым элементом.
Следовательно, они не влияют на окружающие элементы, как элемент in-flow .
Это объясняется в 9,5 Float :
Поскольку поплавок отсутствует в потоке, создаются непозиционированные блоки блоков
до и после поплавка коробка течет вертикально, как будто поплавок не
существовать. Тем не менее, текущие и последующие линейные блоки, созданные рядом с
поплавок укорачивается по мере необходимости, чтобы освободить место для поля на полях
поплавка.
![enter image description here](https://i.stack.imgur.com/Ad2eq.png)
html {
width: 550px;
border: 1px solid;
}
body {
font-family: sans-serif;
color: rgba(0,0,0,.15);
}
body:after {
content: '';
display: block;
clear: both;
}
div {
position: relative;
}
div:after {
font-size: 200%;
position: absolute;
left: 0;
right: 0;
top: 0;
text-align: center;
}
.block-sibling {
border: 3px solid green;
}
.block-sibling:after {
content: 'Block sibling';
color: green;
}
.float {
float: left;
border: 3px solid red;
height: 90px;
width: 150px;
z-index: 1;
}
.float:after {
content: 'Float';
color: red;
}
<div class="float"></div>
<div class="block-sibling">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor.
</div>
Это также указано в 10.6 Расчет высоты и полей . Для «обычных» блоков ,
Учитываются только дети в нормальном потоке (т.е.
плавающие и абсолютно позиционированные блоки игнорируются […])
![enter image description here](https://i.stack.imgur.com/vQacA.png)
html {
width: 550px;
border: 1px solid;
}
body {
font-family: sans-serif;
color: rgba(0,0,0,.15);
}
body:after {
content: '';
display: block;
clear: both;
}
div {
position: relative;
}
div:after {
font-size: 200%;
position: absolute;
left: 0;
right: 0;
top: 0;
text-align: center;
}
.block-parent {
border: 3px solid blue;
}
.block-parent:after {
content: 'Block parent';
color: blue;
}
.float {
float: left;
border: 3px solid red;
height: 130px;
width: 150px;
}
.float:after {
content: 'Float';
color: red;
}
<div class="block-parent">
<div class="float"></div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit.
</div>
Hacky решение: оформление
Способ решения этой проблемы - принудительное размещение некоторого элемента в потоке под всеми поплавками. Затем высота родительского элемента будет расти, чтобы обернуть этот элемент (и, следовательно, также и плавающие элементы).
Этого можно достичь, используя свойство clear
:
Это свойство указывает, какие стороны ящика (ов) элемента могут не
быть рядом с более ранней плавающей коробкой.
![enter image description here](https://i.stack.imgur.com/ukyrs.png)
html {
width: 550px;
border: 1px solid;
}
body {
font-family: sans-serif;
color: rgba(0,0,0,.15);
}
body:after {
content: '';
display: block;
clear: both;
}
div {
position: relative;
}
div:after {
font-size: 200%;
position: absolute;
left: 0;
right: 0;
top: 0;
text-align: center;
}
.block-parent {
border: 3px solid blue;
}
.block-parent:after {
content: 'Block parent';
color: blue;
}
.float {
float: left;
border: 3px solid red;
height: 84px;
width: 150px;
}
.float:after {
content: 'Float';
color: red;
}
.clear {
clear: both;
text-align: center;
height: 37px;
border: 3px dashed pink;
}
.clear:after {
position: static;
content: 'Block sibling with clearance';
color: pink;
}
<div class="block-parent">
<div class="float"></div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra.
<div class="clear"></div>
</div>
Таким образом, решение заключается в добавлении пустого элемента с clear: both
в качестве последнего брата поплавков
<div style="clear: both"></div>
Однако это не семантика. Так что лучше сгенерировать псевдоэлемент в конце родительского элемента:
.clearfix::after {
clear: both;
display: block;
}
Существует несколько вариантов этого подхода, например, использование устаревшего синтаксиса с одинарным двоеточием :after
для поддержки старых браузеров или использование других блочных уровней , например display: table
.
Решение: корни BFC
Существует исключение из проблемного поведения, определенного в начале: если элемент блока устанавливает Контекст форматирования блока (является корнем BFC), то он также переносит свое плавающее содержимое.
В соответствии с 10.6.7 высоты 'Авто' для корней контекста форматирования блока ,
Если у элемента есть плавающие потомки, нижний край поля которых
ниже нижнего края содержимого элемента, то высота
увеличено, чтобы включить эти края.
![enter image description here](https://i.stack.imgur.com/bp7dG.png)
html {
width: 550px;
border: 1px solid;
}
body {
font-family: sans-serif;
color: rgba(0,0,0,.15);
}
body:after {
content: '';
display: block;
clear: both;
}
div {
position: relative;
}
div:after {
font-size: 200%;
position: absolute;
left: 0;
right: 0;
top: 0;
text-align: center;
}
.block-parent {
border: 3px solid blue;
}
.block-parent.bfc-root:after {
content: 'BFC parent';
color: blue;
}
.float {
float: left;
border: 3px solid red;
height: 127px;
width: 150px;
}
.float:after {
content: 'Float';
color: red;
}
.bfc-root {
overflow: hidden;
}
<div class="block-parent bfc-root">
<div class="float"></div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit.
</div>
Кроме того, как объяснено 9.5 Плавающие , корни BFC также полезны из-за следующего:
Граничный блок таблицы, замененный элемент уровня блока или
элемент в нормальном потоке, который устанавливает новое форматирование блока
контекст […] не должен перекрывать поля полей любых чисел в том же
блокировать форматирование контекста как самого элемента.
![enter image description here](https://i.stack.imgur.com/djgsv.png)
html {
width: 550px;
border: 1px solid;
}
body {
font-family: sans-serif;
color: rgba(0,0,0,.15);
}
body:after {
content: '';
display: block;
clear: both;
}
div {
position: relative;
}
div:after {
font-size: 200%;
position: absolute;
left: 0;
right: 0;
top: 0;
text-align: center;
}
.block-sibling {
border: 3px solid green;
}
.block-sibling.bfc-root:after {
content: 'BFC sibling';
color: green;
}
.float {
float: left;
border: 3px solid red;
height: 90px;
width: 150px;
z-index: 1;
}
.float:after {
content: 'Float';
color: red;
}
.bfc-root {
overflow: hidden;
}
<div class="float"></div>
<div class="block-sibling bfc-root">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur.
</div>
Контекст форматирования блока устанавливается
Блок-боксы с overflow
кроме visible
, например hidden
.bfc-root {
overflow: hidden;
/* display: block; */
}
Блокировать контейнеры, которые не являются блок-блоками: когда display
установлен на inline-block
, table-cell
или table-caption
.
.bfc-root {
display: inline-block;
}
Плавающие элементы: когда float
установлен на left
или right
.
.bfc-root {
float: left;
}
Абсолютно позиционированные элементы: когда position
установлено на absolute
или fixed
.
.bfc-root {
position: absolute;
}
Обратите внимание, что они могут иметь нежелательные побочные эффекты, такие как отсечение переполнения содержимого, вычисление автоматической ширины с помощью алгоритма shrink-to-fit или выход из потока. Таким образом, проблема в том, что невозможно иметь элемент уровня блока в потоке с видимым переполнением, который устанавливает BFC.
Дисплей L3 решает следующие проблемы:
Создан внутренний дисплей flow
и flow-root
типы , чтобы лучше выразить макет потока типы отображения и к
создать явный переключатель для создания элемента BFC root.
(Это должно устранить необходимость в таких хаки, как ::after { clear: both; }
и overflow: hidden
[…])
К сожалению, браузер пока не поддерживается. В конце концов мы можем использовать
.bfc-root {
display: flow-root;
}