Причина
Проблема в том, что плавающие элементы вне потока:
Элемент называется вне потока, если он плавающий, абсолютно позиционированный или является корневым элементом.
Следовательно, они не влияют на окружающие элементы, как элемент в потоке.
Это объясняется в 9.5 Floats:
Поскольку поплавок не находится в потоке, непозиционированные блоки блоков, созданные до и после плавающего бокса, перетекают вертикально, как если бы поплавок не существовал. Однако текущие и последующие строчные блоки, созданные рядом с поплавком, укорачиваются по мере необходимости, чтобы освободить место для поля поля поплавка.
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 Расчет высот и полей. Для "обычных" блоков,
Учитываются только дочерние элементы в нормальном потоке (т. Е. Плавающие блоки и блоки с абсолютным позиционированием игнорируются […])
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>
Хакерское решение: оформление
Способ решения проблемы - принудительное размещение какого-либо элемента в потоке под всеми поплавками. Затем высота родительского элемента будет расти, чтобы обернуть этот элемент (и, следовательно, поплавки).
Этого можно добиться с помощью свойства clear
:
Это свойство указывает, какие стороны блока (ов) элемента могут не быть смежными с более ранним плавающим блоком.
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 «Авто» высоты для корней контекста форматирования блока,
Если у элемента есть плавающие потомки, нижний край поля которых находится ниже нижнего края содержимого элемента, высота увеличивается, чтобы включить эти края.
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 Floats, корни BFC также полезны по следующим причинам:
Пограничный блок таблицы, заменяемый элемент на уровне блока или элемент в нормальном потоке, который устанавливает новый контекст форматирования блока […], не должен перекрывать поле поля любых плавающих элементов в том же контексте форматирования блока, что и сам элемент .
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;
}
Обратите внимание, что они могут иметь нежелательные побочные эффекты, такие как отсечение переполненного содержимого, автоматическое вычисление ширины с помощью сжать до соответствия алгоритму или перестать работать. Таким образом, проблема в том, что невозможно иметь элемент уровня блока в потоке с видимым переполнением, которое устанавливает BFC.
Display L3 решает следующие проблемы:
Созданы файлы flow
и flow-root
внутренние типы отображения для лучшего отображения макета потока. display types и создать явный переключатель для превращения элемента в корень BFC. (Это должно устранить необходимость в таких хаках, как ::after { clear: both; }
и overflow: hidden
[…])
К сожалению, поддержки браузеров пока нет. В конце концов, мы сможем использовать
.bfc-root {
display: flow-root;
}
person
Oriol
schedule
30.08.2015