войти зарегистрироваться

Clearing floats: clearfix vs overflow. Недостатки и достоинства обоих подходов.

В своей недавней статье arestov подробно описал принципиальные отличия очистки потока при помощи свойства clear (например, clearfix) от создания нового контекста форматирования при помощи свойства overflow.

В свою очередь, я бы хотел остановиться подробнее на достоинствах и недостатках этих двух решений. Лично я в своей работе применяю и тот, и другой способ. Причиной тому простой факт: каждый из них имеет свои сильные и слабые стороны, которые приходится учитывать при верстке. Ибо на практике, overflow не всегда уместен, а clearfix не так бесполезен, как кажется.

Для начала оговорюсь: под Clearfix я буду понимать не конструкции вида <div style="clear:both"></div> или <br clear="all" /> (я категорически против их применения), а следующее решение:

.clearfix { zoom: 1 }
.clearfix:after {
content: ' ';
clear:both;
display: block;
width: 0; height: 0;
overflow: hidden;
font-size: 0;
}


1. Overflow


Достоинства
  1. Простота.
    Достаточно прописать родительскому блоку overflow:hidden (или auto) и установить hasLayout для IE6 тем способом, который вам больше нравится.

  2. Собственный контекст форматирования
    Как уже было сказано в посте arestov 'a, overflow не выполняет очистки потока, он создает свой собственный изолированный контекст форматирования, который «оборачивает плавающие блоки». Я считаю это достоинством, так как в большинстве случаев использование overflow упрощает процесс верстки.


Недостатки
  1. Проблемы с позиционированием за границы блока.
    В соответствии со спецификацией CSS, свойство overflow предписывает браузеру скрывать все, что выходит за границы блока. В нашем случае, все, что вы выносите абсолютным позиционированием или отрицательными маргинами за пределы блока, для которого выполняется clearing — все будет скрыто.

    Классический пример: выпадающее горизонтальное меню на UL-LI. LI сложены в ряд при помощи float:left, у внешнего UL выполняется clearing. При использовании overflow, во всех браузерах кроме IE, выпадающее меню обрезается до границ родительского UL.
    3.42 КБ
    Другой пример: раскладка страницы, использующая float и отрицательные margin'ы. Overflow также неприменим в данном случае.

  2. Проблема с выделением текста.
    У браузеров на движке Gecko (Firefox и ему подобные) есть неприятная особенность: текст в блоках, для которых задан overflow:hidden (либо auto) не выделяется дальше границ этого блока. Это сложно объяснить, поэтому лучше откройте мою тестовую страницу в firefox и попробуйте выделить текст от середины первого параграфа до конца страницы.

    Должен сказать, что с точки зрения пользователя это весьма раздражающая особенность. Неприятно, когда ты хочешь выделить визуально сплошной текст, а получается — только один абзац. И сколько не дергай мышку, выделение ни на символ дальше не сдвинется. А все потому, что кто-то выполнил clearing для параграфа при помощи overflow.


2. Clearfix


Достоинство

Единственным достоинством Clearfix, на мой взгляд, является отсутствие недостатков overflow :-) Действительно, у этого подхода нет проблем ни с позиционированием, ни с выделением. При этом, не смотря на свою громоздкость, он делает то, что от него требуется.

Недостатки
  1. Разное поведение в различных браузерах.
    Если рассмотреть подробно реализацию clearfix, то можно заметить, что для нормальных браузеров применяется очистка потока (clear:both в .clearfix:after), а для IE выполняется определение нового контекста форматирования посредством установки hasLayout (свойство zoom). Это в некоторых случаях влечет за собой различия в отображении и об этом необходимо помнить.

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

комментарии (16)

  • d-o-b.ru/test/clear/
    • в мозилле марджины не схлопываются, но это не так страшно…
  • меня вы убедили в том что overflow не стоит использовать для очистки потока, хотя я и до этого так считала
  • Вопрос от особы совсем чуть-чуть приближенной к императору вёрстке: что такое поток и зачем его очищать?

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

      К примеру если ты сделаешь так:
      <div id="outer">
      <div style="float:left;height:300px;">123</div>
      </div>
      то, как ни удивительно, у блока outer высота будет отнюдь не 300 пикселей, его ты вообще не увидишь, а все что пойдет дальше по списку окажется под плавающим блоком или слева от него. Еще у блоков есть полезное свойство clear (ну или у br, кому что больше нравится), которое не допускает других блоков на этом уровне (left — слева, right — справа, both — с обеих сторон), т.е. добавив в конец блока outer тег <br clear="all"> проблема решается, все последующие блоки пойдут уже после этого <br>
  • Верстальщики проснулись и зашевелились. Это радует =) Жду еще новых статей.

    P.S. Мне в работе достаточно класса .clear, который я закинул в reset.css:
    .clear:after {
    	content:"";
    	display:block;
    	clear:both;
    }
    

    и height:1%; для IE
  • Жду с нетерпением статью про inline-block. По моему это просто чудо какое-то.
    test.kizu.ru/examples/inline-block-solved.html
    • опять же — zoom:1 работает как overflow только контент не обрезает
    • ой, это не вам)
  • Это в некоторых случаях влечет за собой различия в отображении и об этом необходимо помнить.
    А если точнее?
    • Например, посмотрите на эту тестовую страницу в IE и не-IE.
      • Я думаю, что необходимо просто помнить, что hasLayout, overflow и dot-clearing — это совсем разные вещи. А то, что они, в частности, одинаково решают проблему с клиарингом родителя — просто удачное совпадение. И не стоит ожидать от них одинакового поведения. По-моему, это очевидно.
        • Мне казалось, что именно это я и написал (новый контекст форматирования в IE против clear в в не-IE браузерах). Возможно, это и очевидно, но не упомянуть об этом, по-моему, было нельзя.
  • Я бы первое достоинство overflow:hidden в недостатки перенес. Т.о. появится еще одно достоинство у clearfix'a: достаточно назначить родительскому блоку класс (что проще, чем прописывать каждый раз одно и тоже свойство разным селекторам).
    • А для overflow:hidden нельзя прописать класс? Или вы исходите из соображений, что раз коду меньша, то нет смысла в классе, а раз нет класса, уже не так удобно? Странные у вас рассуждения.
      • В своих странных рассуждениях я отталкиваюсь лишь от предложенной методики: либо класс, либо свойство родителя. И считаю использование класса более удобным (будь он с cler'ом или же с overflow), ибо надоедает каждый раз заботиться о hasLayout.
Только авторизованные пользователи могут оставлять комментарии. Авторизуйтесь, пожалуйста.