Почему высота элемента контейнера не увеличивается, если он содержит плавающие элементы?

211

Я хотел бы спросить, как работают высота и поплавок. У меня есть внешний div и внутренний div, в котором есть содержание. Его высота может варьироваться в зависимости от содержимого внутреннего блока, но кажется, что мой внутренний блок переполнит его внешний блок. Каков был бы правильный способ сделать это?

 <html>
    <body>
        <div style="margin:0 auto;width: 960px; min-height: 100px; background-color:orange">
    	    <div style="width:500px; height:200px; background-color:black; float:right"></div>
        </div>
    </body>
</html>

Бой Пасмо
источник
приятно и очень хорошо спасибо!
Бассам Алугили

Ответы:

581

Плавающие элементы не увеличивают высоту элемента контейнера, и поэтому, если вы их не очистите, высота контейнера не увеличится ...

Я покажу вам визуально:

введите описание изображения здесь

введите описание изображения здесь

введите описание изображения здесь

Более объяснение:

<div>
  <div style="float: left;"></div>
  <div style="width: 15px;"></div> <!-- This will shift 
                                        besides the top div. Why? Because of the top div 
                                        is floated left, making the 
                                        rest of the space blank -->

  <div style="clear: both;"></div> 
  <!-- Now in order to prevent the next div from floating beside the top ones, 
       we use `clear: both;`. This is like a wall, so now none of the div's 
       will be floated after this point. The container height will now also include the 
       height of these floated divs -->
  <div></div>
</div>

Вы также можете добавить overflow: hidden;элементы контейнера, но я бы предложил вам использоватьclear: both; вместо этого.

Также, если вы хотите очистить элемент, вы можете использовать

.self_clear:after {
  content: "";
  clear: both;
  display: table;
}

Как работает CSS Float?

Что такое поплавок и что он делает?

  • floatСвойство понято большинство начинающих. Ну, что именно делает float? Первоначально floatсвойство было введено для обтекания текста вокруг изображений, которые плавают leftили right.Вот еще одно объяснение @Madara Uchicha.

    Итак, неправильно ли использовать floatсвойство для размещения боксов рядом? Ответ - нет ; Нет проблем, если вы используете floatсвойство для установки боксов рядом.

  • Плавающий элемент inlineили blockуровень заставит элемент вести себя как inline-blockэлемент.

    демонстрация

  • Если вы перемещаете элемент leftили right, widthэлемент элемента будет ограничен содержимым, которое он содержит, если widthне определено явно ...

  • Вы не можете floatэлемент center. Это самая большая проблема, которую я всегда видел у новичков, использующих float: center;, что не является допустимым значением floatсвойства. floatобычно используется для floatперемещения / перемещения контента влево или вправо . Есть только четыре допустимых значений для floatсвойств , т.е. left, right, none( по умолчанию) и inherit.

  • Родительский элемент сворачивается, когда он содержит всплывающие дочерние элементы, чтобы предотвратить это, мы используем clear: both;свойство, чтобы очистить всплывающие элементы с обеих сторон, что предотвратит сворачивание родительского элемента. Для получения дополнительной информации, вы можете сослаться на мой другой ответ здесь .

  • (Важно) Подумайте об этом, когда у нас есть стек различных элементов. Когда мы используем float: left;или float: right;элемент перемещается над стеком на единицу. Следовательно, элементы в нормальном потоке документов будут скрываться за плавающими элементами, потому что он находится на уровне стека выше обычных плавающих элементов. (Пожалуйста, не связывайте это с тем, z-indexчто это совершенно другое.)


В качестве примера рассмотрим пример работы CSS-плавающих элементов. Предположим, нам нужен простой макет из 2 столбцов с верхним и нижним колонтитулами и двумя столбцами, поэтому вот как выглядит план ...

введите описание изображения здесь

В приведенном выше примере, мы будем плавающей только красные коробки, либо вы можете floatкак к left, или вы можете floatна left, и другое , rightа также, в зависимости от расположения, если это 3 колонки, вы можете float2 колонки к leftгде другой один к rightтакому зависит, хотя в этом примере у нас есть упрощенная 2-колоночная компоновка, так что будет floatодин к, leftа другой кright .

Разметка и стили для создания макета объяснены ниже ...

<div class="main_wrap">
    <header>Header</header>
    <div class="wrapper clear">
        <div class="floated_left">
            This<br />
            is<br />
            just<br />
            a<br />
            left<br />
            floated<br />
            column<br />
        </div>
        <div class="floated_right">
            This<br />
            is<br />
            just<br />
            a<br />
            right<br />
            floated<br />
            column<br />
        </div>
    </div>
    <footer>Footer</footer>
</div>

* {
    -moz-box-sizing: border-box;       /* Just for demo purpose */
    -webkkit-box-sizing: border-box;   /* Just for demo purpose */
    box-sizing: border-box;            /* Just for demo purpose */
    margin: 0;
    padding: 0;
}

.main_wrap {
    margin: 20px;
    border: 3px solid black;
    width: 520px;
}

header, footer {
    height: 50px;
    border: 3px solid silver;
    text-align: center;
    line-height: 50px;
}

.wrapper {
    border: 3px solid green;
}

.floated_left {
    float: left;
    width: 200px;
    border: 3px solid red;
}

.floated_right {
    float: right;
    width: 300px;
    border: 3px solid red;
}

.clear:after {
    clear: both;
    content: "";
    display: table;
}

Давайте пошагово рассмотрим макет и посмотрим, как работает float.

Прежде всего, мы используем основной элемент обертку, можно только предположить , что это ваше окно просмотра, то мы используем headerи назначить heightиз 50pxтак ничего фантазии там. Это просто обычный элемент уровня блока без плавающего, который будет занимать 100%горизонтальное пространство, если он не является плавающим или мы не присвоим inline-blockему.

Первое допустимое значение для float- это leftтак, в нашем примере мы используем float: left;для .floated_left, поэтому мы намереваемся переместить блок в leftнаш контейнерный элемент.

Колонна плыла влево

И да, если вы видите, родительский элемент, который .wrapperсвернут, тот, который вы видите с зеленой рамкой, не расширился, но должен ли это быть? Вернемся к этому через некоторое время, а пока у нас есть колонка left.

Подойдя ко второму столбцу, пусть это floatкright

Еще один столбец всплыл направо

Здесь мы имеем 300pxширокий столбец , который мы floatк right, который будет сидеть рядом с первой колонке , как это поплыл к left, и так как он плавал к left, он создал пустой желобок к right, и так как там было достаточно места на right, наш rightплавающий элемент сидел идеально рядом с leftодним.

Тем не менее, родительский элемент свернут, давайте исправим это сейчас. Есть много способов предотвратить сворачивание родительского элемента.

  • Добавьте пустой элемент уровня блока и используйте clear: both;до окончания родительского элемента, который содержит плавающие элементы, теперь это дешевое решение для clearваших плавающих элементов, которое выполнит работу за вас, но я бы рекомендовал не использовать это.

Добавить <div style="clear: both;"></div>до .wrapper divконца, как

<div class="wrapper clear">
    <!-- Floated columns -->
    <div style="clear: both;"></div>
</div>

демонстрация

Что ж, это исправляет очень хорошо, больше не свернутый overflow: hidden;родительский элемент , но он добавляет ненужную разметку в DOM, поэтому некоторые предлагают использовать для родительского элемента, содержащего плавающие дочерние элементы, которые работают как задумано.

Использовать overflow: hidden;на.wrapper

.wrapper {
    border: 3px solid green;
    overflow: hidden;
}

демонстрация

Это экономит нам элемент каждый раз, когда нам нужно, clear floatно, поскольку я тестировал различные случаи с этим, он потерпел неудачу в одном конкретном случае, который использует box-shadowдочерние элементы.

Демо (не вижу тени со всех четырех сторон,overflow: hidden; вызывает эту проблему)

И что теперь? Сохраните элемент, нет, overflow: hidden;так что используйте хак для ясного исправления, используйте приведенный ниже фрагмент кода в своем CSS, и точно так же, как вы используете overflow: hidden;для родительского элемента, вызовите classниже для родительского элемента для самоочищения.

.clear:after {
    clear: both;
    content: "";
    display: table;
}

<div class="wrapper clear">
    <!-- Floated Elements -->
</div>

демонстрация

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

И, наконец, мы используем нижний колонтитул после того, как мы clearиспользовали плавающие элементы.

демонстрация


Когда float: none;используется в любом случае, как это по умолчанию, так что любое использование для объявления float: none;?

Ну, это зависит от того, хотите ли вы использовать адаптивный дизайн, вы будете использовать это значение много раз, когда хотите, чтобы ваши плавающие элементы отображались один под другим с определенным разрешением. Для этогоfloat: none; свойства играет важную роль там.


Несколько реальных примеров того, как floatэто полезно.

  • Первый пример, который мы уже видели, - это создание одного или нескольких макетов столбцов.
  • Использование imgплавающего внутри, pчто позволит нашему контенту обтекать.

Демо (без плавающихimg)

Демо 2 (imgвсплыл наleft)

  • Использование floatдля создания горизонтального меню - Демо

Также поплавайте второй элемент или используйте `margin`

И последнее, но не менее важное, я хочу объяснить этот конкретный случай, когда вы floatтолько один элемент, leftно вы неfloat другой - нет, так что же происходит?

Предположим, что если мы удалим float: right;из нашего .floated_right class, то divрендеринг будет экстремальным, leftпоскольку он не является плавающим.

демонстрация

Таким образом , в данном случае, либо вы можете floatк leftа

ИЛИ

Вы можете использовать, margin-leftкоторый будет равен размеру левого плавающего столбца, т.е. 200pxширокий .

Мистер инопланетянин
источник
3
Тот факт, что числа с плавающей запятой не влияют на высоту родительского уровня, явно указан здесь в спецификации: w3.org/TR/CSS21/visudet.html#normal-block . Причина, по которой добавление clearfix работает, заключается в том, что 1) clearfix (обычно) находится в нормальном потоке 2) очистка поплавков требует, чтобы clearfix был размещен в самом низу поплавков 3) контейнер должен быть растянут для содержания этого clearfix.
BoltClock
@BoltClock было бы лучше, если вы откатите редактирование заголовка, так как это серьезно повлияет на SEO для пользователей, которые находят, как работает float. Вы можете написать эти термины в Google и проверить ... иначе этот канонический ответ бесполезен, если люди не в состоянии найти то, что они ищут.
Мистер Чужой
"Как работает CSS float?" Это чрезвычайно широкое название, и оно также вводит людей в заблуждение, чтобы они закрыли любой вопрос с плавающей точкой, как обман этого вопроса . Вопрос здесь охватывает только один аспект: обертывание контейнеров (или не обертывание) float.
BoltClock
@BoltClock В любом случае техническая часть остается такой же, как объяснено в clear: both;, но это хорошо, если вы чувствуете, что редактирование оправдывает себя, поэтому давайте продолжим
Mr. Alien
1
блестящий ответ. «Плавая любой элемент влево или вправо, ширина элемента будет ограничена содержимым, которое он содержит, если ширина не определена явно» - я заметил то же самое и просто искал это, чтобы подтвердить. Спасибо
Дин Джон
38

Вам нужно добавить overflow:autoк вашему родительскому div, чтобы он охватывал внутренний float div:

<div style="margin:0 auto;width: 960px; min-height: 100px; background-color:orange;overflow:auto">
    <div style="width:500px; height:200px; background-color:black; float:right">
    </div>
</div>

Пример jsFiddle

j08691
источник
6
это не решение, вы скрываете контент, который выходит за пределы внешнего div.
Алехандро Руис Ариас
@AlejandroRuizArias - Как именно что-то скрывается?
j08691
3
В этом примере ничего нет, но если вы введете достаточно контента во внутренний div, то да.
Алехандро Руис Ариас
Это не делает то, что искал ОП: Раздвоенный jsfiddle.net/h0ceb5ra
TecBrat
1
Потрясающие. Единственное атрибутивное решение, которое я искал, если бы все остальное было так просто, не было бы необходимости в сжатии.
YK
10

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

При нормальных обстоятельствах, предполагая, что явная высота не была установлена, элемент уровня блока, такой как div, будет устанавливать свою высоту на основе своего содержимого. Нижняя часть родительского div будет выходить за пределы последнего элемента. К сожалению, плавающий элемент мешает родительскому элементу учитывать плавающий элемент при определении его высоты. Это означает, что если ваш последний элемент является плавающим, он не будет «растягивать» родительский элемент так же, как обычный элемент.

клиринг

Есть два распространенных способа исправить это. Во-первых, добавить элемент «очистки»; то есть еще один элемент ниже плавающего, который заставит родителя растягиваться. Поэтому добавьте следующий html как последний дочерний элемент:

<div style="clear:both"></div>

Он не должен быть видимым, и используя clear: both, вы убедитесь, что он будет располагаться не рядом с плавающим элементом, а после него.

Переполнение:

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

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

Maloric
источник
3

Это из-за плавания div. Добавьте overflow: hiddenна внешний элемент.

<div style="overflow:hidden; margin:0 auto;width: 960px; min-height: 100px; background-color:orange;">
    <div style="width:500px; height:200px; background-color:black; float:right">
    </div>
</div>

демонстрация

Starx
источник
3

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

Другими словами, блочные элементы (заголовки, абзацы, div и т. Д.) Игнорируют плавающие элементы и заполняют, а встроенные элементы (изображения, ссылки, текст и т. Д.) Учитывают границы плавающих элементов.

Пример скрипки здесь

<body>
    <div style="float:right; background-color:blue;width:200px;min-height:400px;margin-right:20px">
           floating element
    </div>
    <h1 style="background-color:red;"> this is a big header</h1>
    <p style="background-color:green"> this is a parragraph with text and a big image. The text places arrounds the floating element. Because of the image is wider than space between paragrah and floating element places down the floating element. Try to make wider the viewport and see what happens :D
        <img src="http://2.bp.blogspot.com/_nKxzQGcCLtQ/TBYPAJ6xM4I/AAAAAAAAAC8/lG6XemOXosU/s1600/css.png">
     </p>
Алехандро Руис Ариас
источник
3
Не выделяйте текст и не делитесь ссылками на скрипку, постируйте коды в своем ответе в следующий раз, потому что, если ссылка на скрипку не работает, будущий пользователь не получит никакой помощи, и ваш ответ не будет иметь никакого значения
Mr. Alien
2

Попробуй это

.parent_div{
    display: flex;
}
Yusufbek
источник
1

вы можете использовать свойство overflow для контейнера div, если у вас нет div для показа поверх контейнера, например:

<div class="cointainer">
    <div class="one">Content One</div>
    <div class="two">Content Two</div>
</div>

Вот следующий CSS:

.container{
    width:100%;/* As per your requirment */
    height:auto;
    float:left;
    overflow:hidden;
}
.one{
    width:200px;/* As per your requirment */
    height:auto;
    float:left;
}

.two{
    width:200px;/* As per your requirment */
    height:auto;
    float:left;
}

-----------------------ИЛИ-------------------------- ----

    <div class="cointainer">
        <div class="one">Content One</div>
        <div class="two">Content Two</div>
        <div class="clearfix"></div>
    </div>

Вот следующий CSS:

    .container{
        width:100%;/* As per your requirment */
        height:auto;
        float:left;
        overflow:hidden;
    }
    .one{
        width:200px;/* As per your requirment */
        height:auto;
        float:left;
    }

    .two{
        width:200px;/* As per your requirment */
        height:auto;
        float:left;
    }
    .clearfix:before,
    .clearfix:after{
        display: table;
        content: " ";
    }
    .clearfix:after{
        clear: both;
    }
Нишант Рана
источник