Топ контрибуторов
loading
loading
Знаете ли Вы, что

Лучшие IT работодатели регулярно просматривают рейтинги и профили пользователей в поисках кандидатов. Для корректного отображения ваших данных рекомендуем заполнить ваш профиль и добавить информацию о вас и вашей профессии.

Лента обновлений
ссылка 13:45:44
Комментарий от Olga_Mogir:
Не 100%. Есть очень маленькая вероятность (но есть) с...
ссылка 13:32:37
Комментарий от Olga_Mogir:
Цель: при многократном прохождении в обе стороны оста...
ссылка 02:05:51
Комментарий от Blohin:
спасибо за ответ
ссылка Mar 21 22:40
Комментарий от k098:
Не зря видео-конференции на ютубе смотрел на тему "Неадеква...
ссылка Mar 21 22:33
Комментарий от k098:
Понятия не имею, что такое JavaBean, но ответил правильно т...
Статистика

Тестов: 153, вопросов: 8597. Пройдено: 430042 / 2106835.

CSS: свойство float

head tail Статья
категория
Веб технологии
дата26.03.2015
авторAlexVovolka
голосов15

Свойство Float это значимый и мощный актив для web-developer-ов работающих с HTML и CSS. C другой стороны, он может вызывать одно разочарование и путаницу если вы не до конца понимаете как это свойство работает.

css свойство float

Перевод статьи CSS Floats 101. Оригинал alistapart.com

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

Мы видим float каждый день в мире печати, когда рассматриваем статью в журнале с изображением расположенным слева или справа и текстом красиво расположенным вокруг него. В мире HTML/CSS, текст будет обвертывать изображение в зависимости от свойства float, которое применяется к этому изображению. Использование свойства float к изображению, это все лишь один из многих примеров. Еще как пример, с помощью свойства float, мы можем очень легко сделать популярный двухколоночный макет. А на самом деле, вы можете применять свойство float к любому элементу в вашем HTML. Изучив и поняв применение свойства float, вместе с свойством position, вы сможете комфортно и уверенно себя чувствовать при создании любого макета.

Определение float

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

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

Свойство float имеет 4 значения, которые мы можем применять: left, right, inherint и none. Каждое значение довольно понятно. К примеру, если вы используете float: left к элементу, то он переместится в крайнюю слева границу относительно своего родительского элемента. И, если вы зададитеfloat: right, то элемент аналогично переместится в право. Значение ihnerit говорит элементу унаследовать свойство от своего родительского элемента. И последнее значение none является значением по умолчанию и говорит не применять свойство float к данному элементу.

Вот простой Пример A обтекания текста вокруг изображение и ниже соответствующий CSS:


img {
  float:right;
  margin-top:10px;
}

Поведения floats

Ничего сложного, но все еще не до конца понятно? Прежде чем мы перейдем в мир float-ов, давайте вернемся немножко назад, чтобы обсудить что на самом деле происходит. В мире web, наш HTML связан несколькими правилами, в частности правило нормального потока. При нормальном потоке, каждый блочный элемент (div, p, h1, etc) располагается вертикально друг над другом, начиная из верхней части окна и дальше вниз. Элементы с свойством float изымаются из нормального потока и отправляются в крайний правый или левый край своего родительского элемента. Другими словами, они перестают располагаться друг над другом и становятся друг возле друга, говоря что в родительском элементе достаточно места чтобы расположится рядом всем элементам со свойством float. Важно помнить данное поведение при постройке вашего сайта.

Давайте рассмотрит еще один Пример B, в нем три блока без применения свойства float.


.block{
        width: 100px;
        height: 100px;
    }

Обратили внимание что все блоки расположены вертикально друг над другом? Это и есть концепция нормального потока. Ниже очередной Пример C , только в этот раз к элементам мы применим свойство float: left.

   .block{
        float:left;
        width: 100px;
        height: 100px;
    }

Теперь блоки расположены друг возле друга. Отлично, мы получили то, в чем разбирались. Но как насчет той части, где я сказал "говоря что в родительском элементе достаточно места чтобы расположится рядом всем элементам"? Я думал вы никогда не спросите меня об этом. Давайте возьмем наш последний пример и увеличим количество блоков в пять раз. В нашем случаи, body является родительским элементом наших блоков. Заметьте, что в зависимости от размеров окна вашего браузера. блоки переносятся на следующую сточку, так как им не достаточно места, чтобы располагаться друг возле друга. Если вы будете менять размер окна вашего браузера, то и блоки будут автоматически перестраиваться. Попробуйте сами, вот вам Пример D.

In the clear

Свойство float имеет "сводного-брата" clear. Они настолько дополняют друг-друга, что могут вас сделать счастливым программистом. Как вы помните, элемент со свойством float первый, кто изымается из нормального потока. Это значит что каждый элемент, который будет идти за float-ed элементом, будет вести себя не так, как вы ожидаете. И здесь, я подозреваю, у нас могут начаться проблемы. Давайте быстро посмотрит на очередной пример с нашими блоками. В Примере Е я задам свойство float двум блокам (розовый и синий) и сразу после них добавлю еще два блока (зеленый и оранжевой) без float. Ниже код к данному Примеру Е:

<div class="block pink float"></div>
<div class="block blue float"></div>
<div class="block green"></div>
<div class="block orange"></div>

.block {
	width: 200px;
	height: 200px;
}
.float { float: left; }
.pink { background: #ee3e64; }
.blue { background: #44accf; }
.green { background: #b7d84b; }
.orange { background: #E2A741; }

Как вам зеленый блок? Подождите, где он? Он здесь, спрятан под розовым блоком. Розовый и Синий блоки оба имеют свойство float и ведут себя так, как мы ожидали, т.е расположены друг возле друга. Но так как они были изъяты из нормального потока, то зеленый и оранжевый блоки ведут себя так, как будто их (розового и синего) вообще нет на странице. Вот почему наш зеленый блок спрятан под розовым. Итак, как же нам теперь снова показать наш зеленый блок? Указать свойство clear.

Свойству clear доступно пять значений: left, right, both, inherit и none. Значение left отменяет обтекание с левого края этого элемента. Аналогично при clear: right; - отменяет обтекание этого элемента с правого края. Используя both значение отменяет обтекание элемента одновременно с правого и левого края. При значении inherit свойство clear унаследует значение от своего родительского элемента, а значение none (по умолчанию) отменяет действие свойства clear и обтекание элемента происходит так, как задано с помощью других. Вооружившись этими знаниями давайте взглянем на Пример Е2. В этот раз мы применили свойство clear к нашему зеленому блоку. Наш немножко измененный код теперь выглядит так:


<div class="block pink float"></div>
<div class="block blue float"></div>
<div class="block green clear"></div>
<div class="block orange"></div>

.block {
	width: 200px;
	height: 200px;
}
.float { float: left; }
.clear { clear: left; }
.pink { background: #ee3e64; }
.blue { background: #44accf; }
.green { background: #b7d84b; }
.orange { background: #E2A741; }

Устанавливая значение clear: left к нашему зеленому блоку, мы говорим ему вести себя как будто розовый блок находится в нормальном потоке, несмотря на то что он был изъят, и расположится под ним. Это очень мощное свойство; как вы видите, оно помогает вернуть наши элементы без float свойств в нормальный поток, т.е. к поведению, которое мы склонны ожидать по умолчанию.

Применения floats в макетах

Давайте перейдем к макетам. Это место, где свойство float невероятно полезно. Мы можем создать традиционный двухколонный макет несколькими путями; большинство из них состоят из одного или двух элементов со свойством float. Давайте рассмотрим простой пример: двухколонный web сайт с контент колонкой справа и навигацией слева, а также хедер (header) и футер (footer) к довершению всему. В этой статье мы будем обращать внимание на код, только связан с float-ed элементами. Вот Пример F:


#container {
	width: 960px;
	margin: 0 auto;
}
#content {
	float: left;
	width: 660px;
	background: #fff;
}
#navigation {
	float: right;
	width: 300px;
	background: #eee;
}
#footer {
	clear: both;
	background: #aaa;
	padding: 10px;
}

Еще один Пример , если кому интересно поиграться.

Хорошо, давайте теперь поговорим о том, что здесь происходит. Наш родительский контейнер имеет метку (id) #container. Он хранит в себе наши floated элементы. Если бы его не было, то наши floated элементы расположились бы по самым дальним краям окна просмотра, слева и справа. Следующим мы создали блоки #content и #navigation. Это наши элементы к которым мы будем применять свойство float. Мы отправили наш #content влево и #navigation вправо, чтобы получить двухколонный макет. Я указал ширины блоков, поэтому они заполнили все пространство нашего родительского контейнера. И наконец мы создали #footer, которому мы установили clear свойство. Как нам уже известно, это свойство возвращает элементы следующие за floated элементами в нормальный поток. В данном случае, наш #footer имеет значение clear: both, что располагает его ниже обоих элементов #content и #navigation.

А что произойдет если мы не укажем clear свойство нашему #footer? Взгляните на этот Пример G.

Наш #footer прилип под блоком #navigation. Это произошло, так как под блоком #navigation есть место для #footer и для нормального потока расположения блоков это правильное поведение. Но, это абсолютно не то что нам нужно, не правда ли? Предполагаю вы уже видите взаимосвязь между float и clear и понимаете как они дополняют друг друга.

Если у вас одержимо-маниакальное расстройство, как у меня, вы могли заметить в Пример F разные высоты столбцов #content и #navigation; есть несколько способов решения, но это выходит за рамки данной статьи. Настоятельно рекомендую почитать Faux Columns автора Dan Cederholm чтобы изучить как сделать одинаковой высоты блоки, в не зависимости от контента внутри.

Float first

До сих пор мы видели некоторые довольно простые примеры, которые не создают много головной боли. Есть, однако, несколько подводных камней, которые нужно учитывать при использовании свойства float. Удивительно, но один из самых больших подводных камней связан не с CSS, а больше с HTML. Помещая ваш floated элемент внутрь вашего HTML может привезти к разным результатам. Взгляните на Пример H.

Здесь мы имеем маленький блок, который имеет картинку с свойством float:right и текстом окружающим ее. Наш CSS выглядит так:


#container {
	width: 280px;
	margin: 0 auto;
	padding: 10px;
	background: #aaa;
	border: 1px solid #999;
}
img {
	float: right;
}

Наш родительский элемент #container имеет узкую ширину и удерживает наш floated элемент (изображение) внутри своих границ. Наш HTML код выглядит так:


<div id="container">
	<img src="image.gif" />
	<p>This is some text contained within a small-ish box. I'm using it as an example of how placing your floated elements in different orders in your HTML can affect your layouts. For example, take a look at this great photo placeholder that should be sitting on the right.</p>
</div>

Этот пример дает нам желаемый результат, но что если возьмем и переставим местами некоторые элементы в HTML? В Примере I я переместил <img> после текста <p> :


<div id="container">
	<p>This is some text contained within a small-ish box. I'm using it as an example of how placing your floated elements in different orders in your HTML can affect your layouts. For example, take a look at this great photo placeholder that should be sitting on the right.</p>
	<img src="image.gif" />
</div>

Наш результат не тот, который ожидался. Наше изображение передвинулось вправо, но уже не находится в верхнем углу как мы хотим, а упало вниз под параграф; даже хуже, оно торчит из нижней части нашего родительского элемента #container. Что происходит?

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

Во-вторых. Причина по которой изображение кажется торчащим внизу из нашего блока #container, связана с чем-то под названием collapsing (деформация). Давайте поговорим про collapsing и варианты решения.

Collapsing

Collapsing это когда элемент, который имеет любое количество floated элементов, не расширят свои границы вокруг вложенных элементов, как это происходит если бы вложенные элементы не были floated.

В Примере I, наш родительский элемент #container деформирован, как будто floated img элемента вообще нет внутри. Это не ошибка браузера, а ожидаемое и правильное поведение. Поскольку элементы со свойством float изначально были добавлены в нормальном потоке а потом удалены, то блок #container не учитывает их внутри своих границ и ведет себя как будто их даже не существует.

Примечание. Eric Meyer написал прекрасную статью Containing Floats, которая более детально разбирает данное поведение и является очень полезной.

Хорошей новостью является то, мы можем решить эту проблему в множеством способов; если вы предполагаете, что это связано со свойством clear, то вы на правильном пути.

Один из самых распространенных метод исправить деформацию родительского блока это поместить элемент с clear:both свойством после нашего floated элемента. Это приведет к тому, что родительский элемент продолжит нормальный порядок после floated элемента. Будет проще показать это на действии. Взгляните на HTML для Примера J , который аналогичен предыдущему примеру, только с одним дополнительным элементом:


<div id="container">
	<p>This is some text contained within a small-ish box. I'm using it as an example of how placing your floated elements in different orders in your HTML can affect your layouts. For example, take a look at this great photo placeholder that should be sitting on the right.</p>
	<img src="image.gif" />
	<div style="clear: right;"></div>
</div>

Добавляя div с стилем clear: right нам удалось заставить наш #container обвернуть наше floated изображение путем пересчета его высота, так как теперь внизу еще один элемент. Данное решение работает, но оно может быть не самым элегантным решением, так как нам нужно добавить дополнительный элемент в нашу разметку. Было бы лучше справиться с помощью CSS. Есть несколько путей решения и давайте взглянем на одно из них прям сейчас.

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


<div id="container">
	<img src="image.gif" />
	<img src="image.gif" />
	<img src="image.gif" />
</div>

CSS:


#container {
	width: 260px;
	margin: 0 auto;
	padding: 10px 0 10px 10px;
	background: #aaa;
	border: 1px solid #999;
}
img {
	float: left;
	margin: 0 5px 0 0;
}

Посмотрев на код выше, вы быстро догадаетесь, что наш родительский элемент не содержит floated изображения. И снова, это было ожидаемо, потому так floated элементы изымаются из нормального потока и соответственно наш родительский элемент #container будет пустым. Взгляните на Пример К.

Теперь давайте попробуем исправить это с помощью CSS вместо добавления дополнительной HTML разметки в наш документ, как мы это делали раньше. Существует метод, которые позволяет родительскому элементу "применить" свойство clear после всех floated элементов. Для этого используется CSS свойство overflow со значением hidden. Примите во внимание что свойство overflow не было предназначено для такого использования и может стать причиной возникновения некоторых проблем, таких как скрытие контента или появление нежелательного скроллбара. Для нашего примера, однако, мы все же применим свойство overflow: hidden к нашему родительскому элементу #container:


#container {
	overflow: hidden;
	width: 260px;
	margin: 0 auto;
	padding: 10px 0 10px 10px;
	background: #aaa;
	border: 1px solid #999;
}

Результат показан в Примере L. Достаточно классно, не так ли? Другой метод, который дает аналогичный результат с меньшим количеством предостережений это использование псевдо селектора :after. Используя наш пример, код будет следующим.


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

В данном случаи, с помощью CSS, мы добавляем новый элемент в наш родительский элемент #container и задаем ему значение hidden и heigh: 0. Вы можете найти очень тщательный и подробный обзор этой техники на сайте Position is Everything.

И напоследок, Eric Meyer объясняет третий вариант решения данной проблемы в своей статье Containing Floats. В соответствии CSS Spec 2.1:

элемент со свойством float будет расширять свои границы для floated элементов находящихся внутри.

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

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

Заключение

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


Для закрепления материалы советуем тест знаний CSS-Основы и CSS-Средний уровень.

Если Вам понравилась статья, проголосуйте за нее

Голосов: 15  loading...
admin   maclaine   Stoik_   zaratusta   black40   mrDrozd   greenrow   maladez   Vlad6312   smayl1ks   alomir   faint   netpoj1   Serusch   margomargo