Умные динамические колонки с применением 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();
});
Ссылки по теме
- “Адаптивные блоки” от akella (там же ряд других примеров подобной техники)
P.S. Довольно интересная штука. При удобном случае нужно будет обязательно воспользоваться.
Комментарии (54)
Может, я чего проглядел, но ИМХО, вместо jQuery можно было бы обойтись ведением min-width.
А шЫштой осел — да забудем уже про него:-)
А внимательнее пост прочитать?
Речь-то совсем о другом :)
Да, вроде, мысль понятна.
Покажите тогда на примере, как то же самое будет решено на чистом CSS.
Посидел, покрутил, и понял, что при расширении контентной части без скриптов никуда.
C некоторыми оговорками (последняя строка ячеек всегда будет по горизонтальному центру, сколько бы их в строке не было) – можно:
Для
ul class="column"
text-align:center
, для списков – display:inline-block; без обтекания + хаки для IE и младших лисиц.
Дима, кинул тебе на мыло, свою новую разработку,
к ней поможешь свое хозяйство прикрутить?
Не понимаю, каким образом может пригодиться в трехколоночком макете техника динамических колонок. Именно в таком макете достаточно указания %-й ширины, ведь количечество столбцов в строку всегда будет одинаковое.
А изменение размера шрифта к такому макету можно прикрутить.
Нет, конечно, переноса колонок делать не надо :)
Но динамика измения ширины колонок и одновременно размера шрифта нужна.
Важны пропорции не только в ширине колонок , но и в расстоянии между ними.
Приблизительно так, как в посланном тебе на мыло, моем макете,
не важно, что там фиксированная колонка, в принципе все может прокручиваться.
Причем, вместе с min/max-width всему макету.
Пусть ширина колонок в %.
Как пропорциональное именине размера шрифта к этому привязать?
Спасибо, Дима за помощь.
Все получил.
Играюсь :)
Если будут вопросы то задам, ты же автор данной фишки.
Пиши статью, от себя обязательно линк дам,
думаю многим пригодится.
Пожалуйста. Статью напишу.
К тому, что ты сделал для меня, по моей просьбе,
надо бы добавить из оригинального примера возможность масштабирования картинок, тогда полный фен-шуй будет :)
И, как писал, рассмотреть все на конкретном примере – стандартной трех колоночной разметке, во всех подробностях.
Может даже и не на одну статью потянет :)
В примере из статьи масштабирование изображений работает на голом CSS, так что скриптов для этого не нужно.
FF3 Win7RC1
Скрипт, боюсь, не выполняет свою функцию.
Opera10 Wnin7RC1 – нормально.
Прошу прощения – деза)
В примере не выполняется, но к кастому моему вполне прикрутилось. о_О
Мистика.
Спасибо, очень интересный пример! Интересно и увлекательно разобран по полочкам. Что-то в этом роде я придумал на div, а на списках не догадался. Не додумался и картинкам назначать ширину width: 89% – клёво!
Но вот вопрос: я решил этот пример использовать для фотоальбома, в котором фоты наложены “внавал”, резиново. Но к каждой фотке хотелось бы вставить комменты.
Если размеры и ориентация, а также объем комментов строго одинаков, то все идет пучком: при изменении разрешения экрана, размера окна браузера все резиновое и “резинит” отлично.
Но в реале фотки имеют разный размер и ориентацию, разный объем текста и колонки получаются разной высоты. И вот тут получается неприятный фикус-покус: маленькие колонки цепляются за высокий правый край бОльших колонок, находящихся раньше – получаются зияющие пустоты. Как их избежать – ума не приложу.
Может честной изобретательный и остроумный народ подскажет что-то оч.ценное? Или такая идея неважнецкая?
а как закинуть шаблон в joomla?
А почему он не воспринимает русский шрифт?Как актуализировать русский шрифт ?
Видимо, сохраняете в неправильной кодировке.
Подскажите пожалуйста в какую кодировку написать и где, наверно В CSS. Очень надо
Во-первых, кодировка указывается в текстовом редакторе, в котором сохраняется файл.
Во-вторых, она указывается в HTML-коде в теге
<meta>
, например:Здесь
utf-8
– это название кодировки. Она должно быть одинаковой в обоих случаях. Можно также использовать кодировкуwindows-1252
.Спасибо Dimox, буду пробовать)
не получается( Dimox скажи пожалуйста как в кодировке демо сайта сделать так чтобы читался русский шрифт. Я поменял то, что ты говорил и в настройках блокнота по умолчанию задал данную кодировку (UTF-8), но ничего не помагает((
Замени
iso-8859-1
наutf-8
и сохрани файл вutf-8
.Сработало!Большое спасибо Dimox. Очень помог частенько буду посещать этот сайт!
Подскажите куда вставлять jQuery Сайт будет под Joomla Спасибо!
Посмотрите, как сделано в примере, и сделайте по аналогии.
Каким образом в блоки картинки вставить? Спасибо!
как можно распределить свободное пространство между блоками!? Спасибо!
Вопрос непонятен.
у вас свободное пространство распределяется в блоки тем самым они растягиваються одинаково и заполняют всю страницу по ширене с фиксированными отступами между блоками.
А как сделать так чтобы свободное пространство распределялось между блоками а сами блоки оставались с теми же размерами?
Сходу я могу лишь сказать, что самое просто – сделать это таблицей. Вот пример:
а как сделать если сделано не в таблице каждый блок прописан в div для резиновой странички? Спасибо!
Не знаю.
Добрый день,
хорошая тема.
1. В браузерах Opera и Firefox пример работает как задумано.
2. В браузере IE приведенный пример не работает:
– ширина колонок (div-ов) не изменяется при изменении ширины окна;
– колонки (div-ы) ведут себя как div-ы со стилем float и поэтому справа всегда какое-то место остается. Div-ы не заполняют все пространство.
– при уменьшении экрана до размера, на котором помещается 4 div-а IE входит в ступор – зацикливается. После этого его остается только закрыть.
3. Напишите пожалуйста, не встречался ли в Вашей практике плагин или пример работающий на трех браузерах.
Галина
PS Ссылки на пример, переадресовываются и пример получить нельзя.
У меня работает во всех браузерах, в том числе и в IE, начиная с 6-й версии. Вот рабочий пример – http://fiddle.jshell.net/Dimox/U2A3j/1/show/light/
Этот пример (у меня IE вер.9) работает на широком экране 1800 и при уменьшении окна до 5-6 колонок. Но нельзя уменьшить окно до одной колонки (до одного div-а).
Нельзя преодолеть рубеж 4-5 колонок (div-ов) – IE зацикливается.
В других браузерах этого не происходит.
Попробуйте пожалуйста уменьшить окно до одной колонки, интересно что у Вас получится?
Я выводила ширину окна в Вашем примере ив своем (с другими размерами div-а) и обнаружила, что Ваш и мрй пример зацикливают IE ровно при ширине окна 950px.
Вам это что-нибудь говорит?
Спасибо,
Галина
У меня без проблем уменьшается до одной колонки.
У меня все заработало после удаления, баров-надстроек в IE.
Спасибо
Галина
Замечательно.
А если задача немного иная? То есть, блоки расположены не слева-направо, а сверху-вниз, если объема хватает они стоят по одной вниз, если нет, выкидываются поочередно во второй вертикальный ряд.
Дмитрий, спасибо большое за инфу. Создал колонки с помощью вашего способа и скинул файлы 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;}, поэтому при сужении экрана избыточный текст “проваливается” через нижние границы колонок. В моем случае колонки подчиняются закону таблицы и этого не происходит.
Если данный метод пригодится вам или кому-то из посетителей вашего бога, то буду только рад…
А как разбить на колонки простой текст (с определённым кол-вом строк)? Это вообще возможно?