Динамические колонки — jQuery

Динамические колонки — 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>
 

26.03.17
Для просмотра сайта обновите браузер.