Float'омания: разъяснение как работает css свойство float


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

    Disclaimer


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

    Свойства элемента с float, которые нужно всегда держать в голове

    если оно установлено в значение left или right
    • Элемент отображается как блочный, так словно ему установлено свойство display: block;
    • Элемент по ширине сжимается до размеров содержимого, если для элемента явно не установлена ширина width;
    • Элемент прилипает к левому (left) или правому краю (right);
    • Все остальное содержимое страницы, идущее в HTML коде после элемента с float, обтекает его;

    Жизненный случай #1


    У меня есть два блока, я применил к одному из блоков float: right, он выровнялся по правому краю, но все равно остался под первым. Пример как это выглядит.



    Причина

    Если так произошло, значит, вы применили float не к первому, а ко второму блоку. В силу того, что плавающий (тот, который с float) элемент обтекают только те элементы, которые идут в HTML коде после него, первый блок его обтекать не будет.

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

    Решение

    Поменяйте блоки в HTML коде местами, поставьте блок с float первым.

    Жизненный случай #2


    У меня два блока в header/content/footer. Одному я сделал float: left, другому float: right. Но после этого все содержимое сайта поплыло.



    Причина

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

    Так же всё содержимое сайта, которое идет в HTML коде после плавающих элементов, обтекает их, что часто приводит к неожиданному эффекту.

    Решение

    Решение #1. Явно задать высоту контейнера. В тех случаях, когда известно какими должны быть размеры контейнера, это самое простое решение.

    Решение #2. Добавить пустой блок с clear: both. Добавление подобного элемента отчищает «плавучесть» блоков и заставляет контейнер растягиваться на всю высоту. Семантически это не самое лучшее решение, так как вводит лишний элемент разметки.

    Решение #3. Применить свойство overflow: auto (или hidden) к контейнеру. Заставляет контейнер заново рассчитать высоту и изменить ее так, чтобы включать плавающие элементы, иначе ему бы пришлось добавить полосу прокрутки или скрыть их. Впрочем, иногда это случается, поэтому будьте осторожны.

    UPD
    Так же читайте интересную статью от SelenIT2 как продолжение обсуждения свойства float.
    Поделиться публикацией

    Похожие публикации

    Комментарии 100

      0
      Не являюсь супер верстальщиком т.к. мою душу больше греет чисто php, но пожалуйста расскажите разницу между и блок clear: both, заранее спасибо.
        0
        съел редактор тег br с clear=«all»
          +5
          Стандарт (css 2.1 и css3) знает только значения right, left, both и none.
            0
            У тега
            таки есть свойство clear с допустимыми значениями all | left | right | none
              0
              съел тег <br />
                0
                так он deprecated eще в html 4.01, не говоря уже о html5
                  –1
                  Если вы про <br>, то в html5 он вполне себе здравствует. Читайте спецификации.
                  • НЛО прилетело и опубликовало эту надпись здесь
                      0
                      Я про clear-атрибут.
              0
              В контексте топика, большой разницы нету.
              Т.е. и то и то вернет поток вывода в нормальное русло.
                +1
                Поток-то вернёт, но добавится высота блока <BR>, которая не обнуляется стилями в Хроме из-за бага. И deprecated — не последний аргумент.
                  0
                  BR по дефолту является inline элементом, может в этом проблема с обнулением высоты?
                  • НЛО прилетело и опубликовало эту надпись здесь
                    +1
                    .clear {
                    clear: both;
                    display: block;
                    height: 0;
                    line-height: 0;
                    overflow: hidden;
                    font-size: 0;
                    }


                    ни разу не подводило
                      +1
                      блин, пробелов повтыкало и тег съело
                      <br class='clear' />
                      
              • НЛО прилетело и опубликовало эту надпись здесь
                +1
                Ссылку на пример с overflow:auto пофиксите, смотрит на второй, с clear:both
                  +1
                  исправлено за время написания камента )
                  –5
                  ну раз это такая статейка для начинающих, можно еще заметить, что overflow:hidden не кроссбраузерно: для ie нужно искать другие способы (лично я выношу в отдельный файл для ие zoom:1. это свойство считается невалидным, но именно в отдельном файле все ок)
                    +6
                    Честно говоря, верстая сложные дизайны — поддерживать валидность CSS чрезвычайно сложно. Очень многое будет убегать в разного рода IE7-8-9-Opera файлы, и работать потом с этим будет страшно неудобно. Лично я давно отказался от CSS валидности, ибо она приносит только гемморой, в отличии от HTML валидности, которая позволяет держать себя в тонусе.

                    Ещё не совсем понятно, а чем плох overflow:hidden в пункте кроссбраузерность? Если судить по этой заметке, то всё вполне сносно. Лично я доселе применял zoom:1 только в двух ситуациях:
                    1. непонятные глюки с render-ом страницы в IE7, IE8 (например всё прыгает и моргает, глюки с :hover)
                    2. в IE7 вместе со свойством display:inline, для имитации display: inline-block;
                      0
                      не все имеют возможность отказаться от валидности, так как все-таки пока основным условием валидности является хотя бы от ie7. Не говоря уже о том, что у многих заказчиков на работе в целях безопасности или еще по каким-то соображениям стоит ie6.

                      overflow:hidden ведет себя несколько по-другому в ie 6 и 7. он обрезает содержимое, а не пресчитывает высоту.

                      ну и zoom:1 для ie6 и 7 во многих случаях можно использовать. А вот в 8-ке можно и вовсе без хаков обойтись обычно :)
                        +1
                        Бедолаги, ни border-radius-а, ни opacity, ни zoom.
                          0
                          да нет, в принципе все ок) да и к тому же, верстальщику самому должно быть приятно от своей работы, когда везде все опрятно, не едет, не обрезается и т.п.
                            –1
                            Не вижу связи между «везде все опрятно, не едет, не обрезается и т.п.» и добровольными кандалами.
                              0
                              да какие кандалы, что вы) все замечательно. и про зум — вы невнимательно прочитали мои комменты.
                                +2
                                Попробую проще, что общего между [ «верстальщику приятно», «везде все опрятно, не едет, не обрезается» ] и [ «выношу в отдельный файл для ие», «валидность для галочки» ]? Что в этом удобного и замечательного? Ещё хотелось бы отметить, что всякие IE-комментарии и отдельные файлы легко можно заменить 1 классом для <body> или <html>. А скруглённые уголки понадобятся будете 6-12 блоков добавлять? Или border-radius вынесете в «отдельный файл». Это тоже будет замечательно? :)
                                  0
                                  да нет. представьте, можно и без 6-12 блоков обойтись)
                                    0
                                    Сути дела это не меняет :) Но всё же, а как? Интересует именно css2-метод.
                                      0
                                      меняет) необязательно городить тонны кода для хорошей верстки. даже наоборот. но и старые браузеры по мере возможности поддерживать можно. есть для этого способы.
                                        0
                                        Мой опыт с вами не согласен. И всё же, где метод? :)
                                          –1
                                          ахаха. универсальный для всего?) класс! как найдете такой, напиши обязательно, поделитесь опытом
                                            +1
                                            o_O. Полагаю, что вы потеряли нить беседы. Вы сказали, что знаете как сверстать скруглённые уголки используя <6 блоков, да так, чтобы было валидно (CSS2.1?). Учитывая, что далее вы написали, что «городить тонны кода» не есть хорошо, я сделал вывод что вы уверены в своих словах.

                                            На данный момент мне кажется, что вы спорите ради спора. К примеру, вы так и не привели никаких аргументов, которые бы оправдали иконку CSS-валидности.
                                              –3
                                              это бесполезный диалог просто уже) никакого одного универсального метода не существует. в каком-то макете лучше использовать картинки для декора, в каком-то ксс3+какой-нибудь pie в ие (все в разумных пределах). на эту тему написано очень много, не вижу смысла рассуждать далее. и, прошу, не надо мне навязывать никаких «икон css-валидности».
                              0
                              дело в том что опрятно и т.д. в ИЕ6 просто не рулит. Ошибки в ИЕ6 иногда возникают… мягко говоря из неоткуда. Применил свойство какой-то к элементу, и из-за него где-то что то поплыло(даже не рядом а именно где-то)

                              Ну и пока мы, разработчики не откажемся от ИЕ6 он будет жить. А вообще нужно сказать иди ты на… ИЕ6 лес дремучий. Мне не так хорошо платят что бы я с тобой имел… :)
                                0
                                у меня первые полгода верстки плыло в ие 6… потом вроде бы лучше, меньше времени на правку верстки под этот браузер и хаков меньше) ну а поддержка — как правило да, стараемся отказываться от старых ие, однако очень не всегда получается.
                                  0
                                  Я за последние 2 года только один заказ выполнил с правками для ИЕ6, и то в режиме «умной деградации»…
                            +4
                            ie6 в целях безопасности… nom-nom…
                              0
                              хехе) ну это я конечно погорячилась
                            0
                            по-моему, display:inline-table лучше
                            0
                            В самых крайних случаях когда нужно железно решить проблему без последствий — можно обернуть float-ные блоки в таблицу с width:100%. Всегда работает и не имеет тех проблем что имеют clear:both (выпадание под clear лишних блоков), overflow:hidden (обрезание области для всего что пытается выйти наружу — например для position:absolute элементов)
                              +1
                              Может, сразу отказаться от блоков и верстать таблицами?
                              +2
                              Что блок с флотнутыми элементами внутри не схлопывался можно написать следующий код (кроссбраузерный)
                              .container {
                              overflow:hidden; /* для нормальных браузеров */
                              height:1%; /* для IE */
                              }


                              1% отработает нормально, т.к. ие растягивает блоки в зависимости от контента даже если установлена конкретная высота, но только при условии если у родителя не будет заданна фиксированная высота.

                              Вместо overflow:hidden, что бы не обрезало элементы на абсолютах, можно воспользоватся хаком :after
                              .container {
                              height:1%; /* для IE */
                              }
                              .container:after { /* для нормальных браузеров */
                              content:"";
                              display:block;
                              clear:both;
                              }
                              +3
                              Отличная статья, спасибо. Но у меня есть вопрос как раз по этой теме. Недавно правил верстку одного сайта и нашел проблему с плавающим блоком и списками, которые его обтекают. Вот пример кода:

                              <div style="float:left; width:500px;">Плавающий блок
                              вторая строка
                              третья строка</div><ul><li>первый элемент</li><li>второй элемент</li><li>третий элемент</li></ul>


                              Список обтекает плавающий блок, но круглые отметки каждого элемента налазят на плавающий блок, а не обтекают его. У меня это выглядит так:

                              Вопрос: в чем может быть проблема? Может быть вы уже такое видели?

                                0
                                Так и должно быть. Просто верстку делал ничего не понимающий в CSS человек (студент наверно). Поставьте margin-left: 500px на UL чтобы исправить ситуацию.
                                  +1
                                  Если поставить маргин обтекание будет не совсем верным. А если список по высоте больше, чем флоэт блок? Тогда он продолжится ниже, только будет на 500 px правее, а слева будет куча пустого места. Это не решение вопроса. Например попробуйте ваш вариант, только с ul списком больше 3-х:
                                  <div style="float:left; width:500px;">Плавающий блок
                                  вторая строка</br>
                                  третья строка
                                  </div><ul style="margin-left:500px;"><li>первый элемент</li><li>второй элемент</li><li>третий элемент</li><li>третий элемент</li><li>третий элемент</li><li>третий элемент</li><li>третий элемент</li></ul>
                                  


                                  P.S. Можете объяснить почему так и должно быть? Я не понимаю, почему текст обтекает, а этот флажек нет. Поидее ведь плавающий блок все должно обтекать, а не только текст списка.
                                    +1
                                    overflow:hidden для UL
                                      +2
                                      и, скорее всего, padding-left:20px, иначе буллиты могут исчезнуть.
                                        0
                                        Ниже: habrahabr.ru/blogs/css/136588/#comment_4544449 решение получше, мне кажется.
                                          0
                                          С list-style-position:inside будет обтекание буллита текстом для многострочных элементов списка. Если вам это подходит, то почему бы и нет. Ну и буллиты могут прилипнуть к float блоку.
                                            +1
                                            Решение будет работать на данном несколько самобытном чёрно-белом примере. Но для сохранения правильного и строгого поведения в потоке нужен прежде всего overflow:hidden. Это сделает элемент «правильным».

                                            А list style pos: inside — это как бы графический обман, мы просто притягиваем буллеты к тексту. Так как идентичность буллетов во всех браузер пиксель-в-пиксель невозможно добиться стандартными средствами поэтому часто уходят все эти list-style/list-type, убиваются отступы, ставятся новые padding-left для li и им добавляется рисованный буллет в виде background.

                                            Решение по ссылке — не лучше.
                                        +1
                                        Объясняю. Потому что флоат влияет только на горизонтальные границы inline boxes, проще говоря на отдельные строки из букв и элементы с display:inline-block. А блочные элементы флоат не расталкивает. Поставьте, например, background: yellow на ul (или бордер) и увидите, о чем я говорю. Видимо буллиты здесь браузер видит как чаcть блочного бокса и рисует их в нормальном виде, а текст внутри li флоатом сдвигается вправо.

                                        • НЛО прилетело и опубликовало эту надпись здесь
                                      +2
                                      Поставьте списку css-свойство list-style-position:inside. Это частично решит проблему. При желании можно добиться отображения как в outside, но там для кроссбраузерности нужен бубен.
                                        +1
                                        Большое спасибо! Не слышал об list-style-position:inside. Как говорил Ленин: «Учиться, учиться и еще раз учиться»
                                        –1
                                        минимум попробуйте добавить overflow:hidden для UL, а так хорошо бы было увидеть ссылку на пример
                                        +10
                                        Я верстальщик, знаю, как работает float, но, черт возьми, читая эту статью, не понял, как оно работает :).

                                        Например,
                                        Элемент выравнивается по левому (left) или правому краю (right);

                                        Что значит «выравнивается»? Текст в нем тоже выравнивается? Может, скорее, прижимается?

                                        Вот здесь есть подробная и очень понятная статья Ивана Сагалаева по раскладке колонок на флоатах — softwaremaniacs.org/blog/2005/12/01/css-layout-float/

                                        Все простым языком и не оставит вопросов. Очень рекомендую.
                                          +1
                                          А какой тогда синоним слова «выравнивается» вы считаете более понятным? Мне кажется, фраза «выравнивается по левому краю» вполне проста и ясна.
                                            +2
                                            Как я уже написал, по-моему, слово «прижимается» больше подходит.
                                              0
                                              Кому как:)
                                              0
                                              Ну вообще я думал что перевод вполне подходит — обтекание.
                                              +1
                                              Мне нравится ваш термин, на мой взгляд он действительно звучит проще.

                                              Иван Сагалаев проделал большую работу, спасибо за ссылку на него, я думаю она пригодится читателям, которым нужны будут подробности.
                                              +30
                                              КЛАСС! Ждём статьи:
                                              — Чем padding отличается от margin?
                                              — Как объединить несколько ячеек в таблице в одну?
                                              — UL/OL списки, магия или реальность?
                                                –3
                                                Мой друг, посмотрите на количество людей, добавивших эту статью в избранное. Это говорит о том, что материал актуален. И я полагаю, что статья про padding и margin так же нашла бы своего читателя.
                                                  +5
                                                  Про: «Вложенные дивы это просто!» забыли:)

                                                  А главное такие мануалы можно будет собрать в книжку — CSS за 24 часа.
                                                    +2
                                                    зря смеетесь, про схлопывание маргинов начинающие верстальщики даже не догадываются ;)
                                                    +6
                                                    Еще можно сделать clear при помощи :after
                                                    .element:after {
                                                    clear:both;
                                                    content:"";
                                                    display:block;
                                                    }
                                                      0
                                                      Мне кажется div с классом clear будет визуальнее быстрей найти в верстке, чем лопатить в firebug все свойства.
                                                        +5
                                                        Возможно, но как уже говорил автор это вредит семантике.
                                                        А если уже и делать через класс clear, то добавлять его к контейнеру и прописывать в стили:
                                                        .clear:after {
                                                            content: "";
                                                            display: block;
                                                            clear: both;
                                                        }
                                                        
                                                        /*И для ie7*/
                                                        
                                                        .clear {
                                                           zoom: 1;
                                                        }
                                                        

                                                        +2
                                                        Я тоже предпочитаю делать именно так.
                                                        Всё, что можно выносить в css, лучше выносить в css.
                                                        0
                                                        Всем, кто жаждит основополагающих знаний по верстке, рекомендую прочитать еще и вот эти несколько статей.
                                                          –1
                                                          А как же банальнейший баг с удвоением маргина с той стороны, в которую плавает блок, в ие 7?
                                                            +7
                                                            В ие6, начиная с ие 7 его уже нет.
                                                            0
                                                            Вместо /> можно еще пользоваться Micro-Clearfix Hack, который не засоряет разметку лишними элементами, и безотказно работает во всех браузерах.
                                                              0
                                                              <div class="clear"></div>  имелось в виду, прошу прощения
                                                              +5
                                                              я чего-то не понял… 2012-й год же… я бы понял если бы этот пост написали ну так… лет 5 назад :) ну может 4… в общем Привет кэп!
                                                                +2
                                                                Когда шесть с половиной лет назад я написал свою первую статью про вёрстку, первый комментарий был "все это мы конечно проходили года два назад, но новичкам будет полезно почитать..."

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

                                                                P.S. Хотя сейчас я бы уже float для раскладки блоков во многих местах заменял на более удобный inline-block. Но «old habits die hard».
                                                                • НЛО прилетело и опубликовало эту надпись здесь
                                                                    0
                                                                    мм ну эту проблему можно решить конечно по разному, хотя самое очевидное это все же использовать margin нежели ..-spacing имхо конечно.
                                                                    • НЛО прилетело и опубликовало эту надпись здесь
                                                                        0
                                                                        Я имею ввиду что я использую простое решение, что бы пробелы не мешали отрицательный margin блоку. и они тогда не выидны и не толкаются. Ну хотя может быть я не так вас понял.
                                                                        • НЛО прилетело и опубликовало эту надпись здесь
                                                                            0
                                                                            ну в общем-то да.
                                                                    0
                                                                    Тут нельзя не согласиться. По поводу новичков. Просто само свойство float — плавает, плавающее, и т.д. вроде как должно быть понятно. + есть спецефикации и т.д. с другой стороны я сталкиваюсь с тем же в Django сейчас. ДЛя кого-то что-то очевидно, а для меня ужас как не ясно.

                                                                    Вы правы в чем-то…

                                                                    по поводу inline-block он же зараза не везде уместен :) А вообще конечно лучше его использовать!
                                                                  +2
                                                                  Автор, статья отличная. Я тоже не профессиональный верстальщик но приходится верстать время от времени. Эта проблема на самом деле доставляет много проблем у неопытных. Если бы только нашёлся такой человек который раньше бы мог рассказать об этом всём..) Сколько бы времени и нервов было бы сохранено) Все шаги из твоей статьи были испытаны на своей шкуре. Спасибо за статью.

                                                                  PS: если сайт dotnetways.com/ ваш то я бы советовал на сайдбаре «Свежие .NET Ways» поменять левый margin у списка, пикселей так на 10, а то что-то очень уж некрасиво он вылазит влево =))
                                                                    0
                                                                    С этой целью я именно и написал эту статью, так как совершенно знаю для кого она нужна и что она будет востребована.

                                                                    Спасибо за замечание по сайту, но я открыл его 5 дней назад, пока еще не занимался, там много что еще не так, включая контент. Приходите позже. :)
                                                                    +1
                                                                    Элементарные вещи, но очень хороший стиль изложения. Для совсем новичков самое оно. Не останавливайтесь и пишите еще, люди вас будут читать с удовольствием. Например, я это все знаю и использую уже лет 5, но объяснить незнающим так, чтобы это было интересно и сходу понятно — не могу.
                                                                      +1
                                                                      Элемент отображается как блочный, так словно ему установлено свойство display: block;

                                                                      А разве не inline-block?
                                                                        +2
                                                                        Нет, именно block. Его не получится выровнять при помощи vertical-align относительно окружающего текста.
                                                                        +1
                                                                        Если автору не сложно, в следующих постах разобрать position и overflow, и побольше примеров. Заранее благодарен!
                                                                          0
                                                                          [experience]
                                                                          Eсли есть float элементы, то родителю надо ставить overflow:visible для правильного расчёта размеров с учётом float элементов.
                                                                          [/experience]
                                                                            0
                                                                            а по умолчанию какой overflow у родителя? -_-
                                                                              0
                                                                              auto
                                                                                +1
                                                                                не, по умолчанию visible, я не могу объяснить почему приходилось его прописывать явно
                                                                                  0
                                                                                  А пример можно? само название свойства как бы намекает, что при переполнении ничего не растянется и вылезет наружу, за блок.
                                                                                    0
                                                                                    Если это ожидает, скину пример позже, щас реконструируем сайт и незачем смотреть на отладку :)
                                                                              –1
                                                                              Сколько воды.

                                                                              Float для блочной верстки.

                                                                              CSS:
                                                                              
                                                                              .block { width: 100px; height: 100px; background: #abc; }
                                                                              .fl { float: left; }
                                                                              .fr { float: right; }
                                                                              .cl { clear: both; width: 0; height: 0; }
                                                                              
                                                                              HTML:
                                                                              
                                                                              <div class="block  fl">Блок будет располагаться с левой стороны</div>
                                                                              <div class="block  fr">Блок будет располагаться с правой стороны</div>
                                                                              <div class="cl"> // очищаем обтекание, чтобы блоки не налезали на контент, идущий далее.</div>
                                                                              


                                                                              p.s. в преддверии смерти IE, не поддерживающих css свойство display: inline-block, «float» остается актуальным.
                                                                              • НЛО прилетело и опубликовало эту надпись здесь
                                                                                  –1
                                                                                  Лично мой выбор, уход от использования hasLayout и хаков для IE. С ними было много проблем.
                                                                                  • НЛО прилетело и опубликовало эту надпись здесь
                                                                                0
                                                                                Спасибо за шпаргалку.

                                                                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                                                Самое читаемое