Clear:both vs. overflow:hidden. Что лучше?

До перехода к решению, рассмотрим, что такое clearfix.

Его используют, чтобы родительский элемент «поглотил» плавающий элемент, к которому применён float, дабы избежать т.н. «схлопывания».

Для примера возьмём блок, внутри которого картинка, обтекаемая текстом. Код конструкции следующий:

1
2
3
4
<div>
      <img src="halloween-flat-icon.png" alt="" style="float:left"/>
      <p>Хеллоуин — праздник, для нас несколько чужд, но с каждым годом набирающий популярность. Празднуется 31 октября, в канун Дня всех святых.</p>
</div>
<div>
      <img src="halloween-flat-icon.png" alt="" style="float:left"/>
      <p>Хеллоуин — праздник, для нас несколько чужд, но с каждым годом набирающий популярность. Празднуется 31 октября, в канун Дня всех святых.</p>
</div>

Результат:

clearfix1

Вроде хорошо. Но стоит добавить ещё контента, как идиллия рушится, а мы получаем вот такое безобразие:

clearfix2

Будем исправлять.

clear:both

Первое, что приходит на ум — добавить div со стилем clear:both, который запретит обтекание.

Разметка приобретает следующий вид:

1
2
3
4
5
6
7
8
9
10
11
<div>
      <img src="halloween-flat-icon.png" alt="" style="float:left"/>
      <p>Хеллоуин — праздник, для нас несколько чужд, но с каждым годом набирающий популярность. Празднуется 31 октября, в канун Дня всех святых.</p>
</div>
 
<div style="clear:both"></div> <!-- Отменяем обтекание элемента -->
 
<div>
      <img src="halloween-flat-icon.png" alt="" style="float:left"/>
      <p>Хеллоуин — праздник, для нас несколько чужд, но с каждым годом набирающий популярность. Празднуется 31 октября, в канун Дня всех святых.</p>
   </div>
<div>
      <img src="halloween-flat-icon.png" alt="" style="float:left"/>
      <p>Хеллоуин — праздник, для нас несколько чужд, но с каждым годом набирающий популярность. Празднуется 31 октября, в канун Дня всех святых.</p>
</div>
<div style="clear:both"></div> <!-- Отменяем обтекание элемента -->
<div>
      <img src="halloween-flat-icon.png" alt="" style="float:left"/>
      <p>Хеллоуин — праздник, для нас несколько чужд, но с каждым годом набирающий популярность. Празднуется 31 октября, в канун Дня всех святых.</p>
   </div>

clearfix3

Выглядит хорошо. Но не всё так хорошо, как выглядит. Если блоков будет сотня (а это возможно, например, с комментариями), наплодится и сотня «бесполезных» очищающих дивов. Которые не только засоряют вёрстку, они увеличивают вес страницы. Ладно, вес не существенный, но когда есть возможность упростить и сократить, этим грех не воспользоваться.

overflow:hidden

Обратившись к документации, можем узнать/вспомнить, что свойство overflow управляет отображением содержания блочного элемента, если оно целиком не помещается и выходит за область заданных размеров.

Со значением hidden отображается только область внутри элемента, остальное будет скрыто. При этом, плавающий элемент, в нашем случае — картинка, уже не «выпадает» из блока.

Переписав немного код, мы избавляемся от лишних блоков, а визуально получаем то же, что и на прошлом шаге.

1
2
3
4
5
6
7
8
9
<div style="overflow:hidden">
      <img src="halloween-flat-icon.png" alt="" style="float:left"/>
      <p>Хеллоуин — праздник, для нас несколько чужд, но с каждым годом набирающий популярность. Празднуется 31 октября, в канун Дня всех святых.</p>
</div>
   
<div style="overflow:hidden">
      <img src="halloween-flat-icon.png" alt="" style="float:left"/>
      <p>Хеллоуин — праздник, для нас несколько чужд, но с каждым годом набирающий популярность. Празднуется 31 октября, в канун Дня всех святых.</p>
</div>
<div style="overflow:hidden">
      <img src="halloween-flat-icon.png" alt="" style="float:left"/>
      <p>Хеллоуин — праздник, для нас несколько чужд, но с каждым годом набирающий популярность. Празднуется 31 октября, в канун Дня всех святых.</p>
</div>
<div style="overflow:hidden">
      <img src="halloween-flat-icon.png" alt="" style="float:left"/>
      <p>Хеллоуин — праздник, для нас несколько чужд, но с каждым годом набирающий популярность. Празднуется 31 октября, в канун Дня всех святых.</p>
</div>

Супер! Да не всё так гладко... Печаль кроется в том самом значении hidden, из-за которого контент отображается только внутри блока. Что это значит, рассмотрим на очередном примере.

Захотелось нам, чтобы картинка была не просто слева от текста, а ещё и «выходила» за край блока.

clearfix4

Но из-за overflow:hidden не получится, картинку «обрежет» по краю блока.

clearfix5

И это не единственный момент. Точно так же будут «обрезаться» части элементов при деформации и поворотах, не будет видно теней и т.д.

В целом метод хорош, но не всегда подходит.

.clear:after

В приведённых примерахстили вписывались прямо внутрь тега. Надеюсь, у читающего сей опус, есть мало-мальское представление о таблицах стилей и классах. Если нет, объясню вкратце.

В реальных условиях, верстая грамотно, никто не пишет <div style="clear:both"></div>. Элементу присваивается класс, например, clear

Теперь уже фрагмент разметки будет иного вида: <div class="clear"></div>

А параметры этого класса будут вынесены отдельно:

1
2
3
<style>
    .clear{clear:both}
</style>
<style>
    .clear{clear:both}
</style>

Зачем так делать — тема отдельного разговора. Нужно укреплять теоретическую часть. Рекомендую ознакомиться с хорошими книгами по теме.

В целом, если бы не «мусор» в разметке, clear:both более гибкий в эксплуатации. А раз нас не устраивают лишние элементы вёрстки, от них нужно избавляться. Благо, это возможно.

Возьмём тот же класс .clear, но не напрямую, а задействовав псевдоэлемент :after. Напишем для него стили:

1
2
3
4
5
.clear:after{
    content: '';   /*Обязательное свойство*/
    display:block; /*Делаем элемент блочным*/
    clear:both;   /*Запрещаем обтекание*/
}
.clear:after{
    content: '';   /*Обязательное свойство*/
    display:block; /*Делаем элемент блочным*/
    clear:both;   /*Запрещаем обтекание*/
}

При таком подходе, используя всё тот же класс, что и в начале, отпадает необходимость править вёрстку и «выкашивать» все <div style="clear:both"></div> в срочном порядке. По сути, не будет никаких изменений вообще. А вот уже при развитии проекта, или создании нового, есть возможность очистить работу от ненужного хлама.

Рассмотрим на примере из трёх одинаковых блоков. Каждому из них присваивается один и тот же класс. Но, между вторым и третьим остался фрагмент старой вёрстки.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<style>
    .clear:after{
    content: '';   /*Обязательное свойство*/
    display:block; /*Делаем элемент блочным*/
    clear:both;   /*Запрещаем обтекание*/
    }
</style>
 
<div class="clear">
      <img src="halloween-flat-icon.png" alt="" style="float:left"/>
      <p>Хеллоуин — праздник, для нас несколько чужд, но с каждым годом набирающий популярность. Празднуется 31 октября, в канун Дня всех святых.</p>
</div>
 
<div class="clear">
      <img src="halloween-flat-icon.png" alt="" style="float:left"/>
      <p>Хеллоуин — праздник, для нас несколько чужд, но с каждым годом набирающий популярность. Празднуется 31 октября, в канун Дня всех святых.</p>
</div>
 
<div class="clear"></div>
 
<div class="clear">
      <img src="halloween-flat-icon.png" alt="" style="float:left"/>
      <p>Хеллоуин — праздник, для нас несколько чужд, но с каждым годом набирающий популярность. Празднуется 31 октября, в канун Дня всех святых.</p>
</div>
<style>
    .clear:after{
    content: '';   /*Обязательное свойство*/
    display:block; /*Делаем элемент блочным*/
    clear:both;   /*Запрещаем обтекание*/
    }
</style>
<div class="clear">
      <img src="halloween-flat-icon.png" alt="" style="float:left"/>
      <p>Хеллоуин — праздник, для нас несколько чужд, но с каждым годом набирающий популярность. Празднуется 31 октября, в канун Дня всех святых.</p>
</div>
<div class="clear">
      <img src="halloween-flat-icon.png" alt="" style="float:left"/>
      <p>Хеллоуин — праздник, для нас несколько чужд, но с каждым годом набирающий популярность. Празднуется 31 октября, в канун Дня всех святых.</p>
</div>
<div class="clear"></div>
<div class="clear">
      <img src="halloween-flat-icon.png" alt="" style="float:left"/>
      <p>Хеллоуин — праздник, для нас несколько чужд, но с каждым годом набирающий популярность. Празднуется 31 октября, в канун Дня всех святых.</p>
</div>

На практике можете убедиться, что всё работает корректно.

Таким образом можно вынести вердикт: clear:both; использовать лучше, но следует модифицировать старый подход.

Надеюсь, мой метод окажется полезным. С радостью выслушаю мнения и советы по теме в комментариях.

Мир, труд, Найкрис.

Смотрите ещё