Концепция float возможно одна из самых неинтуитивных концепций в CSS, ее непонимание часто приводит к искажению страницы, проблемам с читабельностью и юзабилити. Тем не менее, причина этого не в самой теории, а в том, как ее интерпретируют разработчики браузеров.

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

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

Что нужно знать о float

  • Обтекание изображения текстом используется уже много лет, поэтому оно появилось и в веб, сначала в Netscape 1.1, а затем CSS сделал его возможным с помощью свойства float.

    Обтекание текстом плавающего блока

    [Containing Floats]
  • Элемент с установленным свойством float позиционируется вне основного потока и смещается влево или вправо насколько это возможно. Содержимое страницы обтекает такие элементы. Если элемент вынесен из основного потока, то содержимое основного потока полностью его игнорирует и не оставляет для него места. [Float Positioning]
  • Элементы с установленным свойством float автоматически становятся элементами уровня блока, потом этот блок смещает влево или вправо. Свойство float может принимать значения right, left и none. [Floatutorial: Float Basics]
  • Вы должны обязательно устанавливать ширину для плавающих элементов (за исключением изображений, потому что для них ширина всегда подразумевается), если ширина не установлена, результаты могут быть непредсказуемыми. [Floatutorial: Float Basics]
  • Во-первых, для плавающих блоков должна быть задана ширина, неважно явным или косвенным образом, иначе он заполнит родительский блок, как и обычные не плавающие блоки, не оставив места для обтекания остальным контентом. Во-вторых, в отличие от элементов в основном потоке, вертикальные границы плавающих блоков не объединяются с границами прилежащих блоков. И последнее, плавающий блок может перекрывать элементы уровня блока, смежные с ним в нормальном потоке.

    Позиционирование в CSS: Float

    [CSS Positioning: Floats]
  • Первое, что мы должны запомнить это то, что плавающие блоки смещены влево или вправо, нельзя создать плавающий в центре элемент, это иногда расстраивает новичков. [Float Layouts]
  • Когда мы устанавливаем для элемента float, он смещаются к правой или левой границе родительского блока, если установить float в том же направлении, для еще одного элемента он будет смещаться к границе предыдущего плавающего элемента, когда элементам перестанет хватать ширины контейнера, они будут перемещаться вниз. [Float Layouts]
  • Плавающий блок позиционируется по вертикали так же, как если бы он был в нормальном потоке, его верхняя граница, выравнивается с верхней границей текущей строки, по горизонтали он смещается к правой или левой границе контейнера настолько, насколько это позволяют отступы контейнера. Остальной контент обтекает его с противоположной стороны. [CSS Positioning: Floats]
  • Поскольку плавающие блоки находятся вне основного потока, непозиционируемые элементы возле него располагаются, как будто его нет, но строки в них становятся короче, чтобы освободить место для плавающего блока.

    Рисунок, иллюстрирующий наложение перемещаемого объекта и границ двух абзацев: графический объект разрывает границы

    [W3C Visual Formatting Model]
  • Если на текущей строке плавающему блоку не хватает горизонтального пространства, он смещается на одну строку, пока места не станет достаточно. [Floatutorial: Float Basics]
  • Плавающий элемент никогда не поднимается выше строки, в которой создан, его верхняя граница выравнивается с верхней границей этой строки (или с нижней границей предыдущего блочного элемента, если нет соответствующей строки). [Float Layouts]
  • Потенциальная проблема при использовании плавающих элементов в свою очередь содержащих плавающие элементы в том, что корректность отображения страницы во многом зависит от браузера. Ситуация усложняется еще сильнее если эти элементы являются частью сложной разметки. [Containing Floats]

Клиринг

  • Элементы, следующие за плавающим элементом, будут обтекать его, если вы не хотите этого, нужно применить к ним свойство clear. Свойство clear может принимать четыре значения left, right, both, none. [Floats and “clear”]
  • Существуют различные техники клиринга плавающих элементов без дополнительной разметки. Во-первых, использовать float для родительского элемента. Во-вторых, использовать overflow:hidden для родительского элемента. В-третьих, генерировать контент с помощью псевдо класса :after. Их работу можно проверить на тестовой странице. [How to clear CSS floats without extra markup]
  • Стандартный метод принуждения родительского элемента растягиваться на всю высоту плавающего потомка, использование элемента «clearer» который нужно разместить после плавающего элемента. [How To Clear Floats Without Structural Markup]
<div> <!-- float container -->
    <div style="float:left; width:30%;"><p>Some content</p></div>
    <p>Text not inside the float</p>
    <div style="clear:both;"></div>
</div>
  • Распространенная проблема с разметками, основанными на плавающих элементах, состоит в том, что родительский элемент не растягивается по вертикали, чтобы полностью поглотить плавающие элементы, это серьезная проблема, если вы хотите добавить бордер к такому элементу или задать для него фон. Одно из решений этой проблемы заключается в использовании overflow.

    Клиринг плавающих блоков

    [Clearing floats]
  • С помощью псевдо класса :after можно добавить символ, к примеру точку, и установить для него clear:both, а чтобы он не влиял на внешний вид страницы используем height:0 и visibility:hidden. [How To Clear Floats Without Structural Markup]
.clearfix:after {
    content: ".";
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
}

Баги связанные с float

  • Если в элементе контейнере есть ссылки после плавающего элемента, подсвечивающиеся при наведении мышки, то можно наблюдать, как нижняя граница контейнера вдруг прыгает к нижней границе не плавающего контента. Наведение мышки на другие ссылки все исправляет, этот интересный эффект назван IE/Win Guillotine Bug. Эффект наблюдается только если при наведении мышки меняется фон ссылки и многие другие свойства, такие как отступы, поля или параметры шрифта. Странно, но если изменяется только цвет ссылки, эффект не наблюдается.

    Баг IE/Win Guillotine

    [How To Clear Floats Without Structural Markup]
  • IE Escaping Floats Bug: Если вы используете элемент с полями, границами и некоторым количеством элементов с установленным float:left, вы получите две ошибки в IE Win. Первая заключается в том, что контейнер будет содержать только последнюю линию плавающих элементов. Вторая в том, что крайние справа элементы будут выходить за пределы экрана, из-за чего появляется горизонтальная полоса прокрутки на многих разрешениях. Это происходит из-за того, что IE использует нестандартное поведение относительно блочной модели и единиц измерения. Holly Hack: assigning a height to the element, i.e. height: 1%;.

    Баг IE Escaping Floats
  • Win/IE6 Peekaboo Bug: Если элемент имеет внутри плавающий элемент и контент который его обтекает. В IE6 контент иногда исчезает, но если скролить страницу вниз или переключиться на другое окно и вернуться, то он снова на месте. К счастью эта ошибка исправлена в IE7.

    Баг Win/IE6 Peekaboo
  • IE/Win добавляет правую границу в 3px всем блокам с float:left, которую нельзя убрать, что бы вы ни делали. Чтобы посмотреть, как это выглядит, проверьте сначала floating bug, а потом double float fix. Этот баг еще называют IE Three Pixel Text-Jog. [Floating Bugs].
  • IE Duplicate Character Bug: В IE 6 есть очень странный баг, возникающий при использовании нескольких плавающих элементов. Текст последнего плавающего элемента, иногда дублируется после него. Причиной этого служит комментарий, заключенный между плавающими элементами. Bugfix.

    IE Duplicate Character баг

    [IE Duplicate Character Bug]
  • Одна из распространенных задач это размещение плавающих изображений слева и справа страницы, чтобы текст обтекал их. В таких случаях добавление clear к изображению гарантирует, что каждое следующее будет размещаться ниже предыдущего. Но использование свойств clear и float в одном элементе может приводить к большим промежуткам в IE — исправление которых, требует использования более сложных стилей, чем те, что мы применяли для исправления предыдущих багов. Bugfix. [Close Gaps Next to Floated Images in Internet Explorer]
  • Чтобы отодвинуть элемент с float:left от левой границы, можно задать левое поле элемента, но в IE его величина будет удвоена. [The IE Doubled Float-Margin Bug]
  • В IE/Win есть баг, приводящий к тому, что inline элементы смежные с плавающим div несколько смещены относительно ожидаемых позиций. The indentation is caused by IE/Win’s weird handling of margins on floated elements. [Floats, Margins and IE]
  • Есть простое решение, исправляющее множество багов в IE. Все плавающие элементы автоматически становятся блочными элементами, в стандарте сказано, что любые значения свойства display кроме none для них игнорируются, тем не менее, если установить для плавающих блоков display:inline, большинство багов IE пропадают, а блоки не становятся inline. [Float Layouts]
  • Использование float и отрицательных полей делает ссылки в элементе недоступными в Safari 1.3 и Safari 2.0, выделение текста тоже усложняется, и если вы используете Tab для переключения между ссылками, они исчезают при потере фокуса. Чтобы исправить этот баг нужно использовать position:relative для всех плавающих элементов с отрицательными границами. [Float + negative margin problems in Safari]
  • IE7 корректно выполняет спецификации W3C в области свертывания контейнеров содержащих плавающие элементы. Но поскольку он не поддерживает свойство content то метод easy clearing для него не подходит, overflow подходящий метод для всех версий IE. [Clearing floats without sructural markup in IE7]
#content { overflow : hidden; _height : 1%; }

Уроки и техники

Похожие статьи