Скажем прощай oveflow: hidden!
Понедельник, 21 декабря 2009

Продолжу эстафету, начатую автором блога cuprum.name, в которой эстафетостартер ( :) предлагает блогерам поделиться со своими читателями переводом интересных зарубежных статей из своего RSS-ридера.
Отмечу сразу, что переводом мой текст можно будет назвать лишь условно, скорее это будут свои мысли, основанные на чужой статье. А оригинал вы сможете найти здесь.
Сейчас в разметке большинства сайтов, в той или иной мере, используется подход с применением float, для «лечения» которого верстальщики применяют разные подходы (всем ведь известно про схлопывающийся контейнер для блоков с float, нарушение потока для последующих элементов разметки, и проблемы, связанные с этим?).
Из часто встречающихся решений для очистки плавающих блоков можно увидеть (кратко пройдёмся по всем методам):
1. Метод с дополнительным <div style="clear:both"></div>
Который (<div>) помещается в тот же контейнер, в котором есть плавающие блоки, непосредственно после них. Позволяет контролировать плавающие элементы относительно последующей разметки. Например, не позволит следующими за плавающей картинкой заголовкам, спискам, абзацам и т.д, наползать на неё.
Негибкий, в плане, что всегда нужно вмешиваться в HTML-код и создавать лишний пустой блок в разметке.
2. Метод с position: relative
Позволяет «вернуть» высоту и видимость фона родительского блока, относительно плавающего, с помощью свойства position: relative.
Основная сложность метода в том, что такой подход трудно контролировать в сложной разметке, если родителей для элемента с float очень много. И для всех придется дополнительно прописывать CSS-свойство position: relative. Ест много времени верстальщика и требует усиленного тестирования. Поэтому, лучше сразу забыть про этот способ.
3. Метод overflow: hidden
Наиболее популярный, простой и часто встречающийся. Здесь можно остановиться подробнее, так, как с ним мы, собственно, и собрались попрощаться :)
Суть метода в том, что родителю плавающего блока добавляется свойство overflow: hidden. Преимущество в том, что по сравнению с предыдущим способом, можно вылечить поток всего лишь одной строкой.
Правда, требуется дополнительный «костыль» для IE6: дополнительно включаем hasLayout с помощью zoom: 1, или, если требуется валидность, height: 1%.
Весь код в этом случае выглядит примерно так:
1 2 3 4 5 6 | #container { overflow: hidden; } * html #container { height:1%; } |
Несмотря на кажущуюся простоту, overflow: hidden иногда не годитcя, если в верстке нужно использовать элементы с отрицательным margin (попробуйте прицепить вебдванольный стикер в такой блок), есть проблемы с ссылками-якорями в Opera (об этом я расскажу в следующий раз), и способен преподнести сюрпризы, как в этом демо (два нижних примера).
Если есть ограничения, значит метод уже не универсальный.
4. Самоочистка для плавающих блоков
Давно известный (да, я не сделал громких откыртий в этом посте!), но мало распространённый метод, основанный на применении к плавающему блоку свойства content: after, выводящему дополнительный контент (текст, точка или пробел) после него, к которому применяется display: block, чтобы сделать его блочным элементом с очисткой clear: both, и одновременно невидимым с помощью visibility: hidden…
В общем, лучше сразу смотрите код, который недавно обновился и больше не поддерживает устаревший IE/Mac:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | .floatElement:after { visibility: hidden; display: block; clear: both; content: " "; height: 0; } /* хаки для IE6,7 */ * html .floatElement { height: 1%; } *:first-child+html .floatElement { min-height: 1px; } |
Судя по той же демке (пример 2), способ избавит вас (как минимум :) от проблем с тенью в CSS3.
Способ более универсальный и гибкий, по сравнению с первыми двумя, и позволяет избежать проблем, связанных с «обрезкой» overflow: hidden и просто просится занять свое место в вашем личном CSS-фреймворке. Кроме того, это единственный метод, который применяется непосредственно к плавающему элементу, а не к его родителю.
Лучше всего его использовать, создав отдельный класс в стилевом листе для плавающих элементов, как, например, .group в статье-источнике мыслей или книге Дэна Седерхольма «Handcrafted CSS».
Дополнительно про float можно почитать на designformasters.info
* * *
Участники эстафеты:
- cuprum.name — Работа с цветовой моделью RGBA
- rotorweb.ru — Скажем прощай overflow: hidden!
- dreamhelg.ru — Фантастическая CSS3 лайтбокс галерея с помощью jQuery
- список cо временем пополнится…
* * *
На этом всё, передаю эстафету Сергею М. (iskariot.ru), Виталию (codeisart.ru) и Насте (mannodesign.com).
Кроме того, чтобы эстафета получила активное развитие (или я кого-то забыл пригласить), предлагаю присоединиться, если вы ведёте блог на смежную тему, имеете в своем активе не ниже ста RSS-подписчиков и способны выполнить все условия эстафеты. Присоединяйтесь!
* * *
* * *
Понравилась статья?
Тогда помогите мне сделать её доступной для других, или будьте в курсе последних событий:
* * *

Я постоянно пользуюсь 1-м, 3-м и 4-м методами, в зависимости от конкретной ситуации.
По поводу 3-го пункта, можно сделать просто вот так:
тогда хак для IE6 не нужен.
А про 2-й способ вообще первый раз вижу и не понимаю, что это за способ такой.
Есть такой способ (второй), я помню давно вычитал на одном из англоязычных блогов. Но после нескольких попыток использования отказался в пользу третьего метода.
А после прочтения книги «Пуленепробиваемый веб-дизайн» Седерхольма, года три назад, пользуюсь четвёртым.
Да. Решение отличное. Overflow:hidden тут вообще ни к селу ни к городу, имхо. Мне никогда не нравился. В основном юзал 1й и 4й методы.
Я бы не стал так резко.
overflow: hiddenхорошо работает в простой вёрстке «без выкрутасов».Просто я сейчас в поиске целиком и полностью универсальных решений, которые можно использовать везде. В этом плане вариант 4 пока без недостатков.
Вместо вот этого:
обычно использую:
в CSS, подключенном через conditional comments.
Это понятно, но первый вариант, хоть и является хаком-костылём для IE, полностью валиден. Иногда (и для некоторых) это очень важно.
кто бы что не говорил, а бездумная «мастурбация» на валидность страницы не имеет под собой никаких оснований, не отрицаю, что валидаторы являются удобными инструментами, особенно для новичка (лично я, например, пользуюсь валидатором раз в пятилетку, изибрательно, для контроля, потому что пишу валидный код без всяких валидаторов просто потому что воспитал себя в своё время, когда ещё начинал работать в этой области) но речь не об этом, а о том, что поддержка в веб-приложениях старых версий браузеров, в частности IE, практически исключает возможность иметь полностью валидный CSS, именно поэтому придумали как вынести всю ересь для IE в отдельный файл и закомментировать всё это специальным образом
К четвертому способу почему то была некая предубежденность; наверное, стоит начать использовать.
Соглашусь с Q-Zma — сейчас оправданнее выносить весь мусор для IE 6 и 7 в условные комментарии (можно даже в один файл). У всех последних версий «смотрелок» все более-менее предсказуемо и им вполне может хватить одного стилевого файла.
Как на счет класса clearfloat?
Хотя у меня вообще это все идет обычно одной строчкой...
Сильно напоминает третий вариант, с небольшими изменениями.
Нет. Это, как раз-таки, и есть «старый» четвертый метод.
Сейчас же он больше не поддерживает устаревший IE/Mac и убрали лишнюю «.» из контента (чтобы пользователи речевых браузеров не слышали после плавающих блоков что-то типа «интересный контент...точка...описание картинки...точка... »).
Так что, в новых проектах, можно смело заменить этот код на тот, что представлен под номером 4 и снова быть на волне современных тенденций в верстке :)
Век живи
я использую первый метод, делаю такой div {clear: both; font-size: 1px; height: 10px;} и использую его, чтобы сделать отступы, а то, что надо лезть в хтмл меня не затрудняет.
Есть способ, когда свойство content: after добавляется родителю плавающего блока:
.container:after {
display:block;
clear:both;
content:"";
}
/* Если нужно, для IE 6 включаем haslayout */
* html .container {height:1%;}
Эффект такой, как при первом способе, но не нужно «лезть» в HTML.
Про четвертый способ в посте сказано: «Кроме того, это единственный метод, который применяется непосредственно к плавающему элементу, а не к его родителю.» Но это тоже не всегда удобно. Очень часто верстальщик не знает, что клиент в последствии «напихает» в блоки. В таких случаях лучше, чтобы соответствующие свойства были заданы для родителя плавающих блоков (если клиент добавит плавающие блоки, то ничего не развалится)
Я использую {display:inline-block} для родителя.
По моему очень удобно, одна строчка и валидно. :)
В четвертом способе написано [b]"Кроме того, это единственный метод, который применяется непосредственно к плавающему элементу, а не к его родителю.[/b]" Кажется это ошибочно, судя по всему 4-й способ все таки применяется к родительскому блоку содержащему плавающие элементы.
[b]css:[/b]
[code]
.floatElement:after {
visibility: hidden;
display: block;
clear: both;
content: " ";
height: 0;
}
/* хаки для IE6,7 */
* html .floatElement {
height: 1%;
}
*:first-child+html .floatElement {
min-height: 1px;
}
ul.test {
padding: 5px;
border: 1px solid red;
}
ul.test > li {
margin: 5px;
width: 25px;
height: 25px;
background: blue;
float: left;
}
[/code]
[b]html: (не работает)[/b]
[code]
[/code]
[b]html: (работает)[/b]
[code]
[/code]
[...] rotorweb.ru — Скажем прощай overflow: hidden! [...]