Плавающие элементы внутри div, плавает вне div. Почему?

скажем, у вас есть div, скажем, вы окрашиваете его в зеленый цвет и даете ему определенную ширину, когда я помещаю в него материал, в моем случае img и другой div. Идея заключается в том, что содержимое контейнера div заставит контейнер div растягиваться и быть фоном для содержимого. Но когда я это делаю, содержащий div сжимается, чтобы соответствовать неплавающим объектам, и плавающие объекты будут либо полностью, либо наполовину, наполовину и не будут иметь никакого отношения к размеру большого элемент div.

Почему это? Есть ли что-то, чего мне не хватает, и как я могу получить плавающие предметы, чтобы растянуть высоту содержащего div?

9 ответов


проще всего поставить overflow:hidden на родительском div и не указывайте высоту:

#parent { overflow: hidden }

другой способ-также плавать Родительский div:

#parent { float: left; width: 100% }

другой способ использует четкий элемента:

<div class="parent">
   <img class="floated_child" src="..." />
   <span class="clear"></span>
</div>

в CSS

span.clear { clear: left; display: block; }

причина

проблема в том, что плавающие элементы из-за потока:

элемент называется из потока если он плавает, абсолютно установленные или является корневым элементом.

следовательно, они не влияют на окружающие элементы, как in-flow элемент.

это объясняется в 9.5 поплавки:

С a float не находится в потоке, созданы непозиционные блок-боксы до и после поплавковой коробки поток вертикально, как если бы поплавок не существовать. Однако текущие и последующие поля строк, созданные рядом с поплавок укорочен по мере необходимости, чтобы освободить место для поля поплавка.

enter image description here

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

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 решение: зазор

путь разрешить проблему принуждает некоторый элемент в-подачи быть помещенным под всеми поплавками. Затем, высота родитель вырастет, чтобы обернуть этот элемент (и, следовательно, поплавки тоже).

этого можно достигнуть используя the clear свойства:

это свойство указывает, какие стороны поля элемента могут не быть рядом с более ранней плавающей коробкой.

enter image description here

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

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

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;
}

положите свой плавающий div(s) на div и в CSS дайте ему overflow:hidden;
все будет хорошо.


ничего не пропало. Float был разработан для случая, когда вы хотите, чтобы изображение (например) сидело рядом с несколькими абзацами текста, поэтому текст обтекает изображение. Этого не произойдет, если текст "растянет" контейнер. Ваш первый абзац закончится, а затем ваш следующий абзац начнется под изображением (возможно, несколькими сотнями пикселей ниже).

и именно поэтому вы получаете результат вы.


рекомендация W3Schools:

put overflow: auto на родительском элементе, и он будет "цвет" весь фон, включая поля элементов. Также плавающие элементы останутся внутри границы.

http://www.w3schools.com/css/tryit.asp?filename=trycss_layout_clearfix


В некоторых случаях, т. е. когда (если) вы просто используете float чтобы элементы текли по одной "линии", вы можете использовать

display: inline-block;

вместо

float: left;

в противном случае, используя clear элемент в конце работает, даже если он может идти против зерна, чтобы нужен элемент, чтобы сделать то, что должно быть работой CSS.


спасибо LSerni вы решили это за меня.

для достижения этого :

+-----------------------------------------+
| +-------+                     +-------+ |
| | Text1 |                     | Text1 | |
| +-------+                     +-------+ |
|+----------------------------------------+

вы должны сделать это:

<div style="overflow:auto">
    <div style="display:inline-block;float:left"> Text1 </div>
    <div style="display:inline-block;float:right"> Text2 </div>
</div>

вот более современный подход:

.parent {display: flow-root;} 

не более clearfixes.

p.s. Использование overflow: hidden; скрывает поле-тень так...


Как говорит Лукас, то, что вы описываете, является предполагаемым поведением для свойства float. Что смущает многих людей, так это то, что float был вытеснен далеко за пределы его первоначального предполагаемого использования, чтобы компенсировать недостатки в модели макета CSS.

посмотреть Floatutorial если вы хотите лучше понять, как работает это свойство.