it-swarm.com.ru

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

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

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

241
DavidR

Самый простой - поместить 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; }
361
Doug Neiner

Причина

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

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

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

Это объясняется в 9.5 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>

Хакерское решение: оформление

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

Это может быть достигнуто с помощью свойство 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 высоты 'Авто' для корней контекста форматирования блока ,

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

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 Floats , корни 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.

Дисплей L решает следующие проблемы:

Созданы flow и flow-rootвнутренние типы отображения , чтобы лучше выразить макет потока типы отображения и создать явный переключатель для сделать элемент BFC root. (Это должно устранить необходимость в хакерских атаках, таких как ::after { clear: both; } и overflow: hidden […])

К сожалению, пока нет поддержки браузера. В конце концов мы сможем использовать

.bfc-root {
  display: flow-root;
}
140
Oriol

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

19
Nad

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

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

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

12
mggluscevic

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

И именно поэтому вы получаете результат, который вы есть.

11
Lucas Wilson-Richter

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

display: inline-block;

вместо

float: left;

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

8
LSerni

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

.parent {display: flow-root;} 

Нет больше исправлений.

постскриптум Использование переполнения: скрыто; скрывает коробку-тень так ...

7
pendingfox

Спасибо 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>
6
Flyout

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

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

4
Sam Murray-Sutton