EasyCode365EasyCode365

Плаваючі елементи і clearfix

Floats — це старіша можливість CSS, але її все ще варто знати.

Сьогодні для повних layout сторінки зазвичай краще використовувати Flexbox або Grid. Floats усе ще корисні для однієї класичної задачі: розмістити зображення або маленький блок поруч із текстом, щоб текст його обтікав.

У цьому уроці ти дізнаєшся, як працюють floats, чому вони можуть ламати батьківські контейнери, і як clear та clearfixes розв'язують типові проблеми з floats.

Навіщо існують floats

Floats створили для layout у стилі журналів.

Початкова ідея була проста: поставити зображення ліворуч або праворуч від статті, а текст абзацу мав обтікати його.

До появи Flexbox і Grid розробники також використовували floats для колонок і layout сторінок. Це працювало, але часто створювало проблеми з layout.

Що робить float

Властивість float переміщує елемент до лівого або правого боку його контейнера.

Контент, який іде після плаваючого елемента, може піднятися і обтікати його.

Поширені значення:

  • float: left
  • float: right
  • float: none

Плаваючі елементи прибираються зі звичайного block flow, але текст і inline-контент усе ще обтікають їх. Саме ця особлива поведінка робить floats корисними.

Float ліворуч і праворуч

Використовуй float: left, щоб притиснути елемент ліворуч.

Використовуй float: right, щоб притиснути елемент праворуч.

Лише читання

Коли елемент плаває ліворуч, близький текст може обтікати його з правого боку. Коли елемент плаває праворуч, близький текст може обтікати його з лівого боку.

Як текст обтікає плаваючі елементи

Це найзрозуміліший випадок використання floats для початківців.

Блок зображення плаває ліворуч, а текст абзацу обтікає його.

Можна редагувати
<article class="article">
  <div class="article-image">Зображення</div>
  <p>
    Цей текст іде після плаваючого зображення. Оскільки зображення плаває ліворуч, абзац
    піднімається і обтікає його правий бік. Це класичний випадок використання CSS floats. Додай
    більше тексту, і ти побачиш, що текст продовжує йти поруч із зображенням, доки поруч із ним є
    вертикальний простір. Коли текст проходить нижче плаваючого зображення, він повертається до
    звичайного рядка на всю ширину нижче.
  </p>
</article>

<style>
  .article {
    max-width: 420px;
    font-family: Arial, sans-serif;
    line-height: 1.5;
  }

  .article-image {
    float: left;
    width: 110px;
    height: 90px;
    margin-right: 16px;
    margin-bottom: 8px;
    display: grid;
    place-items: center;
    background-color: #dbeafe;
    border: 2px solid #2563eb;
    border-radius: 6px;
    color: #1e40af;
    font-weight: bold;
  }
</style>

margin-right створює простір між плаваючим блоком і текстом.

Колапс висоти батьківського елемента

Floats можуть створити заплутану проблему.

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

Можна редагувати
<div class="broken-parent">
  <div class="float-box">Float</div>
</div>

<p class="after-text">Цей текст піднімається, бо батьківський елемент не обгорнув float.</p>

<style>
  .broken-parent {
    border: 3px solid #dc2626;
    background-color: #fee2e2;
    font-family: Arial, sans-serif;
  }

  .float-box {
    float: left;
    width: 120px;
    padding: 20px;
    background-color: #fecaca;
    border: 2px solid #991b1b;
    text-align: center;
  }

  .after-text {
    font-family: Arial, sans-serif;
  }
</style>

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

Що робить clear

Властивість clear каже елементу не ставати поруч із плаваючим елементом.

Замість цього cleared-елемент переходить нижче float.

Можна редагувати
<div class="side-note">Float</div>

<p class="wrap-text">Цей абзац обтікає плаваючий блок.</p>

<p class="cleared-text">Цей абзац має clear, тому починається нижче плаваючого блока.</p>

<style>
  .side-note {
    float: left;
    width: 110px;
    padding: 18px;
    margin-right: 12px;
    background-color: #fef3c7;
    border: 2px solid #d97706;
    font-family: Arial, sans-serif;
    text-align: center;
  }

  .wrap-text,
  .cleared-text {
    font-family: Arial, sans-serif;
  }

  .cleared-text {
    clear: both;
    padding-top: 8px;
  }
</style>

Використовуй clear, коли наступний елемент має починатися нижче плаваючого контенту.

Очищення ліворуч, праворуч і з обох боків

Властивість clear має три поширені значення:

  • clear: left переходить нижче елементів, що плавають ліворуч.
  • clear: right переходить нижче елементів, що плавають праворуч.
  • clear: both переходить нижче floats ліворуч і праворуч.

Для початківців clear: both зазвичай найбезпечніший вибір.

Як зробити, щоб батьківський елемент містив свої floats

Коли батьківський елемент містить лише плаваючих дітей, потрібен спосіб змусити його обгорнути їх і виправити проблему колапсу висоти.

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

  • display: flow-root — сучасний підхід в один рядок.
  • Clearfix — старіша техніка з псевдоелементом ::after.

Наступні дві секції показують обидва варіанти.

Сучасна техніка: display: flow-root

Найчистіший сучасний спосіб змусити батьківський елемент обгорнути своїх плаваючих дітей — один рядок: display: flow-root на батьківському елементі.

Він створює новий block formatting context, який містить floats. Немає псевдоелемента і немає додаткових правил для запам'ятовування.

Можна редагувати
<div class="fixed-parent">
  <div class="float-box">Float</div>
</div>

<p class="after-text">
  Тепер батьківський елемент обгортає float, тому цей текст починається нижче.
</p>

<style>
  .fixed-parent {
    display: flow-root;
    border: 3px solid #16a34a;
    background-color: #dcfce7;
    font-family: Arial, sans-serif;
  }

  .float-box {
    float: left;
    width: 120px;
    padding: 20px;
    background-color: #bbf7d0;
    border: 2px solid #15803d;
    text-align: center;
  }

  .after-text {
    font-family: Arial, sans-serif;
  }
</style>

display: flow-root підтримується всіма сучасними браузерами, тому це рекомендований вибір для нових проєктів.

Класичний clearfix

У багатьох наявних codebases ти все ще побачиш старішу техніку. Clearfix використовує псевдоелемент ::after, щоб створити невидимий елемент після плаваючих дітей і очистити floats.

Можна редагувати
<div class="fixed-parent clearfix">
  <div class="float-box">Float</div>
</div>

<p class="after-text">Clearfix також змушує батьківський елемент обгорнути float.</p>

<style>
  .fixed-parent {
    border: 3px solid #16a34a;
    background-color: #dcfce7;
    font-family: Arial, sans-serif;
  }

  .float-box {
    float: left;
    width: 120px;
    padding: 20px;
    background-color: #bbf7d0;
    border: 2px solid #15803d;
    text-align: center;
  }

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

  .after-text {
    font-family: Arial, sans-serif;
  }
</style>

Корисно впізнавати цей патерн, але для нового коду display: flow-root простіший.

Коли floats усе ще корисні сьогодні

Floats усе ще корисні, коли потрібно, щоб текст обтікав щось.

Хороші приклади:

  • зображення всередині статті
  • маленьке фото автора поруч із біографією
  • виділена цитата всередині довгого абзацу

Для такого обтікання текстом floats усе ще мають сенс.

Коли не використовувати floats

Не використовуй floats для сучасного layout усієї сторінки.

Уникай floats для:

  • колонок сторінки
  • headers і sidebars
  • grids карток
  • layout застосунків

Для таких layouts використовуй Flexbox або Grid. Ними легше керувати, і вони краще працюють на responsive екранах.

Поширені помилки початківців

  • Використовувати floats для сучасного layout сторінки: використовуй Flexbox або Grid для структурних layouts.
  • Забувати очистити наступну секцію: текст або footers можуть обтікати float, коли ти хотів бачити їх нижче.
  • Ставити clearfix на плаваючий дочірній елемент: clearfix належить батьківському контейнеру.
  • Забувати про колапс висоти батьківського елемента: батько лише з плаваючими дітьми може виглядати порожнім.
  • Float без відступів: додавай margins, щоб текст не торкався плаваючого елемента.

Мініпрактика

Подивись на це CSS-правило:

Лише читання

Що це правило робить із footer?

Перевір відповіді у quiz, коли будеш готовий.

Короткий quiz з відповідями

  1. Який класичний випадок використання floats?
  2. Яка CSS-властивість змушує елемент перейти нижче плаваючого контенту?
  3. Де має застосовуватися клас clearfix: на плаваючому дочірньому елементі чи на батьківському?

Відповіді:

  1. Обтікання текстом зображення або маленького елемента.
  2. clear.
  3. На батьківському елементі.

Відповідь на мініпрактику: це змушує footer перейти нижче лівих і правих floats, замість того щоб стояти поруч із ними.

Невеликий виклик

Стилізуй layout статті нижче.

Твої цілі:

  • Зроби .profile-pic float праворуч.
  • Додай лівий margin, щоб текст не торкався плаваючого блока.
  • Використай clear на .next-section, щоб вона починалася нижче float.
Можна редагувати
<article class="bio">
  <div class="profile-pic">Фото</div>
  <p>Ця коротка біографія має обтікати фото. Фото має бути праворуч від тексту.</p>
</article>

<section class="next-section">
  <h3>Наступна секція</h3>
  <p>Ця секція має починатися нижче плаваючого фото.</p>
</section>

<style>
  .bio,
  .next-section {
    max-width: 420px;
    font-family: Arial, sans-serif;
    line-height: 1.5;
  }

  .profile-pic {
    width: 100px;
    height: 90px;
    display: grid;
    place-items: center;
    background-color: #dbeafe;
    border: 2px solid #2563eb;
    border-radius: 6px;
    color: #1e40af;
    font-weight: bold;
    /* Зроби цей блок float праворуч */

    /* Додай лівий margin */
  }

  .next-section {
    /* Перемісти цю секцію нижче float */

    margin-top: 16px;
    padding: 12px;
    background-color: #f3f4f6;
    border: 1px solid #d1d5db;
  }
</style>

Підсумок

  • float: left і float: right переміщують елементи в боки.
  • Текст і inline-контент можуть обтікати плаваючі елементи.
  • Історично floats використовували для layout, але сьогодні вони найкраще підходять для обтікання текстом.
  • Плаваючі елементи можуть спричиняти колапс висоти батьківського елемента.
  • clear не дає елементу стати поруч із плаваючим контентом.
  • clear: both переміщує елемент нижче лівих і правих floats.
  • display: flow-root на батьківському елементі — сучасний спосіб змусити його обгорнути плаваючих дітей.
  • Clearfix з ::after — старіша техніка для тієї самої задачі.
  • Для сучасних layout сторінки використовуй Flexbox або Grid замість floats.