Методи очищення CSS
Методи очищення CSS - прийоми, які змушують батьківський контейнер охоплювати дочірні плаваючі елементи (float) після того, як ті вийшли з нормального потоку документа.
Теорія
TL;DR
- Float виводить елементи з нормального потоку, тому батько не враховує їх висоту і колапсує до 0
- Clearfix через
::after- стандартне рішення для float-макетів overflow: hiddenстворює BFC, але обрізає дочірні елементи зposition: absolutedisplay: flow-root- чистий варіант без побічних ефектів- Flexbox і Grid цієї проблеми не мають взагалі
Чому батько колапсує
Коли застосовуєш float: left або float: right до дочірнього елемента, браузер виводить його з нормального потоку. Батько рахує висоту тільки по блокових елементах, що залишились у потоці. Float-елементи в цей розрахунок не потрапляють. Тому контейнер, де є тільки плаваючі діти, отримує height: 0.
Нижче червона рамка рендериться як пряма лінія:
.container { border: 2px solid red; }
.box { float: left; width: 100px; height: 100px; }<div class="container">
<div class="box"></div>
<div class="box"></div>
</div>
<!-- Рамка - пряма лінія. Блоки виходять за межі. -->Метод clearfix
Найпоширеніший спосіб. Додаємо ::after псевдоелемент до батька:
.clearfix::after {
content: "";
display: table;
clear: both;
}Клас ставиться на батька, не на плаваючі дочірні елементи:
<div class="container clearfix">
<div class="box" style="float: left;"></div>
<div class="box" style="float: left;"></div>
</div>clear: both позиціонує псевдоелемент нижче за всі попередні float-елементи. Батько змушений включити його у висоту. Жодного зайвого HTML. Bootstrap 3 і 4 використовували саме такий підхід у навбарах і медіа-компонентах.
Важливо не плутати: clear - це CSS-властивість, clearfix - назва техніки, яка використовує clear всередині псевдоелемента. Це різні речі.
Метод overflow
.container { overflow: hidden; }Будь-яке значення overflow, крім visible, створює новий контекст форматування блоку (block formatting context, BFC). BFC зобов'язаний містити свої float-нащадки, тому висота більше не колапсує. Зручно, але є ризик: overflow: hidden обрізає дочірні елементи з position: absolute, якщо ті виходять за межі контейнера. Баг з обрізаним тултіпом через це - класика старих кодових баз. Використовуй тільки коли точно знаєш, що нічого не має виходити за межі.
display: flow-root
.container { display: flow-root; }Створює BFC без побічних ефектів. Без обрізання, без скролбарів, без псевдоелементів. Підтримується всіма сучасними браузерами з 2018 року. Якщо пишеш новий код з float (HTML-листи для розсилок, наприклад), це правильний вибір.
Коли що використовувати
- Підтримка Bootstrap 3/4 або старих WordPress-тем: clearfix вже є в проекті, залишай його
- Швидке виправлення і немає абсолютно позиціонованих дітей:
overflow: hidden - Новий код з float (email-розсилки):
display: flow-root - Нові макети: відмовся від float і використовуй Flexbox або Grid
Типові помилки
clear: both на самому плаваючому елементі:
.box { float: left; clear: both; } /* Батько все одно колапсує */clear каже елементу, де стати відносно попередніх float-елементів. Але плаваючий елемент вже виведений з потоку, і клірингування себе самого на висоту батька не впливає. Виправлення треба ставити на псевдоелемент батька або на сусідній елемент після плаваючих.
overflow: hidden коли є абсолютно позиціоновані діти:
.container { overflow: hidden; position: relative; }
/* Дропдаун або тултіп з position: absolute буде обрізаний */Класичний баг у старих проектах. Clearfix або flow-root вирішують це без обрізання.
Clearfix на inline-елементі:
display: table всередині ::after вимагає блокового контексту батька. Якщо батько має display: inline, псевдоелемент поводитиметься неправильно і макет ламається без жодних помилок у консолі. Clearfix ставиться тільки на блокові елементи.
Follow-up питання
Q: Що таке block formatting context (BFC) і як clearing пов'язаний з ним?
A: BFC - ізольована область розмітки, де float-елементи містяться всередині, а відступи не виходять назовні. overflow: hidden і display: flow-root створюють BFC, змушуючи контейнер враховувати висоту float-дітей. Clearfix діє інакше: вставляє блок після float-елементів, що опускає нижній край батька.
Q: Чому display: table використовується в clearfix ::after?
A: display: table генерує блоковий бокс, на який діє clear: both. Цей бокс позиціонується нижче за всі попередні float-елементи. Бонус - він також запобігає злиттю відступів (margin collapse) між псевдоелементом і дочірніми елементами.
Q: clearfix чи display: flow-root - що обирати?
A: flow-root чистіший і не має побічних ефектів. Clearfix потрібен тільки при підтримці старого коду, де він вже використовується, або для браузерів до 2018 року.
Q: Чи працює clearfix всередині flex-контейнера?
A: Ні. Всередині Flexbox float-елементи ігноруються, тому clearfix немає що очищати. Проблеми з колапсом висоти через float там просто не виникає.
Приклади
Базовий: колапс батька і виправлення
<!DOCTYPE html>
<html>
<head>
<style>
.container { border: 2px solid red; margin-bottom: 20px; }
.box { float: left; width: 80px; height: 80px; background: steelblue; margin: 8px; }
.clearfix::after { content: ""; display: table; clear: both; }
</style>
</head>
<body>
<!-- Зламано: рамка колапсує в лінію -->
<div class="container">
<div class="box"></div>
<div class="box"></div>
</div>
<!-- Виправлено: рамка охоплює обидва блоки -->
<div class="container clearfix">
<div class="box"></div>
<div class="box"></div>
</div>
</body>
</html>Перший контейнер - плоска червона лінія. Другий охоплює блоки повністю. Різниця тільки в класі clearfix на батьку.
Реальний кейс: медіа-об'єкт (патерн Bootstrap 3)
<article class="media clearfix">
<img src="avatar.jpg" style="float: left; width: 64px; margin-right: 12px;">
<div class="media-body">
<h4>Заголовок поста</h4>
<p>Текст розташовується поряд з картинкою. Висота батька підлаштовується автоматично.</p>
</div>
</article>.media::after {
content: "";
display: table;
clear: both;
}Саме такий патерн використовував Bootstrap 3 у компоненті .media. Без clearfix тег <article> колапсує до висоти тексту і картинка виходить за межі картки.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.