Управление потоком в CSS: создаём контекст форматирования

    Управлять потоком можно не только свойствами clear или overflow. Возможно, вы найдёте полезным для себя использование display:inline-block или display:table-cell, способных полностью заменить вам упомянутый overflow, избавляя вас от опасности указания размеров элемента, а также предоставляя дополнительные возможности.

    Статья не содержит универсальных решений, но открывает вашему взору дополнительный инструментарий для управления потоком.

    Вот полный перевод абзаца о контекстном форматировании блочных элементов (из css спецификации):
    Плавающим (float), абсолютно спозиционированным, отображаемым как табличные ячейки (table-cell) или заголовки таблиц (table-caption), строково-блоковым (inline-block) и элементам с overflow отличными от visible (не считая случаев, когда значение наследуется областью просмотра) устанавливается новый контекст для форматирования

    С плавающими и абсолютно спозиционированными элементами, думаю, всё ясно; с 'overflow' тоже. Сразу добавлю, что эксперименты с заголовками таблиц ни к чему не привели.

    Что бы не дублировать, оглашу, что новый код используется везде с изначально написанным следующим стилевым кодом:
    #sidebar{
    	width:30px;
    	height:200px;
    	background-color:#ddd;
    	float:left;
    }
    #content{
    	background-color:#dcd;
    	}
    	
    	#content
    	.col{
    		float:left;
    		height:50px;
    		width:30px;
    		text-align:center;
    		background-color:#cdd;
    		}
    #content2{
    	background-color:#ddc;
    }

    и разметкой:
    <div id="sidebar">
    	side
    </div>
    <div id="content">
    	<div class="col">
    		col1
    	</div>
    	<div class="col">
    		col2
    	</div>
    	<div class="col">
    		col3
    	</div>
    </div>
    ff
    <div id="content2">
    	more content
    </div>			
    		


    Данный код вот так отрисовывается в браузерах:


    1. display:inline-block


    Итак, давайте посмотрим на что способен display:inline-block
    #
    Подправим firefox и ie (при наличии hasLayout display:inline работает как display:inline-block)
    #
    Разберёмся с лишним горизонтальным пространством vertical-align:bottom добавим *vertical-align:0% для IE и опустим текст в Опере (vertical-align:text-bottom).
    #
    Вертикальное пространство — баг IE, который появляется при сочетании hasLayout у одного элемента и float у другого. Будет даже если вы используете overflow:hidden, не имеет никакого отношения к display:inline-block, и если вам критично… — возлагаю поиск решения на ваши плечи, а я пока воспользуюсь *margin-left:-3px
    #

    К сожалению не всё так хорошо как кажется: проблема во втором ff, который может совершенно непредсказуемо отображать контент внутри контейнеров с -moz-inline-box, -moz-inline-stack и -moz-inline-block. Хотя в данном случае все колонки со свойством float отобразились нормально.

    2. display:table-cell


    Теперь приступим к display:table-cell
    #
    Всё здорово, safari тупит — напишем просто table, а ie совсем не поддерживает table-cell — тогда сделаем, что бы хотя бы отображалось как во всех браузеров
    Что у нас —
    а)ширина элемента определяется контентом
    б)элемент не пускает другие элементы на свой горизонтальный уровень
    Почти тоже самое что и display:inline-block, только надо добавить перенос строки. Делаем всё это для IE и сразу исправляем известные изъяны.
    #

    Этот способ я бы и стал использовать. Тем более что, если после контейнера идёт не текст или строковый элемент, а элемент блоковый — не нужно делать перенос строки в IE, а также стоит отметить, что если известна ширина контейнера, то
    1) не нужно использовать в IE display-inline, потому что вы определяете ширину, а не контент контейнера
    2) не нужно делать перенос строки для IE, потому что мы не симулируем display-inline
    3) не нужно отдельное свойство для включения hasLayout, потому что width включит его

    3. Float


    Как я уже писал float также создаёт новый контекст форматирования. Не уверен, что пригодится, но знать мы должны. Итак, как это проявляется? float:left установленный для .col вырывает их из потока и их контейнер вроде бы как ничего не содержит и фактически #content не отображается, если ему не задать ширину и высоту. Что бы убедится давайте уберём фон у .col (а также всю последующую мишуру) :
    удаляем background-color у .col
    #
    А теперь посмотрим к чему приведёт overflow:hidden (в ie включаем hasLayout)
    #
    table (ie опущу по понятным причинам)
    #
    и наконец float:left (можно и right).
    #

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

    Используя данные техники вы сможете сможете решить проблемы которые присущи свойствам clear и overflow, а также увеличить производительность браузеров, обрабатывающие ваши страницы.

    Эта же статья на моём сайте Управление потоком в CSS: создаём контекст форматирования
    Поделиться публикацией

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

    Комментарии 34
      +4
      битва за поток, часть третяя =)
      • НЛО прилетело и опубликовало эту надпись здесь
          0
          казалось бы — почему создатели браузеров наконец не могут договориться о единой поддержке css!..
          • НЛО прилетело и опубликовало эту надпись здесь
              +4
              Пока ИЕ не перестанет быть дефолтным браузером в Винде — мы будем оочень долго ждать, увы.
              • НЛО прилетело и опубликовало эту надпись здесь
                  +1
                  Ага, года через 3, а то и позже…
                  Совсем скоро.
                    0
                    CSS тоже не стоит на месте через 3 года будет уже новые версии css, которые врятли, по сущ. тенденциям, будут поддерживаться IE
              • НЛО прилетело и опубликовало эту надпись здесь
                  0
                  откуда такие странные графики?
                  это по конкретному сайту?
                  ибо по миру опера вообще не в доле :) пока
              0
              А как быть с IE под МАС?
                +10
                так же как с 4й оперой
                  +1
                  inline-block судя по всему и в нём включает hasLayout
                  0
                  IE поддерживает inline-block
                    0
                    какой именно? ie6 только в виде display:inline + hasLayout
                      0
                      тут параллельно вашему есть объясняющий комментарий (IE6 тоже поддерживает inline-block).
                    • НЛО прилетело и опубликовало эту надпись здесь
                      0
                      Вариант весьма интересный, однако обкатывать его на наличие подводных камней предстоит ещё долго.
                        0
                        display:table ведёт себя предсказуемо во всех браузерах, hasLayout уже довольно неплохо изучен.
                          +1
                          Увы, но чем больше я занимаюсь вёрсткой, тем больше я убеждаюсь в том что ие и предсказуемость понятия не совместимые.

                          Даже седьмая версия одного_очень_замечательного браузера порой выкидывает интересные номера, из за которых приходится долго прыгать с бубном.
                            0
                            Верстайте, согласно стандартов и всё будет ок :)
                            Так как все браузеры по умолчанию поддерживают стандарты.
                            Правда еще существует вопрос, в том как например ms понимает этот стандарт ;)
                            Но если придерживаться строгих стандартов и соблюдать правильность стандартов технологий, то можно спокойно верстать любые сайты и без всяких грязных хаков.
                            Просто надо не лениться и почаще читать, например такие статьи.
                            Поэтому спасибо автору за статью, к тому же хорошо проиллюстрированную и подготовленную.
                              +2
                              Верстайте, согласно стандартов и всё будет ок :)
                              Так как все браузеры по умолчанию поддерживают стандарты.
                              Правда еще существует вопрос, в том как например ms понимает этот стандарт ;)
                              Но если придерживаться строгих стандартов и соблюдать правильность стандартов технологий, то можно спокойно верстать любые сайты и без всяких грязных хаков.

                              Далеко от реальности.
                                0
                                Правильнее будет: старайтесь соблюдать рекомендации W3C.

                                Далеко не все браузеры их поддерживают, да и стандартом они вовсе не являются, это лишь РЕКОМЕНДАЦИИ, и MS уже не раз демонстрировала на практике своё к ним отношение.
                        • НЛО прилетело и опубликовало эту надпись здесь
                            0
                            потому я и советую display:table ))
                            • НЛО прилетело и опубликовало эту надпись здесь
                              +2
                              Второго можно нелохо прокачать, сделать внутри элеменов еще один с display: block; position: relative; Причем чтобы ие смог применить inline-block нужно чтобы элементы изначально инлайновые, а чтобы мозг у рандомного рендера фаерфокса не свело, нужно чтобы все дочерние элементы тоже были изначально инлайновыми. И для того-же второго фф нужно все флоаты внутри сделать relative. А для оперы 9.2 сделать их обратно static с помошью хака. Короче, проблем— море, но мне удалось решить все на довольно сложной разметке. Основное, что привлекло — возможность без последствий использовать блоки разной высоты, и даже выравнивать их через vertical-align, так что игра стоит свечь.
                              +4
                              У вас в примерах display:-moz-inline-box; добавляется после display:inline-block; В таком случае Fx 3 тоже «подхватывает» -moz свойство, вместо inline-block, что как-то не логично. ;)

                              А статья очень познавательна, спасибо (кармы нет, поэтому только на словах, извините :)).
                                0
                                Спасибо в карму не положишь?0_о

                                <левее>Иллюстрации хорошо сделаны… был бы такой генератор, что бы сайт раз, и он тебе табличку на всех бравзерах показал...</левее>
                                  +1
                                  http://browsershots.org/

                                  Но он подходит только для самых простейших тестов. Как правило, самые сложные баги являются динамическими, т.е. возникают при взаимодействии с браузером (ресайз окна, наведение курсора на ссылку, выделение, добавление текста).
                                0
                                ошибка: «загаловками таблиц»
                                  0
                                  спасибо. можно было личным сообщением :)
                                  0
                                  1. Хорошо бы сначала показывать html-структуру примера, а потом применённые к ней стили.
                                  2. «Итак, давайте посмотрим на что способен display:inline-block...» — тут нужно дописать: "… применённый к классу такому-то".
                                    0
                                    структура общая, если бы указывал каждый раз была бы каша.
                                    а так мы просто вносим в изменения в один и тот же кусок html

                                    кстати, спасибо за замечания! чуть позже подправлю, действительно будет лучше

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

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