Responsive square divs with jQuery and Bootstrap.
Что делать, если у нас блоки разного размера, и они должны образовать сетку? Конечно, изотоп-масонри. Но вот беда — что делать, если сетка должна на любом размере браузера не образовывать рваного низа? То есть каждый блок из элементов, а расположение квадратных, горизонтальных и вертикальных элементов постоянно разнится, должен иметь ровный низ, как на принтскрине. Если загнать картинки в изотоп (что изначально и было сделано), то на ресайз первая горизонтальная картинка становится короче, чем две справа от нее. Это происходит из-за расстояния МЕЖУ ними, так как размер картинок уменьшается-увеличивается, а паддинг в пикселях — нет.
К тому же мы хотим верстать все на бутстрапе, чтобы не морочиться с перепрыгиванием элементов вниз на планшетах и мобилках.
Мы решаем загонять в кубики картинки не через <img src=»…»>, а с помощью бэкграунда. Но тут возникает проблема — чтобы бэкграунд срабатывал, содержащим его элементам нужно давать ВЫСОТУ. И мы не можем сделать ее жесткой, так как на ресайз ширина будет меняться, а кубики должны оставаться квадратными, не вытягиваться.
На помощь пришел вот этот референс Responsive, square elements with JavaScript/jQuery. Приведу его здесь, плюс выросшее на базе решение, как организовать вертикальные и горизонтальные блоки, чтобы они всегда по высоте совпадали с квадратными.
Итак, у меня есть маленькие кубики — <div class=»item small»>, есть горизонтальные <div class=»item wide»>, вертикальные <div class=»item long»> и большие кубы <div class=»item big»> (кресло STRANDMON).
Маленькие делаем прямо по референсу, кроме разметки цсс, так как по ширине они у меня загнаны в бутстрап-колонки. Еще одна деталь — каждый кубик имеет внизу подпись на белом фоне, она является частью квадрата, то есть выделенная под картинку область чуть меньше по высоте, чем идеальный квадрат, поэтому я произвожу калькуляцию процентов:
Если
Ширина (колонки бустрапа) = 100%
Высота = 83%
и нам нужно найти высоту, то Высота = Ширина * 83% / 100% (вспоминаем алгебру)
function adjustHeight() { var myWidth_small = $('.item.small').width(); /* ширина маленького кубика */ var finalResult = (myWidth_small * 83 / 100) + 'px'; /* считаем высоту с учетом, что она - 83% от ширины */ $('.item.small').css('height', finalResult); /* присваиваем эту высоту кубику */ } adjustHeight();
Пока что все элементарно. Высота горизонтальной картинки — ура — такая же, как маленьких кубиков, поэтому присваиваем ее обоим элементам через селектор item (вот в чем удобство множественных классов), убираем уточнение small:
function adjustHeight() { var myWidth_small = $('.item.small').width(); /* ширина маленького кубика */ var finalResult = (myWidth_small * 83 / 100) + 'px'; /* считаем высоту с учетом, что она - 83% от ширины */ $('.item').css('height', finalResult); /* присваиваем эту высоту кубику */
}
Далее логично предположить, что высота большого квадрата равна высоте маленького, умножить на 2, однако на деле он оказывается короче. В чем дело? Дело в следующем — два маленьких кубика имеют ДВЕ подписи, а 1 большой — ОДНУ. И нам не хватает еще одной высоты этой белой полоски. Так как высота подписи разная в зависимости от устройства, найдем ее динамически через jQuery:
var title_height = parseInt($(".title").height());
И добавляем еще одну переменную finalResultBig:
function adjustHeight() { var title_height = parseInt($(".title").height()); var myWidth_small = $('.item.small').width(); /* ширина маленького кубика */ var myWidth_big = $('.item.big').width(); /* ширина большого куба */
var finalResult = (myWidth_small * 83 / 100) + 'px'; /* считаем высоту с учетом, что она - 83% от ширины */ var finalResultBig = ( (myWidth_big * 83.7 / 100) + title_height ) + 'px'; $('.item').css('height', finalResult); /* присваиваем эту высоту маленькому и широкому кубикам */ $('.item.big').css('height', finalResultBig);
}
Что присходит с длинным вертикальным? Его высота равна высоте большого куба:
function adjustHeight() { var title_height = parseInt($(".title").height()); var myWidth_small = $('.item.small').width(); /* ширина маленького кубика */ var myWidth_big = $('.item.big').width(); /* ширина большого куба */
var finalResult = (myWidth_small * 83 / 100) + 'px'; /* считаем высоту с учетом, что она - 83% от ширины */ var finalResultBig = ( (myWidth_big * 83.7 / 100) + title_height ) + 'px'; $('.item').css('height', finalResult); /* присваиваем эту высоту маленькому и широкому кубикам */ $('.item.big').css('height', finalResultBig); $('.item.long').css('height', finalResultBig);
}
Теперь внимание — на телефоне все кубики падают один под другой, то есть в ряду у нас по 1 элементу. Маленькие и большие кубики принимают свою высоту, зависимую от ширины (значит они станут у нас одного размера). Но вот широкие у нас принимают высоту квадратных, а значит, горизонтальные картинки будут по бокам наполовину обрезаны. Поэтому нам необходимо разделить — какую высоту принимают горизонтальные картинки на десктопах и планшетах, а какую — на мобилках. Еще одна проблема — вертикальные полосы. На десктопе они принимают высоту больших кубиков, но на мобилке большие кубики уже не такие большие — они же по высоте такие же как по своей ширине — а шире мобильника не станешь. Поэтому все вертикальные обрежутся по высоте. Что делать? Задать двойную высоту квадратных! Делаем все манипуляции через условие if на ширину устройства. Для этого не забудьте сначала найти эту самую ширину устройства, мой способ предполагает использование джс-библиотеки viewportSize-min.js. Скачать: viewportSize-min. Этот мини-файлик помогает вычислять высоту и ширину вьюпорта также, как это делают медиа-квери — с у четом скролл-баров.
var w_height = viewportSize.getHeight(); var w_width = viewportSize.getWidth();
function adjustHeight() { var title_height = parseInt($(".title").height()); var myWidth_small = $('.item.small').width(); var myWidth_big = $('.item.big').width(); var finalResult = (myWidth_small * 83 / 100) + 'px'; var half_finalResult = ((myWidth_small * 83 / 100) / 2) + 'px'; var twice_finalResult = ((myWidth_small * 83 / 100) * 2) + 'px'; var finalResultBig = ( (myWidth_big * 83.7 / 100) + title_height ) + 'px'; if(w_width > 767){ $('.item').css('height', finalResult); $('.item.big').css('height', finalResultBig); $('.item.long').css('height', finalResultBig); } else { $('.item.small').css('height', finalResult); $('.item.wide').css('height', half_finalResult); $('.item.long').css('height', twice_finalResult); $('.item.big').css('height', finalResult); } } adjustHeight();
Вот и все, ребята, не забудьте вызвать функцию adjustHeight(); не только на загрузку документа, но и на ресайз!
You must be logged in to post a comment.