Сейчас я расскажу про поток документа, с чем его едят, проблемы с 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:
У clear есть 3 основных значения: left, right, both. Таким образом, применяя clear мы очищаем поток с левой, с правой или обеих сторон.
Этот способ рабочий, но не семантичный. Дополнительных, не нужных элементов можно и нужно избегать всеми силами, чтобы не нарушать семантику документа.
2. overflow:hidden. С помощью этого стиля, задав его блоку родителю, создается новый контекст форматирования. Результат такой же, как и с прошлым способом.
Но у браузеров на движке Gecko (Firefox и ему подобные) есть неприятная особенность: текст в блоках, для которых задан overflow:hidden (либо auto) не выделяется дальше границ этого блока. Но эта особенность лично мне никак не мешала.
3. Clearfix. Это название css-класса, имя которго сложилось исторически :-)
Существует несколько вариантов такого класса, рабочих и не очень. Я лишь приведу тот, которым пользуюсь я сам:
Не буду подробно расписывать что здесь и зачем, это уже выходит за рамки данной статьи (это всегда можно нагуглить).
Добавив данный класс нашему блоку .preview мы так же добиваемся необходимого нам внешнего вида:
А чтобы было совсем красиво, уберём у картинки нижний отступ, изменив стиль margin:0 10px 0 0 :
И так, подведём итог.
Все способы работают и все работают кроссбраузерно.
Но:
1й способ не семантичный, а семантику необходимо соблюдать. Зачем? Почитайте.
2й и 3й способ одинаково хороши для подавляющего большинства случаев.
Единственно, что хотелось бы сказать, что, применяя overflow:hidden, не забывайте, что всё, что выходит за границы блока - будет скрыто. Например, вам надо добавить какую-нибудь абсолютно спозиционированную рюшечку внутрь блока (например всплывающее сообщение), которая быдет выходить за его границы. Тогда используйте 3й способ. Просто добавьте класс clearfix к элементу и результат вас порадует.
На сегодня всё, ждите новых рецептов! :-)
Итак, поток.
В браузерном мире и мире вёрстки есть понятие "потока документа". В HTML формирование элементов на странице происходит сверху вниз согласно схеме документа. Соответственно, блок, расположенный в коде выше, будет показан раньше, чем блок, расположенный ниже. Вот этот порядок вывода блоков страницы и называется потоком.
Вырвать любой элемент из потока можно несколькими способами.
Это:
- задать блоку абсолютное позиционирование - position:absolute;
- задать блоку фиксированное положение на странице - position:fixed;
- и задать элементу обтекание - float:left, float:right.
Если с первыми двумя всё достаточно тривиально (нужно лишь указать координаты начальной позиции блока top|bottom и left|right, и не забыть, что при абсолютном позиционировании отсчёт ведётся от ближайшего родителя с position:relative (или от начала документа, если такового не имеется)), то со вторым способом могут оказаться проблемы.
Представим себе ситуацию.
У нас есть превьюшка какого-то поста с текстом и картинкой, в котором картинка выровнена по левому краю:
Код простейший:
.preview{ margin:40px; width:600px; padding:5px; } img { float:left; margin:0 10px 10px 0; }
<div class="preview"> <p><img src="/google.logo.png" width="250" /> Это Google. Лидер мирового поиска. Lorem ipsum dolor sit amet, aliquam pellentesque nunc et quam elementum ornare. Quisque tortor sapien, aliquam in luctus a, fringilla ac ante. Suspendisse potenti. Mauris faucibus justo tortor. </p> </div>
И вот всё вроде бы хорошо, всё вроде бы смотрится, всё замечательно... Да? Да!
Но ровно до тех пор, пока нам не понадобится декорировать этот блок, например задать фоновый цвет, или добавить рамку.
Давайте попробуем (заодно немного приукрасим наш блок):
.preview{ margin:40px; width:600px; background:#F3F3F3; padding:10px; border:1px solid #E5E5E5; font:13px/16px Tahoma; } img { float:left; margin:0 10px 10px 0; } p { margin:0; }
Что у нас получилось:
Как видите немного не тот результат, какой мы ожидали.
Почему так произошло?
Всё дело в том, что, задав картинке выравнивание по левому краю (float:left), мы вырвали её из потока документа. Таким образом граница родителя .preview высчитывается, исходя из размеров последнего дочернего элемента в потоке, а именно по границе внутреннего текста.
В итоге встаёт вопрос - как же сделать так, чтобы наш блок выглядел красиво? Так, чтобы фоновый цвет с рамкой захватывал всю необходимую нам область превьюшки?
Конечно, можно добавить текста, чтобы его было больше, чем размер картинки. Т.е. нижняя граница текста визуально будет ниже картинки. Тогда всё будет так, как нам надо:
Но это не наши методы :-)
И так, какие у нас есть варианты?
Существует 3 способа вернуть в поток элемент, вырванный из этого же потока:
1. дополнительный элемент со специальным CSS-свойством, очищающим поток документа: clear:both;
2. CSS-свойство overflow:hidden;
3. Так называемый clearfix.
Теперь давайте поподробнее.
1. Вставим внутрь .preview новый элемент и зададим ему стиль clear:both;
<div class="preview"> <p><img src="/google.logo.png" width="250" /> Это Google. Лидер мирового поиска. Lorem ipsum dolor sit amet, aliquam pellentesque nunc et quam elementum ornare. Quisque tortor sapien, aliquam in luctus a, fringilla ac ante. Suspendisse potenti. Mauris faucibus justo tortor. </p> <div style="clear:both"></div> </div>
Результат:
Как видите мы добились того, чего хотели. Забегая вперёд, скажу, что этот результат достигается всеми тремя способами.
Что же произошло? Читаем описание css-свойства clear:
Устанавливает, с какой стороны элемента запрещено его обтекание другими элементами. Если задано обтекание элемента с помощью свойства float, то clear отменяет его действие для указанных сторон.
У clear есть 3 основных значения: left, right, both. Таким образом, применяя clear мы очищаем поток с левой, с правой или обеих сторон.
Этот способ рабочий, но не семантичный. Дополнительных, не нужных элементов можно и нужно избегать всеми силами, чтобы не нарушать семантику документа.
2. overflow:hidden. С помощью этого стиля, задав его блоку родителю, создается новый контекст форматирования. Результат такой же, как и с прошлым способом.
Но у браузеров на движке Gecko (Firefox и ему подобные) есть неприятная особенность: текст в блоках, для которых задан overflow:hidden (либо auto) не выделяется дальше границ этого блока. Но эта особенность лично мне никак не мешала.
3. Clearfix. Это название css-класса, имя которго сложилось исторически :-)
Существует несколько вариантов такого класса, рабочих и не очень. Я лишь приведу тот, которым пользуюсь я сам:
.clearfix:before, .clearfix:after { content: "\0020"; display: block; height: 0; visibility: hidden; } .clearfix:after { clear: both; } .clearfix { zoom: 1; }
Не буду подробно расписывать что здесь и зачем, это уже выходит за рамки данной статьи (это всегда можно нагуглить).
Добавив данный класс нашему блоку .preview мы так же добиваемся необходимого нам внешнего вида:
А чтобы было совсем красиво, уберём у картинки нижний отступ, изменив стиль margin:0 10px 0 0 :
И так, подведём итог.
Все способы работают и все работают кроссбраузерно.
Но:
1й способ не семантичный, а семантику необходимо соблюдать. Зачем? Почитайте.
2й и 3й способ одинаково хороши для подавляющего большинства случаев.
Единственно, что хотелось бы сказать, что, применяя overflow:hidden, не забывайте, что всё, что выходит за границы блока - будет скрыто. Например, вам надо добавить какую-нибудь абсолютно спозиционированную рюшечку внутрь блока (например всплывающее сообщение), которая быдет выходить за его границы. Тогда используйте 3й способ. Просто добавьте класс clearfix к элементу и результат вас порадует.
На сегодня всё, ждите новых рецептов! :-)
Автор, пиши ещё - у тебя хорошо получается
ОтветитьУдалить