Умные динамические колонки с применением CSS и jQuery

Существует два типа колонок, используемых на веб-сайтах: фиксированной ширины и тянущиеся в ширину в зависимости от размера экрана (их еще называют «резиновыми»).

Недостатком фиксированных колонок при их использовании в «резиновом» блоке является то, что может появляться лишнее незаполненное пространство (при определенной ширине блока), поскольку его ширина меньше ширины столбца:

Фиксированные колонки

«Резиновые» же колонки не оставляют избыточных пустого пространства и прекрасно вписываются в родительский блок. Однако их недостаток заключается в том, что в строку мы можем поместить только фиксированное число столбцов:

''Резиновые'' колонки

Решение

Суть решения заключается в том, чтобы взять преимущества обоих ситуаций и объединить их в одно. Что мы должны получить в итоге:

  • Блок должен вмещать столько фиксированных колонок, сколько позволяет размер экрана.
  • Если в блоке образовалось лишнее свободное пространство, равномерно распределить его на каждую из колонок, чтобы заполнилось все свободное пространство в блоке.
  • При растяжении колонок ориентироваться на их базовую ширину и растягивать их до той поры, пока потенциальное свободное пространство не вместит очередную колонку.

Умные колонки

Посмотреть пример — Умные динамические колонки.

HTML

Начнем с создания неупорядоченного списка, пункты которого будут вести себя как колонки.

<ul class="column">
	<!-- повторяющийся элемент списка -->
	<li>
		<div class="block">
		<!-- контент -->
		</div>
	</li>
	<!-- конец повторяющегося элемента -->
</ul>

CSS

ul.column{
	width: 100%;
	padding: 0;
	margin: 10px 0;
	list-style: none;
}
ul.column li {
	float: left;
	width: 200px; /* ширина колонки по умолчанию */
	padding: 0;
	margin: 5px 0;
	display: inline;
}
.block {
	height: 355px;
	font-size: 1em;
	margin-right: 10px; /* отступ между колонками */
	padding: 20px;
	background: #e3e1d5;
}
.block h2 {
	font-size: 1.8em;
}
.block img {
	/* параметры для изображений с меняющимися размерами и бордюром */
	width: 89%; /* убираем 1% от ширины, чтобы предотвратить баг в IE6 */
	padding: 5%;
	background:#fff;
	margin: 0 auto;
	display: block;
	-ms-interpolation-mode: bicubic; /* предотвращение пикселизации изображений в IE 6/7 */
}

jQuery


function smartColumns() { //функция, подсчитывающая ширину колонок

	//сброс ширины строки до 100% после изменения размера экрана
	$("ul.column").css({ 'width' : "100%"});

	var colWrap = $("ul.column").width(); //определяем ширину строки
	var colNum = Math.floor(colWrap / 200); //определяем, сколько столбцов в 200px вместится в строку и округляем число до целого
	var colFixed = Math.floor(colWrap / colNum); //ширину строки делим на количество столбцов, округляем до целого числа, в результате получаем точную скорректированную ширину колонки

	$("ul.column").css({ 'width' : colWrap}); //ставим точную ширину строки в пикселях вместо использования % - это предотвратит возможные баги в разных браузерах при различных разрешениях экрана
	$("ul.column li").css({ 'width' : colFixed}); //ставим точную ширину измененным столбцам

}

smartColumns(); //запускаем функцию после загрузки страницы

$(window).resize(function () { //запускаем функцию после каждого изменения размера экрана
	smartColumns();
});

Ссылки по теме

P.S. Довольно интересная штука. При удобном случае нужно будет обязательно воспользоваться.

Комментарии (55)
  1. 1

    Дмитрий, спасибо большое за инфу. Создал колонки с помощью вашего способа и скинул файлы html, css и js себе в папку-«заначку» . У меня уже коллекция заготовок с различными способами реализации «резины». Если вас заинтересует, то есть еще один интересный способ реализации вашего примера html. Фактически берем за основу вашу разметку. Только в таблице стилей для списка (ul и li) прописываем свойства таблицы. Конкретно:

    ul { display: table-row; width: указываем нужную ширину;}

    ul li {display: table-cell;}

    .block {display: table-cell;
    width: указываем ширину ul. Благодаря этому все блоки равномерно распределяются по горизонтали;}

    Для родителя ul.column ( у вас его нет) прописываем max-width, min-width и нужные величины border-spacing (задает отступы между ячейками-колонками сверху и снизу.

    Это все. Прописал только те функции, на которых нужно акцентировать внимание. Все эти background и прочее указывается индивидуально.

    Преимущества этого способа:
    1) одинаковая высота и ширина всех колонок;
    2)в каждую колонку-ячейку можно ввести любой объем контента. Если это будет текст (разный объем в разных колонках), то при сужении экрана браузера колонки будут синхронно менять свой размер, подстраиваясь под самую большую;
    3) при сужении экрана текст, объем которого будет превышать размеры колонок, будет давить на нижнюю границу колонки, автоматически растягивая ее вниз.

    Этого невозможно добиться, если указать высоту колонки или ее родителя. У вас указана высота .block {height: 355px;}, поэтому при сужении экрана избыточный текст «проваливается» через нижние границы колонок. В моем случае колонки подчиняются закону таблицы и этого не происходит.

    Если данный метод пригодится вам или кому-то из посетителей вашего бога, то буду только рад…

  2. 2
    Дмитрий

    А как разбить на колонки простой текст (с определённым кол-вом строк)? Это вообще возможно?