- Способы отмены обтекания (float) в HTML
- Типичный случай HTML верстки
- Способ 1: метод старой школы
- Способ 2: свойство overflow
- Способ 3: класс “clearfix”
- Способ 4: значение contain-floats для min-height
- Как избавится от float
- Для чего можно использовать float?
- Отмена свойства float
- Большой коллапс
- Способы отмены float
- Проблемы с float
- Альтернативы float
- Проблемы float и их решения
- Проблема 1. Обтекание влияет на другие элементы
- Проблема 2. Нулевая высота контейнера с float-элементами
- Проблема 3. Перенос блоков при добавлении отступов
Способы отмены обтекания (float) в HTML
Прежде чем мы углубимся в методы очистки потока, давайте взглянем на проблему, которую мы пытаемся решить.
Типичный случай HTML верстки
Блоки .el-1 и .el-2 размещаются бок о бок внутри контейнера .container, и один элемент .main следует после .container:
Мы хотим, чтобы высота контейнера .container была равной высоте самого длинного из его дочерних элементов (т.е. либо .el-1, либо .el-2) и чтобы блок .main, чтобы был после блока .container.
А вот, что мы видим: .container (черная рамка) схлопнулся, как будто в нем ничего нет, блок .main (блок с рыжим фоном) находится под блоком .container, как мы и хотели, но при этом он прячется за блоки .el-1 (с желтым фоном) и .el-2 (с розовым фоном). Черт знает что! Видел бы это мой начальник — непременно сказал бы мне,- «Используй, Шурик, табличную верстку». К счастью, времена, когда web-страницы верстались таблицами уже давно прошли и мы отлично обойдемся и без них. Не верите? Читайте дальше.
Несмотря на то, что многие считают это багом браузера, — это всего лишь принцип, по которому работают плавающие элементы. Следовательно нам нужно заставить родительский элемент расширяться, чтобы полностью вмещать дочерние элементы. Тогда, следующие элементы будут располагаться под контейнером.
Способ 1: метод старой школы
Как вам известно, CSS свойство clear устанавливает с какой стороны элемента запрещено его обтекание другими элементами, следовательно это свойство может предотвратить налезание элементов поверх плавающих. Идея заключается в следующем: вставьте пустой элемент, который свойство clear под обтекаемыми блоками. Это использовать определенный класс для подобного элемента — давно устоявшаяся традиция, так что вы можете использовать его в вашем HTML. Вот классический CSS код:
Который применим к нашей HTML верстке:
Наш демо-пример, реализуемый с помощью этого метода:
Если вас не волнует схлопывающийся контейнер, а только неправильно расположенный блок .main, то вы можете также поместить «очищающий поток» элемент br после контейнера. Но, если вы решите сделать так, то гораздо проще будет просто добавить свойство clear самому элементу .main.
Это простой и понятный метод. Тем не менее, в современной верстке практикуется отделение контента от стиля, поэтому лучше его не использовать.
Способ 2: свойство overflow
Используя свойство overflow в теге .container, мы можем заставить контейнер расшириться до высоты размещенных элементов. Наш CSS будет выглядеть следующим образом:
Наш HTML останется таким же, каким и был изначально, без дополнительных элементов. Вот, что мы получим в итоге:
К сожалению, у этого метода есть недостаток: любой дочерний элемент, который выступает за пределы контейнера, будет либо обрезан (в случае overflow: hidden; ), либо вызовет появление полос прокрутки (в случае overflow: auto; ).
Способ 3: класс “clearfix”
Мы создаем класс .clearfix с псевдо-элементами ::before и ::after и задаем им display: table , что создает анонимную ячейку таблицы. Этот класс будет использоваться для очищения плавающих элементов. CSS код выглядит так:
Изменим немного HTML код добавив к классу container класс clearfix:
Вот результат работы наешго новвого класса:
если вам не нужна поддержка браузеров ниже IE8, то наш код значительно сократится:
Способ 4: значение contain-floats для min-height
Спецификация W3C добавила новое значение для свойства min-height (и для других свойств min/max), для решения этой проблемы. Выглядит оно так:
Этот код дает практически тот же эффект, что и clearfix, или overflow, но с помощью одной строки кода и, к тому же он лишен тех недостатков, о которых мы говорили ранее. К сожалению, пока ни один из браузеров не поддерживает это свойство, так что просто имейте его ввиду.
Итак, у вас есть целый набор различных «clearfix» методов. Применение класса .clearfix стало стандартом, и я очень рекомендую использовать его вместо прежних двух методов.
Источник
Как избавится от float
Float — это свойство CSS для позиционирования элементов. Для того чтобы понять его назначение и происхождение, можно обратиться к полиграфическому дизайну. В компоновке при печати, изображения могут располагаться на странице так, чтобы текст «обтекал» их. Обычно это так и называется: «обтекание текстом».
В программах для вёрстки страниц, элементы с текстом, могут учитывать изображения, а также и игнорировать их. В случае если они будут проигнорированы, текст будет отображаться над картинками, как будто их и нет. Это главная разница между тем, являются ли изображения частью основного потока страницы, или нет. Веб-дизайн очень похож.
В веб-дизайне, элементы страницы с установленным свойством float, ведут себя точно также как и изображения в полиграфии, когда текст «обтекает» их. Такие элементы являются частью основного потока веб-страницы. Однако всё обстоит иначе, если элементы используют абсолютное позиционирование. Абсолютно позиционированные элементы удаляются из основного потока страницы, подобно примеру выше, когда в полиграфии текст игнорирует изображения. Такие элементы не влияют на позицию остальных элементов, соприкасаются они или нет.
Установка свойства float происходит следующим образом:
Всего есть 4 значения для свойства float. Left и right используются для соответствующих направлений. None (по умолчанию) — обеспечивает, что элемент не будет «плавать». И inherit, которое говорит, что поведение должно быть такое же, как и у родительского элемента.
Для чего можно использовать float?
Помимо обтекания текстом изображений, float может использоваться для создания макета всего сайта.
Свойство float также полезно и в меньших масштабах. Для примера рассмотрим маленькую область на странице сайта. Допустим вы используете float для аватара, при изменении размера изображения, размер текста будет подогнан в соответствии с изображением.
Такое же расположение объектов может быть достигнуто путём использования позиционирования. Объекту-контейнеру присваивается относительное (relative) позиционирование, а объекту с изображением — абсолютное (absolute). В этом случае аватар не повлияет на положение текста.
Отмена свойства float
Для float, родственное свойство — clear. Любой элемент, у которого установлено свойство clear, не будет поднят вверх, как от него ожидается, а отобразится ниже, после float-элементов. Возможно, пример на картинке объяснит лучше, чем слова.
В примере, сайд-бар прижат к правому краю (float: right;), а его высота меньше, чем область основного контента. Поэтому footer будет поднят выше, поскольку для него хватает высоты и этого требует поведение float. Чтобы исправить ситуацию, ему необходимо установить свойство clear, которое гарантирует, что элемент выведется ниже float-элементов.
Свойство clear может принимать четыре значения. Both, наиболее используемое, применяется для отмены float каждого из направлений. Left и Right — используются для отмены float одного из направлений. None — по умолчанию, обычно не используется, за исключением случаев, когда необходимо отменить значение clear. Значение inherit было бы пятым значением, но оно странным образом не поддерживается в Internet Explorer. Отмена только левого или правого float, встречается гораздо реже, но, безусловно, имеет свои цели.
Большой коллапс
Ещё одна удивительная вещь при работе со свойством float — это то, что его использование может влиять на родительский элемент. Если такой элемент содержит только float-элементы, то он буквально схлопывается, то есть его высота равна нулю. Это не всегда заметно, если у родительского элемента не установлен какой-либо видимый фон.
Такое схлопывание выглядит нелогичным, однако альтернатива ещё хуже. Рассмотрим такой пример:
Если блочный элемент, располагающийся наверху, будет автоматически увеличиваться, чтобы вместить все float-элементы, то мы получим неестественный разрыв в тексте между параграфами, без всякой возможности это исправить. Если бы было именно так, наши дизайнеры жаловались бы гораздо чаще такому поведению, чем схлопыванию.
Таким образом, схлопывание почти всегда необходимо, чтобы предотвратить трудности в вёрстке. Для того чтобы изменить такое поведение, необходимо добавить элемент отменяющий float после float-элементов, но до закрытия родительского элемента.
Способы отмены float
Если вам известно, что следом после float-элементов, всегда будет выводится какой-либо другой элемент (например футер), то вам достаточно ему установить свойство clear: both;, как в примере выше, и заниматься дальше своими делами. Это идеальный вариант, поскольку он не требует каких-либо хаков, или дополнительных элементов. Конечно не всё в нашей жизни так гладко и бывают случаи когда такого способа не достаточно. Поэтому необходимо иметь несколько дополнительных способов в своём арсенале.
- Метод пустого div-а. Используется, в буквальном смысле, пустой div.
И, как вы понимаете, каждый из способов используется в различных ситуациях. Возьмём, к примеру, сетку из блочных элементов, отличающихся типами.
Для более лучшего визуального представления было бы неплохо объединить подобные блоки. Например мы хотим, чтобы каждый тип начинался с новой строки, в нашем случае тип элемента определяется цветом. Мы можем использовать метод с overflow или «метод простой очистки», если у каждой группы есть свой элемент-контейнер. Или же мы можем использовать метод пустого div-а между каждой из групп. Три элемента-контейнера, или три пустых div-а, что лучше для вашей задачи — решать вам.
Проблемы с float
Float часто стараются обходить, поскольку работать с ними надо очень аккуратно. Большинство ошибок пришло вместе с IE6. Поскольку всё больше и больше веб-дизайнеров отказываются от поддержки IE6, то вас могут и не волновать эти проблемы. Но для тех, кому не всё равно, вот краткий список.
- «Выталкивание» (pushdown). Возникает когда элемент внутри float-элемента оказывается шире его (обычно это изображения). Большинство браузеров обработает такие элементы вне float-структуры и вёрстка не будет сломана. IE расширит элемент, чтобы изображение влезло, зачастую это ломает дизайн. На картинке представлен пример, как изображение торчит из основного контента и таким образом «выталкивает» сайд-бар вниз.
Самый просто способ избежать этого — это проверить что все ваши изображения подходят по ширине. Можно использовать overflow: hidden;, чтобы обрезать выступающую часть.
- Двойной внешний отступ. Ошибка проявляющаяся в IE6, в случае если вы устанавливаете внешний отступ в том же направлении, в котором у вас указан float. В этом случае отступ удваивается. Чтобы исправить это, необходимо установить плавающему (float) элементу свойство display: inline;, не беспокойтесь, элемент по прежнему будет блочным.
- Трёх-пиксельный прыжок (3px Jog). Ошибка, которая проявляется следующим образом: текст, который расположен рядом с float-элементом неожиданно съезжает на 3 пикселя. Чтобы избежать этого, необходимо установить ширину или высоту пострадавшему тексту.
- В IE7 существует Ошибка нижнего внешнего отступа (Bottom Margin Bug) — возникает когда элемент с установленным свойством float, содержит в себе ещё один float-элемент. В таких случаях, нижний внешний отступ дочернего элемента игнорируется. Для обхода этой проблемы необходимо использовать внутренний отступ родительского элемента, вместо внешнего отступа дочернего.
Альтернативы float
Если вам необходимо обтекание картинки текстом, то альтернатив нет. Но для макета страницы, определённо есть выбор. Существуют очень интересные подходы, в которых комбинируется гибкость float с мощью абсолютного позиционирования. В CSS3 есть, так называемый, Модуль разметки шаблона (Template Layout Module), который в будущем предоставит достойную альтернативу float.
Источник
Проблемы float и их решения
В процессе верстки с использованием float-элементов вы непременно заметите некоторые странности в их поведении. Мы расскажем о наиболее часто встречающихся проблемах и способах их решения.
Проблема 1. Обтекание влияет на другие элементы
На первом уроке по свойству float мы рассмотрели пример, где футер, расположенный сразу за плавающими блоками, ведет себя странно, прижимаясь верхним краем к низу float-элемента. Это происходит из-за того, что, по сути, футер обтекает боковую панель, но поскольку он занимает 100% ширины, то обтекание выражается лишь прижиманием к нижнему краю, без перемещения по горизонтали.
На примере ниже более явно показано, что происходит с элементом, который должен обтекать соседний элемент, но при этом им не хватает места в одном ряду:
Элемент с классом .b4 пробует обтекать float-элемент .b3 , содержащийся в контейнере .wrapper , но поскольку .b4 не влазит в один ряд с .wrapper , он просто прижимается верхней стороной к этому ряду, из-за чего между блоками не остается свободного пространства. Как видите, элементу .b4 дополнительно задано свойство margin-top: 50px , эффект которого сейчас не заметен. Не зная причины, можно долго ломать голову, почему margin не работает. Однако, если посмотреть на элемент через инспектор кода, можно увидеть, что margin-top всё же работает, просто сейчас он никак не влияет на картину.
Как сделать, чтобы элемент .b4 перестал обтекать соседний? Конечно же, с помощью свойства clear , которое мы уже рассматривали ранее. Повторим еще раз:
Добавив этот код, мы получили такую картину:
Уже лучше, но отступ в 50 пикселей сверху так и не появился. Он всё ещё накладывается на верхний блок:
Такое впечатление, что элементу со свойством margin-top нет от чего отталкиваться. На самом деле, так и есть, потому что если мы проинспектируем элемент .wrapper , то увидим, что его высота странным образом стала равна нулю:
Проблема 2. Нулевая высота контейнера с float-элементами
Еще одна проблема при работе с float-элементами заключается в том, что блок, содержащий плавающие элементы, теряет свою высоту, поскольку свойство float исключает элементы из нормального потока. Высота родительского контейнера изменяется следующим образом:
- Если в контейнере содержатся только плавающие элементы, то его высота станет нулевой. Либо, если родителю задано, к примеру, свойство padding-top и/или padding-bottom , то его высота будет равна сумме этих padding-ов.
- Если в родительском контейнере помимо float-элементов имеются также обычные элементы, то высота родителя будет равна высоте этих обычных элементов плюс отступы.
Иными словами, из высоты блока-родителя просто вычитается высота float-элементов.
Как заставить родительский контейнер учитывать высоту содержащихся в нем плавающих элементов? Есть несколько способов решения этой проблемы. Мы расскажем о двух наиболее распространенных и эффективных хаках:
Micro Clearfix. Этот хак был придуман разработчиком по имени Nicolas Gallagher, и заключается он в добавлении нескольких строк CSS к псевдоэлементу :after родительского контейнера, потерявшего высоту:
Этот код работает во всех современных браузерах. Преимущество данного способа состоит в отсутствии необходимости писать лишний HTML-код.
Overflow: hidden. Второй вариант решения проблемы с пропавшей высотой контейнера — добавить к этому блоку свойство overflow: hidden . Вообще, данное свойство определяет, будет ли видно содержание блочного элемента, если оно не помещается в него целиком и выходит за пределы области. Однако в данном случае оно еще и заставляет учитывать высоту float-элементов.
У этого метода есть недостаток: если в контейнере находятся абсолютно позиционированные элементы, размещенные за пределами его границ, то они могут исчезнуть из поля зрения. Впрочем, то же самое произойдет с любым содержимым, которое будет вылезать за область контейнера — такова работа значения hidden.
Итак, воспользуемся первым хаком и взглянем на результат:
Как видим, высота блока-родителя стала включать в себя плавающие элементы, а у элемента .b4 теперь нормально отображается верхний отступ в 50 пикселей.
Проблема 3. Перенос блоков при добавлении отступов
После создания колонок с помощью float вы наверняка захотите наполнить их содержимым. В нашем примере есть три колонки одинаковой ширины, которые идеально помещаются в один ряд. Давайте добавим немного контента в каждую из них:
Выглядит неплохо, но нам не хочется, чтобы текст примыкал так сильно к боковым сторонам блоков. Чтобы сделать небольшие промежутки между текстом и внутренними границами блока, мы добавим padding слева и справа (сейчас он добавлен только сверху и снизу в размере 40 пикселей, а для боковых сторон указан 0):
И здесь у нас появляется проблема: одна из колонок съехала вниз. Это случилось из-за того, что ширина каждой колонки стала равна не 33.333333% , а 33.333333% + 10px + 10px. Как вы помните из предыдущего раздела учебника, полная ширина блока — это сумма чисел, в которую включена ширина содержимого, а также размеры боковых отступов, границ и полей.
Чтобы исправить эту проблему, используйте свойство box-sizing со значением border-box . Тогда браузер будет автоматически включать отступы, поля и рамку в заданную вами ширину блока:
Рекомендуем при создании сетки в CSS заблаговременно прописывать box-sizing , чтобы застраховаться от выпадания блоков при дальнейшей работе с сеткой.
Таковы основные проблемы, которые встречаются у float-элементов и могут быть легко решены. Безусловно, существуют и другие трудности, и некоторые из них порой нельзя обойти простым способом. Однако, зная принципы работы float и помня о вышеперечисленных недостатках, вы уже сэкономите много времени и нервов во время верстки.
Далее в учебнике: что такое адаптивный веб-дизайн.
Источник