Верстка плитками и вариант решения на JQuery
Верстка плитками и вариант решения на JQuery
Одним из последних веяний в веб-дизайне, да и в GUI в принципе, является плиточная верстка. Win8 яркий тому пример. Наверное, с точки зрения дизайна это очень клево и стильно. Так уж исторически сложилось, что я не дизайнер, я верстальщик. И вот именно в верстке плитками есть много тонкостей и сложностей.
Сначала выскажу свое видение вариантов такой верстки.
1. Если в дизайне все блоки имеют одинаковый размер.
Проблем я не вижу. Жмем блоки друг к другу с помощью float:left и пляшем.
2. Блоки имеют одинаковую ширину, но разную высоту.
Можно, конечно, воспользоваться таким же вариантом с float:left, но в результате вы получите следующую проблему:
Та-да-да-дан
Это особенности свойства float: left, кстати, если использовать display: inline-block, ситуация будет ровно такой же, поскольку элементы хоть и применяют свойства блочных элементов, но в линию выстраиваются как строчные, т.е. по строкам, такое вот масло масленное.
Но хотелось бы увидеть результат, когда не будет пустых ячеек и нижние три блока поднимуться выше.
Лично я решал эту проблему колоночным вариантом верстки: 4 колонки (или столько колонок, сколько вам нужно) и в них добавляются ваши блоки контента. Выглядеть это будет примерно вот так:
Красота, не правда ли? Конечно, тому кто будет эту верстку притягивать к движку, надо будет как-то заполнять сверстанный макет, но это уже не наша проблема, у нас верстка идеальна. Только, как правило, это наша проблема, а наполнять можно либо по очереди в каждую колонку, но тогда может оказаться, что одна колонка много больше других, что не очень хорошо, либо анализировать высоту колонок и добавлять в ту, высота которой меньше. А вот эту идею надо запомнить, он нам еще пригодится.
Перейдем к последнему типу плиточной верстки
3. Блоки имеют различную высоту и ширину.
Не совсем различную, а есть некоторый базовый блок, а все остальные имеют размер кратный базовому. По крайней мере, мне хочется верить, что все обстоит именно так =) Как быть тут? Понятно, что вариант 1 и 2 нам не подходят. Но дизайнеры, нормальные дизайнеры, понимают, что можно сделать, а что нельзя. Соответственно, верстальщик может выделить в макете некоторую закономерность или упорядоченность. Сразу приведу пример как я решал проблему неодинаковых блоков.
Так что же тут происходит?
Можно идти очень сложным, но логичным путем, сначала выделяем большой блок, равный одной строке, в нашем случае этот блок будет равен 4 базовых блока в ширину и 2 базовых блока в высоту. Затем, для верхних двух маленьких блоков создаем собственную обертку, чтобы они располагались один под другим. Для верхних правых такая же история.
Я в данном примере, исключил большой блок 2х4, он только загромождает верстку, поэтому структура такая. (Дальше размеры блоков будут обозначаться NxM, где N — ширина в базовых блоках и M — высота в базовых блоках)
- Блок 1х2 с float: left
- Внутри него 2 блока 1х1 без float: left
- Блок 2х2 с float: left
- Снова блок 1х2 с float: left
- Внутри него 2 блока 1х1 без float: left
- Затем переход но новую строку и начинает ее блок 2х2 c float: left
- И т.д.
В данном примере, структура не очень сложная, но даже заполнение такой верстки, когда она станет шаблоном определенного движка, у меня вызывает некоторые вопросы, особенно, если, вдруг, появится подгрузка контента, т.е. так называемый, бесконечный скролл. Если структура будет сложнее, думаю, вы сами понимаете весь масштаб трагедии, как с точки зрения верстки, так и с точки зрения наполнения этой верстки.
Вот и у меня возникла мысль: «Ну ее нафиг, такую структуру, надо искать плагины плиточной верстки!»
Я не любитель искать, особенно, когда в голове уже сидит идея как можно сделать свой велосипед и по какой логике он должен работать. Вот так и рождаются стопицот квадратноколесых велосипедов.
Как оно работает?
Есть некоторый стандартный набор элементов: во-первых обертка с классом tile_content, которая наполняется нашими элементами. Затем внутрь обертки помещается много-много необходимых элементов с обязательным классом b_itemtile и еще одним классом, который говорит нашему скрипту о размерах блока b_itemtile_1_1, где первая цифра ширина, а вторая высота. А больше ничего по верстке нет. Круто? Я считаю, что круто! Мне очень нравится такая простая верстка, тем более, что я прямо вижу как классно наполнять эту верстку =)
<div class="tile_content"> <div class="b_itemtile_1_1 b_itemtile"></div> <div class="b_itemtile_2_1 b_itemtile"></div> <div class="b_itemtile_1_1 b_itemtile"></div> <div class="b_itemtile_1_1 b_itemtile"></div> <div class="b_itemtile_1_1 b_itemtile"></div> <div class="b_itemtile_1_1 b_itemtile"></div> <div class="b_itemtile_1_1 b_itemtile"></div> <div class="b_itemtile_2_2 b_itemtile"></div> <div class="b_itemtile_1_1 b_itemtile"></div> <div class="b_itemtile_4_1 b_itemtile"></div> <div class="b_itemtile_1_1 b_itemtile"></div> <div class="b_itemtile_1_1 b_itemtile"></div> <div class="b_itemtile_1_1 b_itemtile"></div> <div class="b_itemtile_3_3 b_itemtile"></div> <div class="b_itemtile_1_1 b_itemtile"></div> <div class="b_itemtile_1_4 b_itemtile"></div> <div class="b_itemtile_1_3 b_itemtile"></div> <div class="b_itemtile_1_2 b_itemtile"></div> <div class="b_itemtile_1_1 b_itemtile"></div> <div class="b_itemtile_1_1 b_itemtile"></div> <div class="b_itemtile_3_4 b_itemtile"></div> <div class="b_itemtile_1_1 b_itemtile"></div> <div class="b_itemtile_1_4 b_itemtile"></div> <div class="b_itemtile_4_1 b_itemtile"></div> </div>
А самое классное это количество стилей для этой верстки
.tile_content{position: relative; outline: 1px solid #f00; overflow: hidden;} .b_itemtile{position: absolute; background: #aaa;}
И все! Все остальное сделает скрипт.
Приводить код скрипта не буду, скажу только, что он работает. И делает это следующим образом. У него есть пока всего 2 настройки: количество колонок и расстояние между блоками. Ну как настройки? В коде скрипта есть две переменные, которые и отвечают за эти параметры.
- Сначала вычисляется размер базового блока исходя из ширины контейнера, количества колонок и расстояния между ними
- Затем всем блокам выставляется необходимый размер, в соответствии с базовым блоком и расстоянием между блоками
- А затем начинается магия позиционирования!
- Магия проста, помним пункт 2 про колонки и как их заполнять. Тут все тоже самое, за исключением того, что физически нет никаких колонок, они вымышленные. Ищем ту колонку которая самая маленькая в данный момент, затем смотрим чтобы наш блок вошел по своим габаритам в соседние колонки и если все хорошо, пихаем этот блок на законное место при помощи абсолютного позицирнирования.
- Предыдущий шаг повторяется пока не будут спозиционированны все блоки по очереди
- Высота родительского блока выставляется равной высоте самой большой колонки
- Вуаля!
В данном подходе есть нюанс, что если блок нашел себе место, а соседняя, правая колонка имеет меньшую высоту чем найденная колонка, то высота соседней колонки равняется высоте текущей колонки, что ведет к дырам в плитках. Наглядная демонстрация. (Картинка)
Но если дизайн составлен под руководством здравого смысла, управляемого логикой, то на выходе красота, да и только.
Вот ссылка на архив с рабочим примером. К тому же я потихоньку изучаю Git и дам ссылку на github, есть вероятность, что к моменту прочтения поста, на гитхабе будет версия более похожая на плагин и более функциональна. Хотя меня пока устраивает и этот вариант, мои задачи он выполняет!