Очищення плаваючих елементів: огляд різних методів clearfix

1

Від автора: Очищення плаваючих елементів довго була найпоширенішою необхідністю у фронт-енд розробці. Не дивно, що протягом декількох років нам було надано безліч технік, відомих як методи clearfix. До того, як ми поглибимося у різні методи, давайте подивимося на саму проблему, яку метод clearfix покликаний вирішувати.

Сценарій: .el-1 та .el-2 – елементи, плаваючі пліч-о-пліч всередині контейнера, а також є елемент .main після елемента .container

Бажаний результат: Ми хочемо, щоб .container розкривався до висоти своїх дочірніх елементів (тобто до найвищого з двох .el-1 та .el-2), і ми хочемо, щоб елемент .main був після .container.

Дійсний результат: .container згортається і не має висоти взагалі, як ніби всередині нічого немає, що ставить .main на небажану позицію і потенційно змушує зникнути фонові зображення і межі, задані елементу .container.

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

A long string of stuff here…
A short string of stuff here…
Some stuff here…

Тоді наш CSS-код буде виглядати ось так:

.el-1, .el-2 {
float: left;
width: 50%;
}
.el-1 {
/* стилі для класу .el-1*/
}
.el-2 {
/* стилі для класу .el-2 */
}
.main {
/* стилі для класу .main */
}

Нарешті, результат показаний на демо нижче:

Дивлячись на демо і подивившись на CSS код елемента .container, ви побачите, що він і справді згорнувся. Ви можете побачити шматочок чорної кордону нагорі, і немає навіть натяку на колір фону. Значить, він не розширюється для того, щоб поміщати .el-1 та .el-2, дозволяючи елементу .main переміститися в несподіване місце ( у нашому випадку під елемент .el-2).

Незважаючи на те, що багато хто вважає це багом браузера або неправильної імплементацією властивості float. Це всього лише принцип, за яким працюють плаваючі елементи. Хоча в процесі розробки, у багатьох випадках для нас він є небажаним результатом. Що ставить для нас просту задачу – необхідність «очищати плаваючі елементи».

Очищення плаваючих елементів (або clearfix) покликане змусити батьківський елемент розширюватися, щоб повністю вміщати дочірні елементи. Таким чином, наступні елементи будуть йти під контейнером. Протягом декількох років, для досягнення цієї мети з’являлися різні методи. Перш ніж ми звернемося до цих методів, давайте уважніше розглянемо CSS властивість clear, яке є основною можливістю CSS для вирішення цієї задачі.

Властивість «clear»

MDN визначає clear як:

Властивість CSS clear визначає повинен елемент, що йде слідом за плаваючим, перебувати перед ним або зміщений вниз (очищений).

З цього позначення, стає зрозумілим, що властивість clear може запобігти напливу інших елементів поверх плаваючих… правильно. Тепер перейдемо до самих методів.

Рішення 1: дідівський спосіб

Це метод старої закалки. Стара закалка – поняття відносне, і, звичайно ж, справжня стара закалка вимагає використання таблиць для розмітки (в разі чого очищення плаваючих елементів не потрібно). Так що вважайте цей метод дідівським, з тих пір, як з’явилися плаваючі елементи.

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

.clear {
clear: both;
}

І HTML буде виглядати ось так:

I’m floated…
I’m also floated…

Bravo, sirs and madams. I’m in the clear.

І ось демо з імплементацією цього методу:

Зверніть увагу: Якщо вас не турбує згортання контейнера, а тільки неправильне розташування елемента .main, ви можете розмістити «очищений» елемент після контейнера. Але якщо ви вирішите зробити це, ви можете просто поставити clear: both самого об’єкта .main.

Коли-то цей метод був одним з найпоширеніших. Він працює швидко і просто. Однак, в сучасному світі коли прийнято розділяти вміст і оформлення, а також прагнути зробити все максимально семантичним, цей метод не скрізь зустрічає захоплення.

Метод 2: спосіб Overflow

Використовуючи властивість overflow для елемента .container, ми практично можемо змусити контейнер розширитися до висоти плаваючих елементів. Наш CSS-код буде виглядати ось так:

.container {
overflow: hidden; /* can also be «auto» */
}

Наш HTML код залишиться колишнім, без будь-яких додаткових елементів. Ось демо:

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

Однак, одним з головних недоліків цього методу є той факт, що будь-дочірній елемент, який видається за межі контейнера буде обрізаний (якщо задано значення hidden), або викличе появу смуг прокручування (якщо задано значення auto). Краще, ніж попереднє рішення, але далеко від ідеалу. Давайте буде розбиратися далі.

Метод 3: клас «clearfix»

Ви часто про нього чули, але що він з себе представляє? Всі просунуті розробники його використовують, і ви теж хочете. «clearfix» (що означає виправлення очищення плаваючих елементів) визначає клас .clearfix у таблиці стилів, який ми можемо призначити будь-якого елемента, що містить плаваючі. Це змусить контейнер розширитися, виштовхуючи наступні елементи вниз. Як він працює? Він використовує чудові псевдо-елементи ::before ::after. Ніколас Галахер описує його достатньо точно:

Цей метод створює псевдо-елементи і задає їм display: table, що створює анонімну клітинку таблиці. Псевдо-елемент :after використовується для очищення плаваючих елементів. І в результаті… загальна кількість коду скорочується.

CSS код виглядає наступним чином:

.clearfix:before,
.clearfix:after {
content: «»;
display: table;
}
.clearfix:after {
clear: both;
}
.clearfix {
zoom: 1; /* ie 6/7 */
}

HTML-код буде трохи змінений, щоб виглядати ось так:

I’m floated…
I’m also floated…
Bravo, sirs and madams. I’m in the clear.

І ось наше демо з доданим класом .clearfix

І зверніть увагу, Chris Coyier радить, що у випадку, якщо вам не потрібна підтримка браузерів нижче IE8, то ви цілком можете обійтися наступним кодом:

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

Просто, ефективно і легко використовувати у подальшому.

Зауважте: метод, використаний вище – це мікро «clearfix», популяризуваний Ніколасом Галахером. Єдина відмінність – це ім’я класу, яке використовує Ніколас. До появи цього методу, використовувалися схожі техніки, описані Пітером Паулем Кохом і Тьєррі Коблентцом. Зокрема, цей метод clearfix має досить довгу історію і той метод, що ми використовували вище –його остання ітерація.

Метод 4: значення contain-floats з майбутнього

Що цікаво, специфікація W3C додала нову властивість min-height (і для інших властивостей min/max), для того, щоб допомогти вирішити цю проблему. Воно виглядає наступним чином:

.container {
min-height: contain-floats;
}

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

Висновок

Ось і все, ми швидко пробіглися по всім методам «clearfix». Застосування клас .clearfix стало стандартом і я переконливо рекомендую його використання замість попередніх двох методів. Він просто робить життя легше. Звичайно, вам зручніше всього використовувати те, що підходить саме вам, але, як згадувалося раніше, я б радив уникати методу 1 у ці дні і використовувати стандартний «clearfix» трюк.