Чому висота елемента контейнера не збільшується, якщо він містить плаваючі елементи?


210

Я хотів би запитати, як працюють висота і поплавок. У мене є зовнішній 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>



приємно і дуже добре дякую!
Bassam Alugili

Відповіді:


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? Спочатку 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 стовпців із заголовком, колонтитулом та 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;
}

Переходимо крок за кроком з компонуванням і подивимося, як працює флоат ..

Перш за все, ми використовуємо основний елемент обгортку, можна тільки припустити , що це ваше вікно перегляду, то ми використовуємо 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>

Демо

Ну, це виправляє дуже добре, більше не згорнувся батьків, але це додає непотрібну розмітку DOM, тому деякі пропонують використовувати overflow: hidden; на батьківському елементі, що містить плаваючі дочірні елементи, які працюють за призначенням.

Використовуйте overflow: hidden;на.wrapper

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

Демо

Це економить нам елемент кожен раз, коли нам потрібно, clear floatале, як я перевіряв різні випадки цього, це не вдалося в одному конкретному, який використовує box-shadowдочірні елементи.

Демо (не можна побачити тінь з усіх 4 сторін,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 Причина, чому додавання чіткого виправлення працює, тому що 1) clearfix є (як правило) у звичайному потоці 2) очищення плаває вимагає, щоб clearfix розміщувався в самому дні плавців 3) контейнер повинен бути розтягнутий, щоб містити цей clearfix.
BoltClock

@BoltClock було б краще, якщо ви відкажете редагування заголовка, оскільки це сильно вплине на seo для користувачів, які виявляють, як працює флоат. Ви можете написати ці терміни в Google і перевірити. не в змозі знайти те, що шукають.
Містер

"Як працює плаваючий CSS?" це надзвичайно широкий заголовок, і це також вводить людей в оману для голосування, щоб закрити будь-яке поплавкове питання як обдурення цього. Питання тут охоплює лише один аспект: контейнери, які обгортають (або не обгортають), плавають.
BoltClock

@BoltClock У будь-якому разі технічність залишається такою ж, як і в поясненні clear: both;, але це добре, якщо ви вважаєте, що редагування виправдовує, так що давайте продовжувати так
Містер

1
блискуча відповідь. "Плаваючи будь-яким елементом вліво або вправо, ширина елемента буде обмежена вмістом, який він містить, якщо ширина не визначена явно", - я спостерігав те саме, і просто шукав, щоб це було підтверджено. Дякую
Дін Джон,

38

Вам потрібно додати overflow:autoдо свого батьківського div, щоб він охоплював внутрішній плаваючий 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


6
це не є рішенням, ви приховуєте вміст, який виходить за межі зовнішнього діва.
Алехандро Руїз Аріас

@AlejandroRuizArias - Як саме щось приховується?
j08691

3
У цьому прикладі нічого, але якщо ви введете достатній вміст у внутрішній розділ, так.
Алехандро Руїс Аріяс

Це не те, що шукала ОП: Forked jsfiddle.net/h0ceb5ra
TecBrat

1
Дивовижно. Єдине рішення атрибутів, яке я шукав, якби все інше було таким простим, не було б потреби в скороченні.
YK

10

Ви стикаєтеся з плаваючою помилкою (хоча я не впевнений, чи технічно це помилка через те, скільки браузерів проявляє таку поведінку). Ось що відбувається:

За звичайних обставин, якщо припустити, що не встановлена ​​явна висота, елемент рівня блоку, такий як div, встановить свою висоту залежно від вмісту. Дно батьківського діла буде виходити за межі останнього елемента. На жаль, плаваючий елемент заважає батькові враховувати плаваючий елемент при визначенні його висоти. Це означає, що якщо ваш останній елемент плаває, він не буде "розтягувати" батьківський шлях так само, як і звичайний елемент.

Розмитнення

Є два поширених способи виправити це. Перший - додати елемент "очищення"; тобто ще один елемент нижче плаваючого, який змусить батьків розтягнутись. Тому додайте наступний html як останню дочірню:

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

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

Переповнення:

Другий метод, який більшість людей вважають за краще (я думаю) - це змінити CSS батьківського елемента, щоб переповнення було чим-небудь, але "видимим". Тож встановлення переливу на "приховане" змусить батьків витягнутись за дно плаваючої дитини. Це справедливо лише в тому випадку, якщо ви, звичайно, не встановили висоту для батьків.

Як я вже сказав, другий метод є кращим, оскільки він не вимагає від вас додавати і додавати до своєї розмітки семантично безглузді елементи, але бувають випадки, коли вам потрібно overflowбути видимим, і в цьому випадку додавання елемента очищення є більш ніж прийнятним .


3

Це через поплавок діву. Додайте 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>

Демо


3

Ви плутаєте, як веб-переглядачі відображають елементи, коли є плаваючі елементи. Якщо один елемент блоку плаває (ваш внутрішній діл у вашому випадку), інші елементи блоку будуть ігнорувати його, оскільки браузер видаляє плаваючі елементи зі звичайного потоку веб-сторінки. Потім, оскільки плаваючий 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
Не виділяйте текст і не діліться скрипковими посиланнями, поштовими кодами у своїй відповіді наступного разу, адже якщо скрипкове посилання померло, майбутній користувач тут не отримає ніякої допомоги, а ваша відповідь не матиме жодного значення
містер Чужий


1

ви можете використовувати властивість переповнення до контейнера 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;
    }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.