Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Методи очищення CSS». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Методи очищення CSS** - прийоми, які змушують батьківський контейнер охоплювати плаваючі (float) дочірні елементи, що вийшли з нормального потоку. ```css /* Стандартний clearfix */ .container::after { content: ""; display: table; clear: both; } /* BFC без побічних ефектів (сучасний варіант) */ .container { display: flow-root; } ``` **Ключове:** Flexbox і Grid не потребують очищення - колапс висоти через float там не виникає.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**Методи очищення CSS** - прийоми, які змушують батьківський контейнер охоплювати дочірні плаваючі елементи (float) після того, як ті вийшли з нормального потоку документа. ## Теорія ### TL;DR - Float виводить елементи з нормального потоку, тому батько не враховує їх висоту і колапсує до 0 - Clearfix через `::after` - стандартне рішення для float-макетів - `overflow: hidden` створює BFC, але обрізає дочірні елементи з `position: absolute` - `display: flow-root` - чистий варіант без побічних ефектів - Flexbox і Grid цієї проблеми не мають взагалі ### Чому батько колапсує Коли застосовуєш `float: left` або `float: right` до дочірнього елемента, браузер виводить його з нормального потоку. Батько рахує висоту тільки по блокових елементах, що залишились у потоці. Float-елементи в цей розрахунок не потрапляють. Тому контейнер, де є тільки плаваючі діти, отримує `height: 0`. Нижче червона рамка рендериться як пряма лінія: ```css .container { border: 2px solid red; } .box { float: left; width: 100px; height: 100px; } ``` ```html <div class="container"> <div class="box"></div> <div class="box"></div> </div> <!-- Рамка - пряма лінія. Блоки виходять за межі. --> ``` ### Метод clearfix Найпоширеніший спосіб. Додаємо `::after` псевдоелемент до батька: ```css .clearfix::after { content: ""; display: table; clear: both; } ``` Клас ставиться на батька, не на плаваючі дочірні елементи: ```html <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 ```css .container { overflow: hidden; } ``` Будь-яке значення `overflow`, крім `visible`, створює новий контекст форматування блоку (block formatting context, BFC). BFC зобов'язаний містити свої float-нащадки, тому висота більше не колапсує. Зручно, але є ризик: `overflow: hidden` обрізає дочірні елементи з `position: absolute`, якщо ті виходять за межі контейнера. Баг з обрізаним тултіпом через це - класика старих кодових баз. Використовуй тільки коли точно знаєш, що нічого не має виходити за межі. ### display: flow-root ```css .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` на самому плаваючому елементі:** ```css .box { float: left; clear: both; } /* Батько все одно колапсує */ ``` `clear` каже елементу, де стати відносно попередніх float-елементів. Але плаваючий елемент вже виведений з потоку, і клірингування себе самого на висоту батька не впливає. Виправлення треба ставити на псевдоелемент батька або на сусідній елемент після плаваючих. **`overflow: hidden` коли є абсолютно позиціоновані діти:** ```css .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 там просто не виникає. ## Приклади ### Базовий: колапс батька і виправлення ```html <!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) ```html <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> ``` ```css .media::after { content: ""; display: table; clear: both; } ``` Саме такий патерн використовував Bootstrap 3 у компоненті `.media`. Без clearfix тег `<article>` колапсує до висоти тексту і картинка виходить за межі картки.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.