Динамические колонки — jQuery
Тема умных колонок давно остро стоит в сфере интернет-разработок. Но для начала нужно разобраться, какой смысл вкладывается в словосочетание - "умные" или динамические колонки? Это колонки, которые умеют изменять свой размер (ширину) в зависимости от ширины экрана (области просмотра). То есть общая логика такая: если на экран помещается полных 5 колонок и остается пустое место справа, то эти колонки растягиваются таким образом, чтобы места справа не осталось. Если пользователь начинает сжимать окно браузера, то начинают сжиматься и колонки до тех пор, пока не достигнут минимальной ширины и тогда в одну линию будут стоять уже 4 колонки, которые займут все доступное пространство. Идея очень хорошая, но вот реализация подкачала. Даже FlexBox, на который были все надежды, не справляется полностью с этой задачей. Давайте разберемся, как же нам сделать динамические колонки с помощью jquery.
Для начала создадим html-структуру. Добавим несколько колонок, поместив в них любое содержимое. Количество колонок должно быть достаточным, чтобы занять больше 1 ряда. Все колонки должны быть внутри одного блока (columns-list). У меня структура колонки получилась вот такая:
<div class="column"> <div class="column-content"> Содержимое колонки </div> </div>
Теперь добавим немного стилей, чтобы все выглядело более-менее прилично:
body { background:#f5f5f5; } .columns-list:after { content:''; display:block; clear:both; } .column { width:250px; padding:30px; -moz-box-sizing:border-box; box-sizing:border-box; float:left; } .column-content { border:1px solid #c6c6c6; box-shadow:0 0 5px 0 #999; background:#fff; line-height:200px; text-align:center; }
А теперь самое интересное - скрипт, который будет выполнять всю работу за нас (не забудьте подключить свежую библиотеку jquery):
$(document).ready(function() { function columns() { var colParent = $('.columns-list') var colParentWidth = $(colParent).width(); var colNum = Math.floor(colParentWidth / 250); var colFixed = Math.floor(colParentWidth / colNum); if ( $(colParent).children('.column').length > colNum ) { $(colParent).children('.column').css({ 'width' : colFixed}); } } columns(); $(window).resize(function () { columns(); }); });
Вы могли обратить на цифру 250 в скрипте - это базовая ширина колонки (изменяется по вкусу). Вот и все. Теперь наши колонки будут подстраиваться под размер экрана. Поигравшись со стилями можно менять отступы между колонками (padding), цвета, тени и вообще все, что угодно.
Полный код страницы:
<!DOCTYPE html> <html> <head> <title>Динамические колонки</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <style> body { background:#f5f5f5; } .columns-list:after { content:''; display:block; clear:both; } .column { width:250px; padding:30px; -moz-box-sizing:border-box; box-sizing:border-box; float:left; } .column-content { border:1px solid #c6c6c6; box-shadow:0 0 5px 0 #999; background:#fff; line-height:200px; text-align:center; } </style> <script> $(document).ready(function() { function columns() { var colParent = $('.columns-list') var colParentWidth = $(colParent).width(); var colNum = Math.floor(colParentWidth / 250); var colFixed = Math.floor(colParentWidth / colNum); if ( $(colParent).children('.column').length > colNum ) { $(colParent).children('.column').css({ 'width' : colFixed}); } } columns(); $(window).resize(function () { columns(); }); }); </script> </head> <body> <div class="columns-list"> <div class="column"> <div class="column-content"> Содержимое колонки </div> </div> <div class="column"> <div class="column-content"> Содержимое колонки </div> </div> <div class="column"> <div class="column-content"> Содержимое колонки </div> </div> <div class="column"> <div class="column-content"> Содержимое колонки </div> </div> <div class="column"> <div class="column-content"> Содержимое колонки </div> </div> <div class="column"> <div class="column-content"> Содержимое колонки </div> </div> <div class="column"> <div class="column-content"> Содержимое колонки </div> </div> <div class="column"> <div class="column-content"> Содержимое колонки </div> </div> <div class="column"> <div class="column-content"> Содержимое колонки </div> </div> <div class="column"> <div class="column-content"> Содержимое колонки </div> </div> <div class="column"> <div class="column-content"> Содержимое колонки </div> </div> <div class="column"> <div class="column-content"> Содержимое колонки </div> </div> <div class="column"> <div class="column-content"> Содержимое колонки </div> </div> </div> </body> </html>
Вместо ширины хочу отступ!
Для тех, кто хочет увеличивать расстояние между колонками вместо их размера, придется чуть модернизировать скрипт и немного переписать стили. Начнем со стилей:
body { background:#f5f5f5; } .columns-list:after { content:''; display:block; clear:both; } .column { width:250px; margin-right:30px; padding-bottom:30px; float:left; } .column-content { border:1px solid #c6c6c6; box-shadow:0 0 5px 0 #999; background:#fff; line-height:200px; text-align:center; }
А теперь скрипт (структура остается неизменной):
$(document).ready(function() { function columns() { var colParent = $('.columns-list'); var minMargin = 30; //минимальный отступ справа var colWidth = $(colParent).children('.column').width(); var colParentWidth = $(colParent).width(); var colNum = Math.floor(colParentWidth / (colWidth + minMargin)); if ( colParent.children('.column').length < colNum ) { $(colParent).children('.column').css({ 'margin-right' : minMargin, 'float' : 'left'}); return; } if (colNum == 1) { colNum = Math.floor((colParentWidth - minMargin) / colWidth); } var allMargin = colParentWidth - (colNum * colWidth); var colMargin = (allMargin / (colNum-1)); $(colParent).children('.column').css({ 'margin-right' : colMargin, 'float' : 'left'}); $(colParent).children(".column:nth-of-type(" + colNum +"n)").css({ 'margin-right' : '0'}); if (colNum == 1) { $(colParent).children('.column').css({ 'float' : 'none', 'margin' : '0 auto'}); } } columns(); $(window).resize(function () { columns(); }); });
Вот и все:) Полный код страница и демо:
<!DOCTYPE html> <html> <head> <title>Динамические колонки</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <style> body { background:#f5f5f5; } .columns-list:after { content:''; display:block; clear:both; } .column { width:250px; margin-right:30px; padding-bottom:30px; float:left; } .column-content { border:1px solid #c6c6c6; box-shadow:0 0 5px 0 #999; background:#fff; line-height:200px; text-align:center; } </style> <script> $(document).ready(function() { function columns() { var colParent = $('.columns-list'); var minMargin = 30; //минимальный отступ справа var colWidth = $(colParent).children('.column').width(); var colParentWidth = $(colParent).width(); var colNum = Math.floor(colParentWidth / (colWidth + minMargin)); if ( colParent.children('.column').length < colNum ) { $(colParent).children('.column').css({ 'margin-right' : minMargin, 'float' : 'left'}); return; } if (colNum == 1) { colNum = Math.floor((colParentWidth - minMargin) / colWidth); } var allMargin = colParentWidth - (colNum * colWidth); var colMargin = (allMargin / (colNum-1)); $(colParent).children('.column').css({ 'margin-right' : colMargin, 'float' : 'left'}); $(colParent).children(".column:nth-of-type(" + colNum +"n)").css({ 'margin-right' : '0'}); if (colNum == 1) { $(colParent).children('.column').css({ 'float' : 'none', 'margin' : '0 auto'}); } } columns(); $(window).resize(function () { columns(); }); }); </script> </head> <body> <div class="columns-list"> <div class="column"> <div class="column-content"> Содержимое колонки </div> </div> <div class="column"> <div class="column-content"> Содержимое колонки </div> </div> <div class="column"> <div class="column-content"> Содержимое колонки </div> </div> <div class="column"> <div class="column-content"> Содержимое колонки </div> </div> <div class="column"> <div class="column-content"> Содержимое колонки </div> </div> <div class="column"> <div class="column-content"> Содержимое колонки </div> </div> <div class="column"> <div class="column-content"> Содержимое колонки </div> </div> <div class="column"> <div class="column-content"> Содержимое колонки </div> </div> <div class="column"> <div class="column-content"> Содержимое колонки </div> </div> <div class="column"> <div class="column-content"> Содержимое колонки </div> </div> <div class="column"> <div class="column-content"> Содержимое колонки </div> </div> <div class="column"> <div class="column-content"> Содержимое колонки </div> </div> <div class="column"> <div class="column-content"> Содержимое колонки </div> </div> </div> </body> </html>