вторник, 4 января 2011 г.

CSS: Всё о float

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


Что такое "float"?

Float это свойство CSS позиционирования. Что бы понять его суть и происхождение нужно обратить своё внимание на печатный дизайн. В печатных макетах изображение может быть расположено так, что текст обтекает его. Обычно это и называется "обтекание текстом".

Print Layout

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

Web Layout

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

Установка свойства float для элементов с помощью CSS выглядит следующим образом:

#sidebar {
   float: right;
}

Есть четыре допустимых значения для свойства float - left, right, none, inherit. Первые два, left и right указывают направления расположения - слева и справа, соответственно. None - значение по умолчанию, указывает что элемент не плавающий и inherit указывающий элементу наследовать значение свойства float от родительского элемента.


Для чего используется float?

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


Float, так же удобно использовать для небольших элементов макета. К примеру, возьмём этот небольшой фрагмент веб страницы. Если мы установим свойство float для небольшого изображения аватара, то когда изменится размер изображения обтекание измениться в соответствии с новыми размерами изображения:


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



Сброс обтекания

Clear родственное свойство свойству float. Элемент с установленным свойством clear не будет двигаться вверх обтекая элемент с установленным свойством float, но будет смещаться вниз игнорируя обтекание. И снова иллюстрация, которая объяснит всё без лишних слов.


В приведённом выше примере, боковая панель "плавала" справа от блока основного контента. "Подвал" переместился в свободное место под боковой панелью, обтекая блок с основным контентом. Для решения этой проблемы необходимо указать значение свойства clear:both "подвала" для "очищения" обтекания обоих столбцов.

#footer {
   clear: both;
}

Свойство clear имеет четыре значения. Both используется для сброса обтекания в обоих направлениях. Left и Right используются для сброса одного направления - левого или правого, соответственно. None - значение по умолчанию. Inherit может быть пятым значением, но оно на удивление не поддерживается Internet Explorer. Сброс только левого или правого обтекания встречается довольно редко, но имеет практическую пользу.



Великий коллапс

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


Но альтернатива такого коллапса ещё хуже. Рассмотрим следующий сценарий:


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

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


Техники отмены обтекания

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

Метод пустого блока.

Это в буквальном смысле пустой блок. <div style='clear:both;'></div>. Иногда можно встретить элемент <br/> или любой другой случайный элемент, но div наиболее распространён поскольку он не имеет в браузерах стиля по умолчанию, не имеет специальной функции и вряд ли будет в общем стиле CSS. Этот метод отвергают семантические пуристы поскольку его присутствие не имеет контекстного смысла на странице и он расположен там только для внешнего вида. Конечно, в строгом смысле они правы, но он выполняет свою работу и никому не вредит.

Метод переполнения.

Основан на указании CSS свойства overflow для родительского элемента. Если это свойство установлено в auto или hidden для родительского элемента, то он будет расширятся вслед за плавающим элементом эффективно сбрасывая обтекание его для последующих элементов. Этот метод может быть семантически красив, так как не требует дополнительных элементов. Однако, как вы видите мы добавили новый div для использования этого метода, что эквивалентно использованию не семантического пустого блока и менее гибко. Так же следует помнить, что свойство overflow предназначено не для отключения обтекания. Будьте осторожны что бы случайно не скрыть контент или вызвать нежелательные полосы прокрутки.

Метод лёгкой очистки.

Использует CSS псевдо-селектор (:after) для удаления обтекания. Вместо использования свойства overflow для родительского элемента установите дополнительный класс для него, например 'clearfix' и используйте следующий стиль CSS:

.clearfix:after {
   content: ".";
   visibility: hidden;
   display: block;
   height: 0;
   clear: both;
}

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

Разные ситуации требуют разных методов сброса обтекания. Возьмём для примера сетку разнотипных блоков.


Для лучшего визуального объединения аналогичных блоков мы должны начинать новую строку когда меняется цвет. Мы можем использовать метод переполнения или лёгкой очистки, если у каждой цветовой группы есть родительский элемент. Или используем метод пустого блока между группами. Три родительских блока, которых ранее не существовало или три пустых блока, которых ранее не существовало. Вам решать какой метод лучше.



Проблемы с плавающими элементами

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

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


Быстрое решение проблемы: используйте overflow: hidden; для обрезания излишков.

Баг с двойными полями (double margin bug) - ещё одна вещь о которой необходимо помнить работая с IE6. Этот баг выражается в том, что если поле находится с той же стороны куда ориентирован float, поле удваивается. Например:

#content {
     float: left;
     width: 500px;
     padding: 10px 15px;
     margin-left: 20px; }

Мы получим слева поле в 40 px., вместо 20 px.

Быстрое решение проблемы: установить display: inline для плавающего блока, и не волнуйтесь элемент останется блочным.

3х пиксельный толчок (3px Jog). Суть этого бага в том, что текст расположенный рядом с плавающим элементом странным образом смещается на три пикселя, как будто под воздействие силового поля расположенного вокруг плавающего элемента. Быстрое решение проблемы: установить ширину и высоту пострадавшего текста.

В IE7 появляется Баг нижнего отступа (bottom margin bug), когда родительский элемент является плавающим и его потомок расположенный внутри него тоже плавающий элемент. Нижнее поле (margin-bottom) потомка игнорируется, элементом предком. Быстрое решение проблемы: Использовать нижнее поле (padding-bottom) в родительском элементе, вместо нижнего отступа (margin-bottom) потомка.

Оригинальная статья: All About Floats

Похожие по тематике посты:

6 комментариев:

Анонимный комментирует...

Спасибо, мне и моему другу было интересно и полезно это почитать

snake.nf комментирует...

Мне самому было интересно по читать, по этому и сделал перевод, хотя к концу перевода наткнулся на ещё несколько вариантов перевода этой же статьи.

Анонимный комментирует...

Огромное спасибо за перевод!

До этого копипастил в переводчик, а с ним так не понятно и долго.

Молодец!!

Анонимный комментирует...

Спасибо за статью! Весьма доступно!

Анонимный комментирует...

Спасибо за материал!

Анонимный комментирует...

Спасибо за перевод, не мог найти причину почему на меня ругалась программа... нашел единственный ответ здесь... два вопроса...я видел что многие используют clear fix метод, но многие используют только одну строчку - clear:both в css, также зачем нужен float, если есть inline block метод, без очевидных, по крайней мере для меня, заморочек...