Задача
Добиться, чтобы блоки с заданной шириной, меньшей ширины контейнера, но неизвестной высотой, располагались друг за другом, образуя ровные строки.

Решение
У нас имеется HTML-код:
<div>
<h3>Прости мне, милый друг</h3>
Двухлетнее молчанье: Писать тебе посланье мне было недосуг. На тройке пренесенный из ...
</div>
<div>
<h3>От утра до утра</h3>
Два года всё кружился без дела в хлопотах зевая, веселился...
</div>
<div>
<h3>В театре, на пирах</h3>
Не ведал я покоя, увы! ни на часок, как будто у налоя в великой четверток измученный дьячок ...
</div>
<div>
<h3>Заботы и печали</h3>
Которые играли, стыжусь, столь долго мной; и в тишине святой философом ленивым ...
</div>>
<div>
<h3>С диваном, с камельком</h3>
Три комнатки простые - в них злата, бронзы нет, и ткани выписные не кроют их паркет...
</div>
<div>
<h3>Где мне в часы полдневны</h3>
Березок своды темны прохладну сень дают; где ландыш белоснежный сплелся ...
</div>
Этот код описывает последовательность блоков, которые имеют некоторое содержание. Количество текста в каждом блоке своё. Эти блоки имеют ширину (пусть в нашем случае это будет 33% от родительского элемента). Для того, чтобы их выровнять в одну линию, к ним применяется левое обтекание:
div {width: 33%; float: left}
Это отображается в браузере следующим образом:

Но вот, что будет, если в первой колонке окажется много текста:

Для борьбы с ошибками обтекания предлагается следующее решение:
Шаг первый
Представим строчки, которые мы хотим получить в виде обычных текстовых строк. И воспользуемся «чудесным» значением свойства display — inline-block. Применим его к нашим блокам, а для того, чтобы это корректно сработало в IE6, заменим блоки на инлайновые span.
<span>
<h3>Прости мне, милый друг</h3>
Двухлетнее молчанье: Писать тебе посланье мне было недосуг. На тройке пренесенный из ...
</span>
<span>
<h3>От утра до утра</h3>
Два года всё кружился без дела в хлопотах зевая, веселился...
</span>
<span>
<h3>В театре, на пирах</h3>>
Не ведал я покоя, увы! ни на часок, как будто у налоя в великой четверток измученный дьячок ...
</span>
<span>
<h3>Заботы и печали</h3>
Которые играли, стыжусь, столь долго мной; и в тишине святой философом ленивым ...
</span>
<span>
<h3>С диваном, с камельком</h3>
Три комнатки простые - в них злата, бронзы нет, и ткани выписные не кроют их паркет...
</span>
<span>
<h3>Где мне в часы полдневны</h3>
Березок своды темны прохладну сень дают; где ландыш белоснежный сплелся ...
</span>
span {width: 33%; float: left;
display: inline-block;}
Можно заметить, что внутри блоков, например, как у нас, могут находится блочные элементы, а помещать блочный элемент внутри инлайнового, так сказать, некошерно. Но меня это не интересует, т.к. я всегда могу для корректности употреблять только инлайновые элементы, а с помощью CSS задавать им нужный display. А сейчас просто не заморачиваюсь. И вам тоже советую не заморачиваться:-))
Теперь можно увидеть, что блоки выстроены по строкам, но при этом хромает вертикальное выравнивание:

Шаг последний
Выставляем нашим блокам вертикальное выравнивание:
span {width: 33%; float: left;
display: inline-block; vertical-align:top;}
Это даст нам то, что требуется:

Работающий пример можно посмотреть здесь.
Всех с праздником!
Так не проще ли сделать так:
ОтветитьУдалитьтем более любой шаблонизатор понимает остаток от деления на 3.
Нет, не проще, т.к. число колонок может быть произвольным.
ОтветитьУдалить+ шаблонизатор (что это вообще такое?) применим не в любом проекте
Да, жаль что нет предупреждения о вырезаемых тегах.
ОтветитьУдалитьДля всех поясню, что способ, мною предлагаемый таков
-div
--div float:left;/
--div float:left;/
--div float:left;/
-/div
Когда див закрывать - тогда собственно и срабатывает шаблонизатор.
В принципе, если знать количество колонок, то можно не парясь сделать таблицей.
А вот плюс Вашего решения - то что верстка получается на произвольную ширину.
Ну, не совсем...
ОтветитьУдалить1. Плюс как раз именно в произвольной высоте блоков) это более ценно
2. в вашем решении для того, чтобы вставить блок в самое начало (а остальные должны сдвинуться), предётся переделать всё разбиение по тройкам.
понимаете?
Ваш способ сработал везде, кроме Seamonkey
ОтветитьУдалитьНиколай, это как понять? Хорошо или плохо? ;))
ОтветитьУдалитьпомнится наткнулся на habrahabr и сейчас активно пользуюсь этим методом.
ОтветитьУдалитьhttp://tjkdesign.com/articles/css-layout/
А вы таблицу юзать не пробовали?
ОтветитьУдалитьНе нужно привязываться к глупой философии.
Табличные данные верстаются таблицами. Юзать для этого блоки калечно и дико.
дивы сьело.. вот вообщем они:
ОтветитьУдалитьdiv id="block" /div
div id="block" /div
div id="block" /div
div id="separator" /div
div id="block" /div
div id="block" /div
div id="block" /div
Но если вам уж так сильно хочется блоками то вот пожалуйста:
ОтветитьУдалитьbody {
width:100%;
}
#block {
float:left;
width:300px;
clear:none;
}
#separator {
float:left;
clear:both;
width:100%;
height:20px;
}
Кста.. вы юзали span. Это не совсем верно. Так как он используется для других целей, и юзать его в качестве блока не совсем верно с логической точки зрения.
ОтветитьУдалитьДля пользователей Seamonkey плохо, для остальных хорошо. Я отношусь к остальным. Так что все в порядке :)
ОтветитьУдалитьнемного не потеме, но у вас в инета магазе можно заказать отрицательное количество товаров :(, на сайте графити проверил
ОтветитьУдалитьКто таки эти вездесущие пользователи Seamonkey?)
ОтветитьУдалитьПожалуй поделюсь своим решением.
ОтветитьУдалитьСемантично, без лишних элементов, кроссбраузерно (проверено в IE6+, FF2+).
HTML:
<ul><!--
--><li>
<h3>Прости мне, милый друг</h3>
<p>Двухлетнее молчанье: Писать тебе посланье мне было недосуг. На тройке пренесенный из ...</p>
</li><!--
--><li>
<h3>От утра до утрa</h3>
<p>Два года всё кружился без дела в хлопотах зевая, веселился...</p>
</li><!--
--><li>
<h3>В театре, на пирах</h3>
<p>Не ведал я покоя, увы! ни на часок, как будто у налоя в великой четверток измученный дьячок ...</p>
</li><!--
--><li>
<h3>Заботы и печали</h3>
<p>Которые играли, стыжусь, столь долго мной; и в тишине святой философом ленивым ...</p>
</li><!--
--><li>
<h3>С диваном, с камельком</h3>
<p>Три комнатки простые - в них злата, бронзы нет, и ткани выписные не кроют их паркет...</p>
</li><!--
--></ul>
CSS:
li {
width: 33%;
vertical-align: top;
display: -moz-inline-stack; /* for Fx2*/
display: inline-block; /* normal browsers */
zoom: 1; /* for IE (hasLayout true) */
*display: inline; /* for IE */
}
Почему не таблица? Можно сказать что это несемантично, но думаю убедительной будет то, что при использовании списка намного проще управлять количеством элементов в строке - простым изменением ширины элемента списка.
Так как наш список фактически текст, то пробельные символы между элементами будут отображены браузером. Из-за этого на на небольших ширинах контейнера эти два пробела в строке в сумме могут оказаться больше оставшегося 1% и последний элемент упадёт на следующую строку. Есть два решения:
1) Не ставить пробелов между элементами списка в коде.
2) Заключить пробелы в комментарии.
Я использую второй способ.
В стилях никаких float'ов не нужно - inline-block относительно родителя ведёт себя как инлайновый элемент.
FireFox 2 не поддерживает display: inline-block, но у него есть проприетарное display: -moz-inline-stack, которое полностью повторяет нужное поведение.
Для IE не обязательно использовать инлайновый элемент для того чтобы заработал inline-block, достаточно после указания display: inline-block; переопределить display значением inline.
Сколько геморроя, чтобы воспроизвести функционал уже существующей и поддерживаемой во всех броузерах таблицы :(
ОтветитьУдалитьВашу бы энергию да в мирных целях использовать...
2Алексей Кузьмин:
> Почему не таблица? Можно сказать что это несемантично
Ага, а заголовки в список помещать это видать семантично
Далеко не так просто. У таблиц много «против», и они объективны.
ОтветитьУдалитьНу перечислите "против", хоть знать буду
ОтветитьУдалить1. больше тегов и их вложенности, а значит медленнее работа JS
ОтветитьУдалить2. меньше гибкости, когда надо быстро поменять что-то местами
и т.д.
> 1. больше тегов и их вложенности, а значит медленнее работа JS
ОтветитьУдалитьЗато броузеру легче строить предположения, чего от него требуется, значит выше скорость отрисовки.
+ обращение по ID независит от уровня вложенности.
> 2. меньше гибкости, когда надо быстро поменять что-то местами
Читать (и понимать!) табличный код проще. В Вашем же случае в коде будет лента DIVов и прежде чем менять местами, придётся ещё разобраться, что тут к чему.
> и т.д.
Вообщем, коллега Никишаев в своём сообщении от 11 сентября был прав, тут в основном религиозная убеждённость, не требующая объяснений.
ЗЫ
+1 Вам за то что удержались от обычного аргумента ДИВных верстальщиков "W3C не рекоммендует!", который я ждал :)
1. чтобы отрисовать таблицу, браузер должен произвести достаточно много вычислений (т.к. размер всех ячеек может зависеть от контента). Не вижу принципиальной разницы с дивами. Кстати, посмотрите внимательнее, речь шла о JS, который работает на порядок медленнее рендера
ОтветитьУдалить2. ну как вы можете это утверждать, когда как правило это не так. Говорю из моего опыта и опыта тысяч верстальщиков. Когда 2-3 вложенные таблицы - это ужас. Особенно если ещё форматирование плохое.
ЗЫ
возьмите плюс себе, мне он не нужен, т.к. я имею достаточный опыт вёрстки, чтобы считать ваши доводы некорректными!
> чтобы отрисовать таблицу, браузер должен произвести достаточно много вычислений (т.к. размер всех ячеек может зависеть от контента). Не вижу принципиальной разницы с дивами.
ОтветитьУдалитьПри фиксированной ширине колонок, броузер заранее имеет представление, что его ждёт. А в случае с ДИВами не имеет никакого представления вообще.
> Когда 2-3 вложенные таблицы – это ужас
А эмуляция 2-3 вложенных таблиц с помощью ДИВов - это букет фиалок, надо полагать? :)
Не думаю также, что Вы имеете право за тысячи верстальщиков высказываться.
> возьмите плюс себе, мне он не нужен, т.к. я имею достаточный опыт вёрстки, чтобы считать ваши доводы некорректными!
Скажу больше, чтобы считать чужие доводы некорректными, вообшще никакого опыта не требуется :)
1. Бред.
ОтветитьУдалить2. Бред.
3. Может быть.
> Кстати, посмотрите внимательнее, речь шла о JS, который работает на порядок медленнее рендера
ОтветитьУдалитьПосмотрите внимательнее, обращение по ID избавляет от необходимости обходить иерархию вообще!
(Не всегда можно использовать ID, чтобы было удобно работать с js)
ОтветитьУдалитьБред.
ОтветитьУдалить> 1. Бред. 2. Бред. 3. Может быть.
ОтветитьУдалитьОке, я всё понял!
> Бред.
ОтветитьУдалитьНу хватит, хватит, я всё понял уже!