MAXSITE.ORGКак сделать сайт своими руками

Адаптивная сетка. Верстка по-новому

02-10-2013Время чтения ~ 4 мин.CSS, HTML, LESS, SASS 43618

Адаптивность на сайтах на сегодняшний момент, как правило, решается единственным способом:

  • выстраиваем колонки для обычных разрешений (например более 960px);
  • для средних разрешений колонки становятся «резиновыми»;
  • для малых экранов сбрасываем float, после чего все ячейки следуют одна под другой.

Посмотрите на демо-примере, где используется именно такой подход. Изменяя ширину браузера можно увидеть как меняются ячейки.

Способ достаточно простой, поэтому получил широкое распространение. Вместе с тем, очевидно, что в нем существуют большие ограничения, связанные с тем, что модель поведения блоков сетки фиксирована и не предполагает более сложной организации, например для средних экранов сделать не только резиновую ширину, но и расположить ячейки попарно «1-2» и «3-4».

После выхода Bootstrap 3, вебмастера столкнулись с новым методом построения сетки (grid). Именно он вызвал массу непонимания, поскольку сломал «старый» вариант без намёка на совместимость.

Впрочем, кому принадлежит авторство этого метода судить сложно: например в UIKit (отличный css-фреймворк) он появился несколько раньше.

Для затравки посмотрите ещё один пример, где собраны 5 примеров с разным поведением сеток. Заметьте, что для обычных мониторов (более 960px) сетки абсолютно идентичные.

HTML-разметка

Разметка такой сетки ничем не отличается от традиционного варианта.

<div class="row">
	<div class="col w1-4">1</div>
	<div class="col w1-4">2</div>
	<div class="col w1-4">3</div>
	<div class="col w1-4">4</div>
</div>

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

  • .row — контейнер. Ему нужно прописать стили .clearfix, поскольку внутренние блоки будут плавающими.
  • .col — общий класс для одной ячейки. Здесь выставляем float: left и .box_sizing(border-box) (это упростит использование отступов и нужной ширины).
  • w1-4 — класс, где указывается ширина ячейки width: 25%. Удобно считать не в процентах, а в колонках. В данном случае w1-4 говорит, что это 1/4 ширины (1 колонка из 4-х).

Стили определяем так:

.row .col {
	&.w1-1 { width: 100%; float: none;}
	&.w1-2 { width: 50%; }
	&.w1-3 { width: 33.333%; }
	&.w1-4 { width: 25%; }
}
В примерах CSS я использую LESS.

В css-фреймворках используются разные варианты построения сетки. Например отступы могут задаваться как фиксированными, так и в процентах. От этого будут зависеть и стили, определяющие ширину ячейки. Скажем ширина может быть уменьшена на размер отступа. В своих примерах я указываю «чистую» ширину.

Типовое поведение сетки

Классы подобные .col.w1-4 определяют типовое поведение сетки. То есть то, как будет выглядеть сетка без условий в @media.

Этот момент важен, поскольку в разных фреймворках (и у разных вебмастеров) за основу берется разная ширина экрана. Я, например, предпочитаю за основу брать именно десктопы с разрешением 960-1140px, а все что ниже — описывать через @media. В том же Bootstrap'е используется mobile first, где основа — малые разрешения мобильников, а для перехода к десктопу следует использовать @media-правила.

То есть класс .col.w1-4 будет работать только для «типового» размера, а для того, чтобы использовать другую ширину экрана необходима модификация стилей.

Принципиальное отличие нового подхода в том, что мы не переопределяем «типовой» класс ячейки, а используем новый, который срабатывает только в пределах своего @media-условия.

Классы для breakpoints

Предположим, что у нас есть блоки @media, где задаются условия:

// t — tablets 
@media (max-width: 768px) and (min-width: 480px)
 
// p — phones 
@media (max-width: 480px) 

Мы можем задать поведение для средних экранов (tablets) и малых (phones). Соответственно, в каждом из этих условий нужно сделать уникальные классы.

// t — tablets 
@media (max-width: 768px) and (min-width: 480px) {
	.row .col {
		&.w1-1-t { width: 100%; float: none;}
		&.w1-2-t { width: 50%; }
		&.w1-3-t { width: 33.333%; }
		&.w1-4-t { width: 25%; }
	}
}
 
// p — phones 
@media (max-width: 480px) {
	.row .col {
		&.w1-1-p { width: 100%; float: none;}
		&.w1-2-p { width: 50%; }
		&.w1-3-p { width: 33.333%; }
		&.w1-4-p { width: 25%; }
	}
}

Фактически это те же самые классы, только добавлены постфиксы «-t» и «-p». В Bootstrap'е используются префиксы «.col-xs-», «.col-sm-», «.col-md-», «.col-lg-». В UIKit — «.uk-width-medium-» и «.uk-width-large-». То есть именование классов может быть произвольным.

Исходя из этого, можно задать для каждой ячейки разную ширину с учетом ширины экрана (читай @media-правил).

<div class="row">
	<div class="col w1-4 w1-2-t w1-1-p">1</div>
	<div class="col w1-4 w1-2-t w1-1-p">2</div>
	<div class="col w1-4 w1-2-t w1-1-p">3</div>
	<div class="col w1-4 w1-2-t w1-1-p">4</div>
</div>

В этом примере на обычных экранах все ячейки займут по 1/4 ширины. Для tablets все ячейки займут по 1/2 ширины. Для малых экранов (phones) ячейки займут все 100% ширины.

Ещё варианты

Данный подход, когда css-класс определяется в пределах @media-условия, может быть использован для разных задач. Например в Semantic UI (один из лучших css-фреймворков), можно задать «tablet.only» или «mobile.only». Аналогично можно придумать «phone-hide» и «tablets-hide» — скрывать ячейку для разного вида устройств.

@media (max-width: 768px) and (min-width: 480px) {
	.col.tablets-hide {
		display: none;
	}
}	
 
@media (max-width: 480px) {
	.col.phone-hide {
		display: none;
	}
}

И HTML-разметка:

<div class="row">
	<div class="col w1-4 w1-2-t w1-1-p">1</div>
	<div class="col w1-4 w1-2-t phone-hide">2</div>
	<div class="col w1-4 w1-1-p tablets-hide">3</div>
	<div class="col w1-4 w1-1-t w1-1-p">4</div>
</div>

В этом примере скрываем 2-ю ячейку для мобильников, и 3-ю ячейку для средних экранов.

Как видите, управлять можно не только шириной ячеек, но и их видимостью.

Использование LESS

Желающие поэкспериментировать, могут скачать grid.less, где рассписаны классы для 12 колонок.

Похожие записи
Сайт использует cookie
Для улучшения работы сайта собирается анонимная статистика через Google Analytics. Разрешить использование аналитических cookie?