Clearfix больше не нужен


Содержание материала:

Clearfix

При использовании CSS-свойства float: left или float: right , элементы начнут выводиться не так, как ожидается.

На примере выше видно, что родительский элемент с белым фоном «не покрывает» свои дочерние элементы. Чтобы страница выводилась как ожидалось, для родительского элемента надо добавить класс .clearfix .

Некоторые верстальщики вместо использования «clearfix» указывают CSS-свойство overflow: hidden , что является неправильным, т.к. в этом случае, объекты, выходящие за пределы контейнера, становятся невидимыми. Например, стрелочки для слайдера, или стикеры («новинка», «хит») на карточках товаров.

Все, что вам известно о clearfix — неверно

Перевод статьи: Everything you Know about Clearfix is Wrong.
Автор: Thierry Koblentz.

Что такое clearfix?

Clearfix — это основанный на CSS прием, который используется для решения проблем, возникающих при содержании «плавающих» элементов в рамках блока контейнера, не предусматривающий внесение каких-либо изменений в разметку документа.

Как это работает?

    В браузерах, поддерживающих псевдоэлемент :after данный хак генерирует контент (находящийся сразу же за содержимым форматируемого элемента), которому назначаются CSS свойства, отменяющие обтекание плавающих дочерних элементов. Короче говоря, это дает примерно тот же эффект, что и включение структурного элемента

В результате имеем.

Из последнего пункта следует то, что в IE, и только в IE, хак clearfix создаст иную конструкцию. Это связано с тем, что контекст блочного форматирования:

  1. содержит в себе плавающие элементы;
  2. предотвращает объединение полей ( margins );
  3. не должен накладываться на плавающие элементы, находящиеся в том же контексте блочного форматирования (согласно пукту 9.5 спецификации).

Отрицательные стороны.

Все напрямую зависит от компоновки вашего документа и стилизации его элементов. Поэтому результаты применения хака clearfix могут быть непредсказуемыми. К примеру, на этом простом демо (иллюстрирующем случаи, упомянутые в первых двух пунктах предыдущего списка) можно увидеть различия визуализации в IE и в, так называемых, современных браузерах:

  • В Mozilla, WebKit, и т.д.:
    • Имеющиеся на странице три заголовка расположены на разных уровнях по вертикали.
    • Высота зазора сверху контейнера .wrapper (который содержит фоновое изображение) превышает 20px.
    • Плавающий блок .floatMe отображается за пределами контейнера wrapper .
  • В IE:
    • Все три заголовка выровнены по вертикали.
    • Высота зазора над контейнером .wrapper , составляет половину той, которая имеет место в современных браузерах.
    • Плавающий блок размещен в рамках элемента контейнера.

Что это дает?

Все эти различия объясняются очень просто:

    В IE:

      Блоку .wrapper назначено свойство hasLayout (так как он имеет фиксированное значение свойства width ), поэтому он образует новый контекст блочного форматирования. Это предотвращает схлопывание поля элемента параграфа (черный блок) и поля заголовка, находящегося в элементе контейнере. Иначе говоря, верхний зазор – это нижнее поле margin-bottom черного блока (элемента

    ).

  • Плавающий блок находится в контейнере .wrapper , так как согласно спецификации, блочный контекст форматирования обязан включать все внутренние смещенные элементы (т.е. floats).
  • В современных браузерах:
    • Все присутствующие элементы находятся в одном контексте блочного форматирования, поэтому прилегающие поля ( margins ) объединяются. Поле внутреннего заголовка выходит за пределы контейнера .wrapper и упирается в край элемента параграфа

      . В отличие от того что происходит в IE, здесь верхний зазор между контейнером и черным блоком образуется не нижним полем ( margin-bottom ) параграфа, а верхним полем ( margin-top ) заголовка.

    • По этой же причине плавающий .floatMe блок не находится в рамках родительского элемента .wrapper .
  • В данной ситуации мы не имеем дело с никаким багом. А причиной разногласий визуализации в IE и современных браузерах является тот факт, что мы просто применяем различное стилевое форматирование элемента .wrapper в рамках нашего тестового макета.

    Теперь взгляните на второй вариант демо страницы, где блок .wrapper образует новый контекст блочного форматирования как в IE, так и в других браузерах. В общем, все выглядит намного лучше (да, в IE внизу плавающего блока присутствует зазор, что является багом, обусловленным тем, что для .wrapper установлено свойство hasLayout ).

    Как это связано с clearfix.

    Давайте предположим, что мы недостаточно знакомы с таким понятием как блочный контекст форматирования и вместо того, чтобы назначить необходимые свойства стилей блоку контейнеру .wrapper , как мы это делали на предыдущем шаге, мы просто применим clearfix к диву

    Во время написания данного материала я пытался предположить, сможете ли вы самостоятельно предугадать изменения, которые будут вызваны применением хака clearfix, в рассматриваемом нами макете. Как бы там ни было, результат использования clearfix продемонстрирован на следующей демо странице.

    Что же произошло?

    Плавающий блок .floatMe включен, но в IE макет страницы нарушен, а именно – средняя колонка смещена вниз относительно боковых колонок. Это произошло потому, что согласно пункту 9.5 спецификации, контекст блочного форматирования не должен перекрывать плавающие элементы, находящиеся с ним в одном блочном контексте форматирования (как было указано выше в третьем пункте).

    Теперь элемент, реализующий среднюю колонку .mainContent получил hasLayout (благодаря применению к нему хака clearfix>), в результате чего он создает новый контекст блочного форматирования, который уже не вмещается в пространство между двумя боковыми колонками и по этой причине смещается вниз.

    В создавшейся ситуации многие разработчики обнаруживают, что если удалить свойства, создающие внутренние отступы элемента ( padding ), то все стает на свои места, полагая при этом, что виной всему является баг. И для его обхода, они, используя условные комментарии, сбрасывают значения внутренних отступов для IE.

    Совершенно не подозревая в этом clearfix и полагая, что созданный ими макет страницы более или менее отвечает условиям кроссбраузерности (не учитывая обнуление значений внутренних отступов и необходимость предотвращения схлопывания полей).

    Как можно исправить ситуацию.

    Придерживаясь базовых основ стилизации элементов вы значительно повысите кроссбраузерность ваших проектов. Это первый и очень важный шаг на пути к достижению кроссбраузерной совместимости веб-документов.

    Применяя необходимые стили для обеих элементов – контейнера .wrapper и средней колонки .mainContent , создающие блочный контекст форматирования (к примеру, для .wrapper определить display:inline-block а для .mainContent установить свойство overflow:hidden ) вы решите проблему. В этом можно убедиться, взглянув на последний вариант нашего примера.

    Подытожим все вышесказанное.

    Существование в сети документов с шаткими макетами в большей своей части объясняется тем, что люди не понимают значение блочного контекста форматирования и то, что он делает.

    Зачастую разработчики манипулируют свойством hasLayout не задумываясь над тем, чтобы вместо этого использовать необходимые свойства стилей, что позволит решить проблему кроссбраузерно. Именно поэтому они, в конечном итоге, добавляют отдельные свойства для IE (в виде хаков) для «залатывания» дыр в своих стилях.

    Это, конечно же, не означает что мы должны совсем отказаться от использования clearfix. Этот хак является отличным инструментом и вполне безопасен, при условии, что мы знакомы с нюансами его использования для содержания плавающих объектов. Кроме того, он может предотвратить объединение полей и «ускользнуть» от окружающих плавающих блоков в IE.

    Я сам применяю clearfix для форматирования модальных окон и других подобных им элементов, точно зная, что в текущем контексте блочного форматирования нет плавающих элементов. Более того, я с уверенностью использовал его при создании своего фреймворка.

    Какие методы «clearfix» можно использовать?

    У меня есть старая проблема обтекания div двухколоночного макета. Моя боковая панель плавает, поэтому мой контейнер div не может обернуть содержимое и боковую панель.

    Кажется, существует множество методов исправления явной ошибки в Firefox:

    В моей ситуации единственный, который, кажется, работает правильно, — это решение
    , которое немного немного изворотливое. overflow:auto дает мне неприятные полосы прокрутки, а overflow:hidden обязательно имеет побочные эффекты. Кроме того, IE7, по-видимому, не должен страдать от этой проблемы из-за ее неправильного поведения, но в моей ситуации он страдает так же, как Firefox.

    Какой метод, доступный в настоящее время для нас, является наиболее надежным?

    В зависимости от создаваемого проекта каждый из нижеприведенных решений clearfix CSS имеет свои преимущества.

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

    Современные решения Clearfix

    Контейнер с overflow: auto;


    Самый простой способ очистить плавающие элементы — это использование overflow: auto стиля overflow: auto для содержащего элемента. Это решение работает во всех современных браузерах.

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

    Использование «переполнения: скрытое» также является решением clearfix, но не имеет полос прокрутки, однако использование hidden содержимого обрезает любой контент, расположенный за пределами содержащего элемента.

    Примечание. В этом примере плавающий элемент является тегом img , но может быть любым элементом html.

    Clearfix Reloaded

    Тьерри Кобленц на CSSMojo написал: Самое последнее обновление clearfix. Он отметил, что, отказавшись от поддержки oldIE, решение может быть упрощено до одной инструкции css. Кроме того, использование display: block (вместо display: table ) позволяет полям рушиться должным образом, когда элементы с clearfix являются братьями и сестрами.

    Это самая современная версия clearfix.

    Старые решения Clearfix

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

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

    Они перечислены примерно в хронологическом порядке.

    «Beat That ClearFix», clearfix для современных браузеров

    Тьерри Кобленц из CSS Mojo отметил, что при ориентации на современные браузеры мы можем теперь отказаться от zoom и ::before свойства/значений и просто использовать:

    Это решение не поддерживает IE 6/7. специально!

    Тьерри также предлагает: » Предупреждение: если вы начинаете новый проект с нуля, пойдите для него, но не перепутайте эту технику с тем, который у вас есть сейчас, потому что, хотя вы не поддерживаете oldIE, ваши существующие правила предотвращают сбрасывание полей «.

    Micro Clearfix

    Последнее и глобально принятое решение clearfix, Micro Clearfix от Nicolas Gallagher.

    Известная поддержка: Firefox 3. 5+, Safari 4+, Chrome, Opera 9+, IE 6+

    Свойство переполнения

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

    http://www.quirksmode.org/css/clearing.html — объясняет, как разрешить общие проблемы, связанные с этим методом, а именно: установить width: 100% на контейнере.

    Вместо использования свойства display для установки «hasLayout» для IE другие свойства могут использоваться для запуска «hasLayout» для элемента.

    Другой способ очистить поплавки с использованием свойства overflow — это использовать подделку подчёркивания. IE будет применять значения с префиксом подчеркивания, другие браузеры не будут. zoom свойств zoom hasLayout в IE:

    Хотя это работает. не рекомендуется использовать хаки.

    PIE: простой способ очистки

    Этот более старый метод «Easy Clearing» имеет то преимущество, что позволяет позиционировать элементы за пределами границ контейнера за счет более сложного CSS.

    Это решение довольно старое, но вы можете узнать все о Easy Clearing on Position Is Everything: http://www.positioniseverything.net/easyclearing.html

    Элемент, использующий свойство «clear»

    Быстрое и грязное решение (с некоторыми недостатками), когда вы быстро шлепаете что-то вместе:

    Недостатки

    • Он не реагирует и, таким образом, не может обеспечить желаемый эффект, если стили макета меняются в зависимости от медиа-запросов. Решение в чистом CSS является более идеальным.
    • Он добавляет разметку HTML без необходимости добавления семантического значения.
    • Для этого требуется встроенное определение и решение для каждого экземпляра, а не ссылка класса на одно решение «clearfix» в css и класс, ссылающиеся на него в html.
    • Это делает код трудным для работы с другими, поскольку им, возможно, придется писать больше хаков, чтобы обойти его.
    • В будущем, когда вам нужно/нужно использовать другое решение clearfix, вам не нужно будет возвращаться и удалять каждый
      тега»], замусоренного вокруг разметки.

    Какие проблемы мы пытаемся решить?

    Есть два важных соображения, когда плавающие вещи:

    Содержит потомок плавает. Это означает, что рассматриваемый элемент становится достаточно высоким, чтобы обернуть всех плавающих потомков. (Они не висят снаружи.)

    Изоляция потомков от внешних поплавков. Это означает, что потомки внутри элемента должны иметь возможность использовать clear: both и не взаимодействовать с плавающими элементами вне элемента.

    clear: both interacting with a float elsewhere in the DOM» />

    Блокировать контексты форматирования

    Есть только один способ сделать оба этих. И это установить новый контекст форматирования блока. Элементы, которые устанавливают контекст форматирования блока, представляют собой изолированный прямоугольник, в котором поплавки взаимодействуют друг с другом. Контекст форматирования блока всегда будет достаточно высоким для визуального переноса его плавающих потомков, и никакие плавающие объекты вне контекста форматирования блока не могут взаимодействовать с элементами внутри. Эта двусторонняя изоляция — именно то, что вы хотите. В IE эта же концепция называется hasLayout, которую можно установить с помощью zoom: 1 .

    Есть несколько способов установить контекст форматирования блока, но я рекомендую решение: display: inline-block with width: 100% . (Конечно, существуют обычные предостережения с использованием width: 100% , поэтому используйте box-sizing: border-box или поместите padding , margin и border на другой элемент.)

    Самое надежное решение

    Вероятно, наиболее распространенным применением поплавков является двухколонный макет. (Может быть расширен до трех столбцов.)

    Сначала разметка структуры.

    Попробуй сам

    Перейдите к JS Bin, чтобы поиграть с кодом и посмотреть, как это решение строится с нуля.

    Традиционные методы исправления ошибок считаются вредными

    Проблема с традиционными решениями clearfix заключается в том, что они используют две разные концепции рендеринга для достижения одной и той же цели для IE и всех остальных. В IE они используют hasLayout для установки нового контекста форматирования блока, но для всех остальных они используют сгенерированные блоки ( :after ) с clear: both , что не устанавливает новый контекст форматирования блока. Это означает, что вещи не будут вести себя одинаково во всех ситуациях. Для объяснения, почему это плохо, см. Все, что вы знаете о Clearfix, неправильно.

    Этот загадочный clearfix

    По началу, когда только начинаешь верстать и натыкаешься в чужих сайтах или в cms на этот clearfix, возникает куча вопросов: что это за абра-кадабра и для чего она.

    Так вот, появление clearfix обязано одной особенности css, которая начинающим верстальщикам кажется очень нелогичной, — это всплывающие элементы. Предположим, у вас есть некий родительский элемент, а внутри него — дочерний со стилем float. А следом за родительским идет ещё один… Что мы получаем в такой ситуации? Если дочерний элемент достаточно большой, то по правилам элементам со стилем float он выпадает из общего потока. А это значит, что высота родительского элемента равна нулю или, если он содержит еще какой-то текст, обтекающий дочерний элемент, то высоте этого текста. Таким образом всё, что будет следовать за этим родительским элементом будет пытаться «всплыть» относительно дочернего. Звучит путано, но кто пробовал верстать, тот с этим сталкивался.

    Самый простой метод очистки такого потока — разместить следом блок со стилем clear: both;

    Минус — некоторая громоздкость из-за наличия дополнительного элемента.

    Избавиться от этого можно так же используя clearfix. Достаточно присвоить этот класс родителю, как он все сразу поправит 🙂

    Правильный clearfix


    Урок по правильному применению хака clearfix.

    Я использую хак clearfix на всех своих сайтах. Он еще известен как “Easy Clearing Hack” – используется для очистки обтекания блоков (div) без использования структурной разметки. Это является очень эффективным в решении вопросов компоновки и несоответствий браузера, без необходимости смешивать структуру с презентацией. В течение последних нескольких лет, я принял к сведению несколько полезных байтов информации относительно метода “Easy Clear”. В этой статье я хочу собрать все эти уроки относительно расширенной версии CSS хака clearfix.

    Используйте пробел вместо точки, чтобы предотвратить изменение размещения.

    Вот реализация этого хака, как представлено в одной из оригинальных статей, описывающих метод:

    Обратите внимание на строку, содержащую свойство content: “.”;. Я обнаружил что точка в кавычках имеет неприятную склонность к нарушению изменение размещения. При добавлении литерала точка после .clearfix блока (в ie, через .clearfix:after селектор) хак создает ошибку в некоторых браузерах. И не только для Internet Explorer – в зависимости от расположения, даже Firefox будет тупить после отключения :after – на основе псевдо-точки. Нужно решение этого беспорядка? Заменить точку на простой пробел: content: ” “; – эта хитрость оказалась вполне успешной, что я теперь использую это свойство во всех своих clearfix-ах.

    Добавить нулевое свойство font-size чтобы сделать все гладко.

    Другая странная несовместимость замеченная в clearfix-е – расположение пропадает, когда свойство CSS font-size, находящееся в хаке устанавливаетя в ноль:

    Конечно, это может быть излишним при использовании пробела вместо символа “точка” (как описано выше), но я, честно говоря, не беспокоюсь об этом. Оглядываясь назад, я думаю что может быть сделать это решение до открытия фикса пробела. Тем не менее, некоторые браузеры обрабатывают пробел как текст, так что это все же может оказаться полезным. Возможно да, возможно нет — я собираюсь бросить его для всех вас CSS-гуру.

    Остерегайтесь дезинформации относительно этого метода.

    Нет, я не пытаюсь вас утомить советами предлагаемых в этой статье — вы увидите, что они вполне безобидны. Взамен этого, я имею в виду ошибочную информацию, найденную в другом месте в Интернете и даже в печатном виде. Вот презентация хака clearfix, описанная в превосходной книге Joseph W. Lowery’s “CSS Hack & Filters”:

    Ой! Вы видите проблему? На самом деле здесь 2 потенциальные проблемы в .clearItem Mr. Lowery’s. Первая проблема: использование устаревшего значения inline в свойстве display в середине декларации .clearItem:

    ..как обсуждалось в оригинальной статье, значение должно быть inline-block – фикс обтекания для IE / Mac:

    Вторая проблема: Mr. Lowery’s включает * html .clearItem * селектор в следующей строке:

    Первый селектор в этой линии это все, что требуется для достижения успешного взлома. Второй селектор, однако, эффективно задает высоту до 1% для всех версий браузеров Internet Explorer. Это отстой – я узнал на собственном опыте: через месяц или около того, используя эту версию хака, я обнаружил, что около половины моих посетителей (т.е. те, кто использует IE) не смогли оставить комментарии, потому что все поля формы были только 1 пиксель высотой! К счастью, это не заняло слишком много времени, чтобы выявить виновника ошибки: гнусный подстановочный знак (*) селектора CSS .clearItem – как видно в коде выше. После удаления второго селектора, все срослось.

    Так в чем мораль этой истории? Просто! Всегда дважды проверяйте ваш код и думайте, прежде чем тупо скопировать и вставить. Даже профессиональные писатели и программисты делают ошибки, так что обязательно обратите внимание и не делайте никаких предположений.

    А теперь все вместе…

    Складываем все вместе и объединяем эти уроки с исходной (правильной) версией “Easy Clear Method”, мы видим – полностью функциональное решение хака clearfix:

    ..и, снято! Надеюсь, вам было так же весело, как я сделал в процессе написания этой статьи.. если нет, то надеюсь что в этом раунде “извлеченных уроков” представлены некоторые полезные сведения о вездесущем и полезном хаке clearfix.

    И наконец – этот пост посвящен CSS и я не ожидаю ничего хорошего, только самой суровой критики идей, изложенных в данном документе. — Валяйте, все вы сумасшедшие CSS-головы!)))

    Clearfix больше не нужен?

    Новые значения свойства display из модуля CSS Display 3-го уровня (за развитием которого мы следили с позапрошлого года) потихоньку проникают в браузерную реальность. Первая ласточка — display:contents — уже больше года поддерживается в Firefox, без всяких префиксов и флагов. Вторая ласточка «прилетит» вот-вот: в Firefox 53+ и Chrome 57+ появляется display: flow-root . И оно уже работает в ночных сборках и Canary соответственно.

    Вокруг этого значения уже много путаницы. Надеюсь, это своего рода мини-ЧаВо поможет в этой путанице разобраться.

    — Что дает display: flow-root ?

    Кратко: заставляет блок создавать отдельный блочный контекст форматирования. Без побочных эффектов.

    Долго: см. подробности ниже.

    — Что такое контекст форматирования?

    Кратко: штука, заставляющая CSS делать раскладку. Кроме шуток: именно так, почти дословно, определялось это понятие в ранних редакциях спецификации CSS Display 3.

    Долго: сейчас контекст форматирования определяется в спецификации так: «среда, в которой размещается набор связанных между собой контейнеров». Правила этого размещения в разных контекстах форматирования бывают разные. Например, во флекс-контейнере действуют контекст форматирования флексбоксов, и правила размещения дочерних элементов (направления главной и поперечной осей, будет ли флексбокс многострочным и т.д.) определяются свойством flex-flow (и его составляющими). У грид-контейнеров свой контекст форматирования, и правила размещения у него свои. В табличном контексте форматирования в обязательном порядке выстраивается структура, эмулирующая структуру HTML-таблицы (table/table-row/table-cell), если какой-то уровень пропущен, браузер достравивает вместо него анонимные боксы. И т.д.

    Но чаще всего мы имеем дело с двумя контекстами форматирования: инлайновым и блочным. Слова (и прочие вещи, встраиваемые прямо в текст — иконки, поля форм и т.д.) собираются в строки, строки «пакуются» в этакие прямоугольные «ящики» — блоки, которые ставятся один к одному «штабелями». Для нас привычно, что строки идут горизонтально слева направо, а блоки — вертикально сверху вниз, но бывают и другие варианты. Собирательно такой порядок вещей называют «нормальным потоком», «потоковой раскладкой» или просто «потоком» (flow по-английски).

    — А зачем делать этот контекст отдельным?

    В блочном контексте форматирования встречаются не только обычные блоки, но и плавающие (наши любимые float-ы). По спецификации, плавающие блоки не влияют на обычные, но влияют на их инлайновое (текстовое) содержимое — заставляют контейнеры строк («line boxes») ужаться. Т.е. границы обычных блоков для плавающих ничего не значат — они запросто накладываются на блоки и проходят сквозь них, хоть внутрь, хоть наружу, хоть навылет. А вот текст накладываться на них не может и вынужден обтекать их снаружи, втискиваясь в оставшееся место. Вот примерная иллюстрация (оффлайновая:), как это может происходить:

    Поскольку float-ы придуманы именно для обтекания врезок текстом, а не для горизонтальной раскладки блоков, это поведение — «не баг, а фича»: текст будет обтекать врезку ровно столько, сколько нужно, не дожидаясь конца блока или абзаца, в верстке не будет некрасивых дырок. Но из него напрямую следует «недержание» float-ов обычными блочными контейнерами, в которых текста недостаточно или вообще нет. Его-то и приходится «лечить» хаками: либо добавлять в конец контейнера (псевдо)элемент с clear (это clearfix и его варианты), либо делать так, чтобы float-ы внутри контейнера и блоки снаружи принадлежали разным контекстам форматирования. На блоки из чужих контекстов float-ы не «наезжают».

    И еще одна «фича» CSS для сплошного текста, оборачивающаяся проблемами в чем-то более сложном — легендарное «схлопывание» margin-ов. Опять же, из обычного блока внешние отступы его дочерних элементов могут «вываливаться» наружу. А из блока, создающего отдельный блочный контекст — никогда.

    У меня был еще старенький наглядный пример на эту тему.

    — Так что, display: flow-root — это просто новый модный clearfix?

    Нет. Это стандартная замена тому, что раньше делалось через overflow:hidden, display:table/table-cell и еще более изощренные хаки.

    — А в чем разница?

    При clearfix плавающие блоки и потомки с выпадающими margin-ами остаются в том же контексте форматирования. А в этих способах — нет. Лучше всего увидеть и «пощупать» это на интерактивных примерах, типа такого или в CodePen чуть ниже. Можно посмотреть и сводную таблицу сравнения.

    — А вот Рэйчел Эндрю пишет, что это — конец хакам с клирфиксами…

    Да, хакам конец, потому что у проблемы теперь есть стандартное решение. Но при всём моем огромном уважении к Рэйчел здесь она, по-моему, слегка переупрощает.

    Я форкнул пример из ее статьи и подбавил туда еще элементов, чтобы наглядно подчеркнуть разницу в поведении каждого подхода (и еще пару бонусов для внимательных читателей):

    Так что в общем случае, как верно заметил там в комментариях Тьерри Кобленц, нельзя просто взять и заменить display: flow-root на clearfix и наоборот. Надо с умом смотреть по ситуации и тестировать!

    — Почему этот flow-root не назвали как-нибудь более понятно, скажем, float-container?

    Кратко: как минимум, потому что он не только про float-ы. А понятие «поток» (flow) одно из ключевых в CSS, из того, чего стыдно не знать;)

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

    В модуле CSS Display 3 свойство display сделали составным: одна часть отвечает за внешнее поведение блока (по отношению к соседям), другая — за внутреннее (правила размещения дочерних элементов). Еще при первом знакомстве с этим модулем мы заметили, что большинство значений display однозначно определяют и то, и другое. То есть однозначно соответствуют конкретным парам новых значений, отвечающих за оба контекста форматирования — внешний, в котором «живет» сам элемент, и внутренний, который управляет его потомками. Все такие элементы создают этот второй контекст автоматически, волей-неволей.

    И лишь два значения display в принципе могут продолжать внутри себя тот же контекст форматирования, в котором находятся сами. Это inline и block. То, из чего состоит поток (flow). Вот W3C и назвали такое поведение элемента, когда внешний поток продолжается внутри него, «втекает» туда — flow. А такое, когда внутри элемента поток как бы начинается заново, независимо от внешнего — flow-root (букв. «корень потока», т.е. его начало).

    Для элемента инлайнового уровня первый вариант (составное значение inline flow) соответствует обычному inline, а второй (inline flow-root) — старому доброму inline-block. А вот для блочного элемента раньше был только обычный block, соответствующий составному block flow. Сделать блок началом нового контекста удавалось лишь побочным эффектом от чего-то другого — т.е. хаком. Теперь же для этого есть стандартное значение (соответствующее составному block flow-root).

    К сожалению, сами составные значения display браузеры еще не поддерживают. Ждут, когда эта часть спецификации «дозреет». Всё-таки, просто добавить одно-два значения для свойства — это одно, а вот менять его логику и ради этого переделывать CSS-парсер — совсем другое…

    — Всё равно не нравится мне название flow-root. Может, еще не поздно поменять его на что-то более «человеческое»?

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

    Добавлено 02.02.2020. Уже нельзя: рабочая группа приняла решение оставить название «как есть», в таком виде и перевести спецификацию в статус кандидата в рекомендации. Добавлено 15.02.2020. Вопрос о переименовании закрыт.

    — Как быть, если я хочу применить модный клирфи… то есть отдельный контекст, скажем, к флекс-контейнеру? Сделать «display: flex flow-root» ведь нельзя. Понадобится добавочная обертка?

    Нет, не понадобится. Это попросту не нужно. Проблемы с «выпадением» float-ов и margin-ов возникают только в потоке, т.е. для обычных блоков. Элементы с другими правилами форматирования изолируют свои контексты автоматически. К тому же в самом флекс-контейнере никаких float-ов и не бывает: даже если у его дочерних элементов и стоял float, «магия» флексбоксового контекста оказывается сильнее и превращает их в обычные флекс-элементы, наравне с прочими. А уже внутри этих флекс-элементов — свой собственный изолированный контекст, из которого тоже ничего никуда не вываливается.

    — Кстати, раз есть флексбоксы, зачем нам сейчас вообще все эти хаки с флоатами?

    Верно подмечено! Действительно, именно для раскладки блоков такие хаки уже практически не нужны. Это раньше приходилось страдать от издержек неподходящих инструментов, потому что других просто не было. А что каких-то 3% браузеров годные инструменты не понимают — так стоит ли убиваться ради мегакрасоты в этих динозаврах, может, важнее, чтобы сайты/интерфейсы быстро грузились и не не падали под тяжестью лишних костылей и полифилов, а «спартанский» внешний вид — наименьшая проблема для их привыкших к трудностям пользователей? Так что со временем эти «клирфиксы» неизбежно канут в историю. Кто сегодня вспоминает IEшный hasLayout (кстати, тоже в каком-то смысле способ создания блочного контекста форматирования:)?

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

    — А что делать сейчас, пока массовые браузеры лишь ждут поддержки flow-root? Можно ли его заполифилить?

    К сожалению, прямой и универсальной замены среди существующих решений нет (как мы уже видели). У каждого из них свои ограничения и недостатки, и надо внимательно смотртеть по конкретной задаче, в каком случае что критичнее. Где-то подойдет overflow, где-то — inline-block/table/table-cell с явным указанием размеров (иначе они получат размер по контенту). Если контейнер — элемент fieldset, вам повезло: с ним почти ничего делать не надо, он создает новый блочный контекст по умолчанию. И по возможности используйте для раскладки блоков не float-ы, а флексбоксы и гриды (ну и CSS-таблицы зря со счетов не сбрасывайте), чтобы вообще не доводить дело до хаков.


    Впрочем, можно порыться в спецификациях (напр. введя в поисковик «’block formatting context’ site:drafts.csswg.org» — чтоб искать конкретную фразу и именно среди актуальных редакторских наработок) и посмотреть, вдруг в них найдется что-то, о чем мало кто вспоминает, но подходящее именно вам? Например, новый блочный контекст форматирования создают многоколоночные контейнеры — причем даже при column-count:1. Или вот чуть более сырой, но на первый взгляд еще более «близкий к теме» модуль CSS-изоляции, уже работающий во всём «хромообразном».

    Так что следите за новинками, не бойтесь эксперименировать, и да пребудет с вами CSSила! =)

    Заметки верстальщика

    суббота, 24 марта 2012 г.

    Поток документа, clearfix, overflow:h >

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

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

    Вырвать любой элемент из потока можно несколькими способами.
    Это:
    — задать блоку абсолютное позиционирование — position:absolute;
    — задать блоку фиксированное положение на странице — position:fixed;
    — и задать элементу обтекание — float:left, float:right.

    Если с первыми двумя всё достаточно тривиально (нужно лишь указать координаты начальной позиции блока top|bottom и left|right, и не забыть, что при абсолютном позиционировании отсчёт ведётся от ближайшего родителя с position:relative (или от начала документа, если такового не имеется)), то со вторым способом могут оказаться проблемы.

    Представим себе ситуацию.
    У нас есть превьюшка какого-то поста с текстом и картинкой, в котором картинка выровнена по левому краю:

    И вот всё вроде бы хорошо, всё вроде бы смотрится, всё замечательно. Да? Да!
    Но ровно до тех пор, пока нам не понадобится декорировать этот блок, например задать фоновый цвет, или добавить рамку.

    Давайте попробуем (заодно немного приукрасим наш блок):

    Что у нас получилось:

    Как видите немного не тот результат, какой мы ожидали.

    Почему так произошло?
    Всё дело в том, что, задав картинке выравнивание по левому краю (float:left), мы вырвали её из потока документа. Таким образом граница родителя .preview высчитывается, исходя из размеров последнего дочернего элемента в потоке, а именно по границе внутреннего текста.

    В итоге встаёт вопрос — как же сделать так, чтобы наш блок выглядел красиво? Так, чтобы фоновый цвет с рамкой захватывал всю необходимую нам область превьюшки?
    Конечно, можно добавить текста, чтобы его было больше, чем размер картинки. Т.е. нижняя граница текста визуально будет ниже картинки. Тогда всё будет так, как нам надо:

    Но это не наши методы 🙂

    И так, какие у нас есть варианты?

    Существует 3 способа вернуть в поток элемент, вырванный из этого же потока:
    1. дополнительный элемент со специальным CSS-свойством, очищающим поток документа: clear:both;
    2. CSS-свойство overflow:hidden;
    3. Так называемый clearfix.

    Теперь давайте поподробнее.
    1. Вставим внутрь .preview новый элемент и зададим ему стиль clear:both;

    Как видите мы добились того, чего хотели. Забегая вперёд, скажу, что этот результат достигается всеми тремя способами.

    Что же произошло? Читаем описание css-свойства clear:

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

    У clear есть 3 основных значения: left, right, both. Таким образом, применяя clear мы очищаем поток с левой, с правой или обеих сторон.

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

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

    3. Clearfix. Это название css-класса, имя которго сложилось исторически 🙂
    Существует несколько вариантов такого класса, рабочих и не очень. Я лишь приведу тот, которым пользуюсь я сам:

    Не буду подробно расписывать что здесь и зачем, это уже выходит за рамки данной статьи (это всегда можно нагуглить).
    Добавив данный класс нашему блоку .preview мы так же добиваемся необходимого нам внешнего вида:

    И так, подведём итог.
    Все способы работают и все работают кроссбраузерно.
    Но:
    1й способ не семантичный, а семантику необходимо соблюдать. Зачем? Почитайте.
    2й и 3й способ одинаково хороши для подавляющего большинства случаев.

    Единственно, что хотелось бы сказать, что, применяя overflow:hidden, не забывайте, что всё, что выходит за границы блока — будет скрыто. Например, вам надо добавить какую-нибудь абсолютно спозиционированную рюшечку внутрь блока (например всплывающее сообщение), которая быдет выходить за его границы. Тогда используйте 3й способ. Просто добавьте класс clearfix к элементу и результат вас порадует.

    Время обновить clearfix

    Clearfix — вспомогательный класс в css, с помощью которого мы исправляем схлопывающиеся размеры контейнера у плавающих элементов.

    Clearfix раньше

    Если вы знаете что такое clearfix, то вероятно вы читали о нем в старых статьях и книгах. В которых встречали следующий код или его разновидности:

    Он рабочий, но проблема в том, что он поддерживает устаревшие IE 6/7 . Вы еще поддерживаете эти браузеры?

    Clearfix сейчас

    Если у вас поддержка браузеров начиная с IE 8 , то воспользуйтесь сокращенной версией:

    Немножко экономии и эстетической красоты ��
    Я редко пользуюсь этим классом, ведь установив у контейнера значение overflow в hidden или auto мы добиваемся тех-же результатов.
    А вы используете clearfix css в своих проектах? ��

    UPD #1: Хорошая статья про виды clearfix и их работе можно прочитать в этой статье.

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

    Новый способ очистки «плавающих» блоков

    Clearfix — полезный метод для очистки плавающих блоков. Оригинальный clearfix hack работает просто великолепно, но браузеры устаревают, и нужно двигаться в ногу с прогрессом.

    Internet Explorer 5 для Mac — это уже история, поэтому нет никакой необходимости беспокоиться об очистке в этом браузере (сугубо личное мнение).

    Можно вообще отказаться и от поддержки Internet Explorer 5.5, 6.0, так как доля этих браузеров постоянно снижается и равна менее десяти процентов.

    Оригинальный метод очистки плавающих блоков

    Конечно, смотрится это ужасно, зато работает, работает, как нужно верстальщику. Логика данного подхода очевидна:

    • Для адекватных браузеров срабатывает первое правило — создание скрытого блока после текущего элемента (это аналогично использованию трюка
      , но только без дополнительной разметки).
    • Вторая декларация ( inline-table ) исключительно для IE/Mac.
    • При помощи обратного слеша (backslash) в комментариях прячем оставшуюся часть правил от IE/Mac.
    • Переключаем свойство hasLayout в IE6, задав высоту, равную 1% (holly hack)
    • Затем применяем display:block для всех обозревателей, кроме IE/Mac
    • Последней строкой закрываем хак для IE/Mac

    Как вы можете заметить, здесь очень много мусора из-за поддержки «мертвых» браузеров. Сейчас уже никто не использует IE/Mac, поэтому хак, относящийся к нему можно смело удалить. В результате получаем значительно более чистый кусок CSS кода

    Современный метод очистки плавающих блоков

    Что изменилось по сравнению с предыдущим методом?

    • Выкинули поддержку браузера IE/Mac
    • Для браузеров IE6, IE7 включили hasLayout при помощи zoom: 1 , используя хак со звездочкой

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

    Браузер IE8 уже поддерживает псевдо-класс :after , поэтому в скором времени метод очистки плавающих блоков станет еще проще и понятнее, а динозавры вроде IE6 и IE7 сами собой отомрут.

    Улучшаем clearfix :: Хранитель заметок

    Улучшаем clearfix

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

    Clearfix

    В статье «Everything you know about clearfix is wrong» подробно рассмотрены особенности использования этого метода в различных браузерах. Самым часто встречающимся «странным» поведением этого метода является схлапывающиеся отступы у блока. Например, в Safari или Firefox этих отступов нет, а в IE они есть.

    Итак, чтобы поведение этого метода в разных браузерах было одинаковым его нужно немного улучшить с помощью дополнительного правила

    Внимание! Нельзя просто заменить правила clearfix в существующих проектах, так как, возможно, вы уже исправили проблему схлапывающихся отступов с помощью других методов.

    Overflow

    Подводным камнем этого метода является то, что утверждение «Если поместить абсолютно спозиционированный блок внутри контейнера с overflow: h >position: absolute контейнером будет служить ближайший предок с установленным стилем position в одно из значений absolute, relative или fixed. Это значит, что элемент с абсолютным позиционированием будет виден до тех пор пока его контейнер имеет статичное позиционирование.

    Альтернативный способ

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

    Топ-пост этого месяца:  Как сделать наложение заголовка на картинку
    Добавить комментарий