О практических применениях свойства float


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

    1. Значения left, right определяют, по какой стороне будет выравниваться элемент;
    2. элементы, имеющие значения left, right, становятся блочными (имея больший приоритет над значениями свойства display);
    3. плавающий элемент обтекается следующим элементом (и другими вложенными в него элементами), следующими соседними элементами родителя, а также предыдущими соседними строчными элементами;
    4. плавающий элемент занимает ширину контента за исключением, если внутренние элементы неплавающие (это было обсуждено в статье Float'омагия: пробуем не «плавать» в спецификации, чтобы не утонуть в потоке);
    5. высота отца не зависит от высоты дочернего плавающего элемента, для следующих неплавающих элементов внешние отступы от плавающих элементов не будут действовать;
    6. элемент, для которого предыдущий соседний элемент — плавающий, будет обтекать его, если позволит ширина отца, в противном случае — обтекать предыдущий плавающий ​​элемент;
    7. элементы не будут флоатиться, если это не позволит ширина отца;
    8. значения absolute и fixed свойства position отменяют действие свойства float.


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

    Пример:

    <span>2</span>
    <div style=”float: left;”>1</div>
    


    Результат:

    12

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

    Но хотелось бы привести еще дополнительные практические применения


    1. Какие стили написать для такой разметки

    <dl>
    	<dt>Бренд:</dt>
    	<dd>Apple</dd>
    	<dt>Потребительная мощность:</dt>
    	<dd>10Вт</dd>
    	<dt>Дополнительные возможности:<dt>
    	<dd>Веб-камера FaceTime HD Встроенный микрофон</dd> 
    </dl>
    


    чтобы выглядело так:


    Все просто:
    dt{
    	float: left;
    }
    


    A если размеры ограничены:
    dl{
    	width: 500px;
    }
    


    Результат:



    микрофон упал под Дополнительные возможности:

    В таком случае стоит лишь добавить
    dd{
    	overflow: hidden;
    }
    


    Результат:



    В итоге получается небольшой код:
    dl{
    	width: 500px;
    }
    dt{
    	float: left;
    }
    dd{
    	overflow: hidden;
    }
    


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


    эта особенность нам поможет.

    С условием, что цвет фона нужно задать элементу li:

    Розметка:
    <ul>
    	<li><a href="#">Главная</a></li>
    	<li><a href="#">Каталог</a></li>
    	<li><a href="#">Контакты</a></li>
    </ul>
    


    Базовые стили:
    ul > li {
    	float: left;
    	background-color: #eee;
    	margin: 4px 0;
    	padding: 4px;
    }
    


    float: left — нужен для того, чтобы ограничить ширину до содержимого.

    Но не обязательно быть профессионалом верстки, чтобы заметить: если ширина ul позволяет элементам обтекать друг друга, то получится следующее:



    Тогда в помощь нам приходит связка свойств float и clear. Стоит селектору ul > li прописать clear: left, и все станет на свои места.

    Не все так просто со свойством clear — применение этого свойства из значением left или right приводит к очищению всего потока зафлоаченных элементов данного типа. Приведу наглядный пример:

    Имеем следующую разметку:
    <div class="leftColumn">lorem ispum</div>
    <div class="rightColumn">
    	<p class="block1">lorem ispum</p>
    	<p class="block2">lorem ispum</p>
    	<div class="block3">lorem ispum</div>
    </div>
    


    и стили:
    .leftColumn {
    	width: 200px;
    	height: 200px;
    	float: left;
    	background: #f55;
    }
    .rightColumn {
    	margin-left: 220px;
    	background: #5ff;
    }
    .rightColumn .block1,
    .rightColumn .block2 {
    	float: left;
    	width: 200px;
    	margin-right: 20px;
    	background: #ebde05;
    }
    .rightColumn .block3 {
    	background: #9e9;
    	clear: both;
    }
    


    Заметка: за задумкой, элемент с классом block3(зеленый) должен расположиться после элементов с классами block1, block2 (желтые) и начинаться с нового рядка.

    В результате:



    Что здесь произошло? Элемент с классом block3 (зеленый), действием правила clear: both; очистил поток, включая красный блок.

    Выходов из этой ситуации много. Все зависит от поставленной задачи:
    • задать элементу с классом rightColumn правило overflow: hidden;
      результат:
    • задать элементу с классом rightColumn правило float: left; но тогда придется убрать margin-left: 220px; и теперь элемент с классом rightColumn не будет занимать остальную ширину окна браузера;
    • обвернуть элементы с классами block1, block2 в элемент, задав ему overflow: hidden; или же display: table-cell; (для ie7 — zoom: 1;)


    Знакомый метод очищения потока и определения высоты элементу под названием clearfix здесь не подходит.

    4. Вооружившись знаниями свойства float и overflow, сверстаем такое меню:



    Разметка:
    <ul>
    	<li><a href="#">Главная</a></li>
    	<li><a href="#">Каталог</a></li>
    	<li><a href="#">Контакты</a></li>
    </ul>
    


    Не будет проблемы, если использовать дополнительные селекторы. Но, к примеру, мы не знаем количества пунктов (для использования селектора соседних элементов), не имеем кроссбраузерную поддержку :first-child, :last-child, а использование каких либо выражений, тем более скриптов для IE — запрет;

    стили:
    ul li {
    	float: left;
    	border-width: 0 3px;
    	border-style: solid;
    	border-left-color: #5FF;
    	border-right-color: red;
    	padding: 0 5px;
    }
    


    В результате получаем:

    Использовав отрицательные внутренние отступы для li и свойства float и overflow для ul, получаем дополнительные стили:
    ul{
    	overflow: hidden;
    	float: left;
    }
    ul li {
    	margin: 0 -3px;
    }
    



    Как можно заметить, border-ы не на своем месте, осталось лишь поменять значения цветов левого и правого бордеров, получается такой код:
    ul {
    	overflow: hidden;
    	float: left;
    }
    ul li{
    	float: left;
    	border-width: 0 3px;
    	border-style: solid;
    	border-left-color: red;
    	border-right-color: #5ff;
    	padding: 0 5px;
    	margin: 0 -3px;
    }
    


    Конечно же, внутренние отступы уменьшились на 3px, поэтому надо их увеличить на 3px:

    ul {
    	overflow: hidden;
    	float: left;
    }
    ul li{
    	float: left;
    	border-width: 0 3px;
    	border-style: solid;
    	border-left-color: red;
    	border-right-color: #5ff;
    	padding: 0 8px;
    	margin: 0 -3px;
    }
    


    Получаем готовое меню:


    Я не упомянул всего, что касается специфики и практических примеров свойства float, но приведу еще некоторые ссылки на полезные статьи:



    Раздел блога ImageCMS “Совершенствуемся — CSS!” в статье учебные материалы об эффективной верстке веб-страниц.

    В заключение хочу добавить, что применять свойство float надо там, где в этом есть необходимость. Известный фреймворк bootstrap использует специальные вспомогательные классы .pull-left и .pull-right. Я использую .f_l, .f_r, это позволяет не только сократить код css, но и дает большую гибкость в построении структуры.

    Ко всем вышеуказанным важностям хочу добавить только одно: с Днем программиста, друзья и коллеги! Легкого кодинга, двойной оплаты в восьмой степени вам и нам!
    Share post

    Similar posts

    Comments 37

      +3
      Я, полностью разобравшись в особенностях float'a, перестал им пользоваться. Как раз по причине, что над большинством проектов работаю не я один, и после меня ещё люди. Надоело объяснять, честно говоря. Теперь пользуюсь в основном:

      tag {
      display:inline-block;
      vertical-align:top
      }

      А всё, что после эелементов вместо clear'a делаю display:block; (зачастую просто div или section)
        +2
        Только омрачает использование inline-block необходимость хаков для ie7 (zoom:1; display: inline;) и необходимость учитывать пробельные символы между элементами. А так действительно применять inline-block, особенно для горизонтальных меню, удобнее.
          +1
          Проблему с хаками решает любой препроцессор. Например, у меня в стайлусе:
          display(type)
              if type is inline-block
                  display: inline-block
                  zoom 1
          	*display inline
              else
                  display: arguments
          

          В общем, остаются беды с пробелами.
            +1
            Я предпочитаю для ie7-8 использовать conditional comments.
            Особой беды от пробелов не вижу, главное знать о ней и правильно прописать шаблоны. На крайний случай можно вставить комментарии вместо пробелов:
            <div class="inline-block">
               ...
            </div><!--
            --><div class="inline-block">
               ...
            </div><!--
            --><div class="inline-block">
               ...
            </div>
            


            В этом случае не надо прописывать font-size:0
              +1
              Для HTML я тоже использую препроцессор (Jade). Там с этим беда, так что приходится ловить font-size.
                0
                да, ну как отказатся от читабельной структуры хтмл кода :)
                  +1
                  habrahabr.ru/post/137582/ — вот тут уже всё решено.
                  Не всякий backend-разработчик поймёт, зачем там пустые комменты, или почему бы не перенести на новую строку.
                  ps. С Днём программиста всех ;)
                    0
                    Как раз для отдельного файла стилей, Роман Комаров сегодня выложил миксин дял стайлуса.
                    То есть вы пишете в основном файле стилей:
                    .foo
                        box-shadow: 0 0 3px #000
                        border: 1px solid #000 if ie
                    

                    И правило про красные бордеры попадает в style_is.css
                  +2
                  Замените div на span и inline-block будет работать в IE7
                    0
                    Но иногда зачастую внутри должен быть другой див или большое их количество, т.ч. это не выход.
                    • UFO just landed and posted this here
                  0
                  Какое-то время тоже пользовался. Но.
                  .page-constrain {
                      font-size: 0;
                      display: inline-block; zoom: 1; display: inline;
                  }
                  /* И это если всё же существуют внутренние элементы */
                  .page-constrain * {
                      font-size: ...;
                  }
                  

                  Такие вещи действительно упрощают код? Есть ещё какие-то беды, сходу не вспомню.
                  То есть вам легче было было объяснить, что после двух узких блоков нужно ставить
                   <div style="display: block;"></div>
                  
                  , вместо
                  <div style="clear: block;"></div>
                  
                  ?
                    0
                    clear: both, конечно
                      0
                      хочу с вами не согласиться, во первых:
                      элементу с класом page-constrain не надо давать font-size: 0;, нужно именно родителю записать font-size: 0;;
                      во вторых:
                      вы написали — То есть вам легче было было объяснить, что после двух узких блоков нужно ставить <div style="display: block;"></div> ето не подходить если ширина элемента с классом rightColumn позволить элементу с классом block3 обтекать два узких
                        0
                        .page-constrain — это родитель у меня в данном примере.
                        То, что вы написали дальше, я, к сожалению, не могу разобрать.
                          0
                          То есть вам легче было было объяснить, что после двух узких блоков нужно ставить
                          <div style="display: block;"></div>
                          

                          , вместо
                          <div style="clear: both;"></div>
                          


                          Извените, я подошел к примеру более общее.

                          То есть я хотел сказать, что ваш пример не подходить, если ширина элемента с классом rightColumn позволить элементу с классом block3 обтекать два узких желтых (в моем примере) блоков
                      0
                      Флоат там, где он к месту — это вполне нормально,
                      однако бесят люди, которые повсеместно используют
                      .blablabla {float: left; width: 100%;}
                      

                      поддерживать проект, в котором оно в каждом блоке — не возможно… хотя я и сам, порою, грешу подобным.
                      0
                      Автор зря не упомянул, что любой пример с overflow: hidden ломается, как только нужно вставить блок, вылезающий за рамки.
                      В том же последнем примере нельзя добавить всплывающее меню.
                        0
                        так вы правы, но я привел еще два рабочих примеры
                        0
                        Не люблю я float. Стараюсь использовать только по назначению, когда картинке необходимо обтекание текстом.
                        Для всего остального стараюсь найти оптимальный способ pos: absolute + display: inline-block;
                          0
                          почти полностью с вами согласен, зато иногда без
                           float 
                          
                          не обойтись, я считаю, что следует взять за правило окучивают хотя бы один плавающий блок оборачивать эментом с правилом:
                          overflow: hidden
                          
                          или
                          display: table-cell
                          
                          или же использовать известный метод clearfix.
                            0
                            извините за граматику:

                            почти полностью с вами согласен, зато иногда без
                            float 
                            

                            не обойтись, я считаю, что следует взять за правило обертывать хотя бы один плавающий блок элементом с правилом:
                            overflow: hidden
                            

                            или
                            display: table-cell
                            

                            или же использовать известный метод clearfix.
                              0
                              Clearfix — это как само собой разумеющееся для float.
                              Overflow опять же используется только по назначению (например, для скрытия последующий слайдов в слайдере, для ограничения высоты блока и прикручивания к нему скролла), а не чтобы косяки float выправлять.
                              Особое исключение ИМХО для overflow: cssing.org.ua/2010/04/26/overflow-hidden/
                          0
                          Для примера с меню достаточно display: inline
                            0
                            а для «12» можно вообще тэги не писать. Но что-то мне подсказывает, что смысл не в этом. А вот в чём, я не могу понять
                              0
                              дело в том что в коде сначала идет 2, затем 1, а в результате 1, а затем 2. Этот пример демонстрирует что зафлоаченого элемента обтекают предыдущие строчные элементы.
                              0
                              для пунктов (li) — согласен, но для элемента (ul) нам нужен
                              float: left;
                              
                              чтобы ограничить его ширину до ширины контента, и действием правила
                              overflow: hidden;
                              
                              спрятать border-ры
                            • UFO just landed and posted this here
                                0
                                Использование float для целей layout это в общем-то грязный хак и весьма не рекомендуется. Собственно как и других штук типа zoom:1.

                                Некоторые проблемы Дэйвид Барон описал в своей статье. Со своей стороны хочу отметить что floats очень тяжелы для динамических изменений. При изменении float элемента пересчитывается layout всего BFC (block formatting context), в общем случае это весь документ.

                                Если уж надо горизонтальное размещение то на выбор: display:inline-block, display:table-cell или display: flexbox со товарищи (если религия проекта позволяет)
                                • UFO just landed and posted this here
                                  0
                                  Век живи, век учись. Трюк с бордерами и отрицательными отступами утащил в копилку, спасибо.
                                  Очищение потока — та еще шляпа, когда приходится доделывать за горе-верстальщиками. clear:both в таком случае подобен брошенной на страницу гранате)
                                  Приходится за компанию флоатить и все остальное. Хорошо, когда удается победить малой кровью — float:left; width:100%;
                                  Обычно быстро и легко не получается, а виной всему первоначальный макет.
                                    0
                                    не имеем кроссбраузерную поддержку :first-child

                                    А где не поддерживается :first-child?
                                      0
                                      я имел в виду общую поддержку этих селекторов…
                                        0
                                        не имеем кроссбраузерную поддержку :first-child, :last-child, а использование каких либо выражений, тем более скриптов для IE — запрет

                                        А написали по другому, но не суть. Для вашего меню логичнее использовать кроссбраузерный селектр :first-child чем отрицательные отступы.
                                          0
                                          но нам нужна замена селектора :last-child чтобы скрыть последний правий border.

                                  Only users with full accounts can post comments. Log in, please.