Простая отзывчивая сетка, даже лучше с Sass
() translation by (you can also view the original English article)
В этом уроке, мы построим простую, отзывчивую сетку, используя CSS. Так как, мы знакомы с тем, как это работает, мы улучшим её с Sass, изучив некоторые основные функции Sass по ходу.
Начнем с CSS
Давайте быстро рассмотрим, как будет выглядеть наша сетка. Есть более умные способы построения сеток, которые менее скучны в разметке, но эта сетка дает нам отличную возможность практиковать простые, но полезные методы Sass. Она использует один обертывающий элемент, затем другие элементы внутри него, которые действуют как строки, а затем больше элементов внутри них, которые работают как наши столбцы.



Grid.css
Для начала, все, что нам нужно, это CSS-файл, поэтому откройте новый документ в редакторе кода и назовите его «grid.css».
Первое, что мы собираемся добавить, это глобальный сброс правила box-sizing. Это позволит убедиться, что padding, применяемый к нашим элементам, добавляется с учетом их рассчитанных размеров, что дает нам гораздо больше свободы для определения ширины столбцов.
1 |
*,
|
2 |
*:after, |
3 |
*:before { |
4 |
margin: 0; |
5 |
padding: 0; |
6 |
-webkit-box-sizing: border-box; |
7 |
-moz-box-sizing: border-box; |
8 |
box-sizing: border-box; |
9 |
}
|
Затем, мы добавим правило, чтобы убедиться, что любые изображения будут обтекаться текстом только сверху и снизу.
1 |
img { |
2 |
width: auto; |
3 |
max-width: 100%; |
4 |
height: auto !important; |
5 |
}
|
Обёртка
Теперь правила, чтобы убедиться, что наш оберточный элемент «сам по себе».
1 |
.wrapper { |
2 |
width: 100%; |
3 |
margin: 0 auto; |
4 |
}
|
Примечание: Имейте в виду, что мы верстаем в первую очередь под мобильные телефоны. Наш контейнер начинается со 100% ширины области просмотра, но мы изменим это для больших экранов.
Строки
Нам нужны элементы строк, только для того, чтобы поместить в них столбцы и убедиться, чтобы группы столбцов правильно отделялись друг от друга. Давайте добавим некоторые общие правила .clearfix
к нашим элементам обёртки и строк.
1 |
.wrapper:after, |
2 |
.row:after { |
3 |
content: ""; |
4 |
display: table; |
5 |
clear: both; |
6 |
}
|
Примечание: мы не должны называть эти элементы .wrapper
, .row
и .column
, мы можем быть гораздо более креативными. Эти имена просто более понятные для целей этого урока.
Столбцы
У нас будет серия классов столбцов, в зависимости от размера каждого из них (например, .column-1
и .column-6
. Давайте использовать селектор атрибутов для выбора и оформления всех их за один раз.
1 |
[class*='column-'] { |
2 |
float: left; |
3 |
padding: 1em; |
4 |
width: 100%; |
5 |
min-height: 1px; |
6 |
}
|
Этот селектор гласит: берём любой элемент, чей класс содержит строку column-
и применим следующий стиль. Следовательно все наши элементы столбцов будут иметь float влево, padding 1em
(это и образует наш желоб и некоторое вертикальное пространство) и заполнит 100% ширины области просмотра (опять же, сперва мобильные телефоны). Наконец, min-height: 1px
гарантирует, что столбец отображается правильно, даже если в нём нет содержимого.
Верите или нет, теперь у нас есть сетка! Следующая разметка, это все, что нам нужно.
1 |
<section class="wrapper"> |
2 |
|
3 |
<div class="row"> |
4 |
|
5 |
<div class="column-3"></div> |
6 |
<div class="column-3"></div> |
7 |
<div class="column-6"></div> |
8 |
|
9 |
</div>
|
10 |
|
11 |
</section>
|
Мы можем использовать любую комбинацию столбцов в строках, взгляните на демо и вы увидите, что у вас должно быть на данный момент.



Делаем отзывчивым
Вот так мы заботимся о том, как это выглядит на мобильном, теперь, давайте добавим медиа-запрос, чтобы получить другой макет для экранов покрупнее. Вам нужно будет определить точки разделения для вашей сетки, но мы будем использовать одну произвольную точку в 30em
.
1 |
@media only screen and (min-width: 30em) { |
2 |
|
3 |
}
|
Любые стили, которые мы вложим в этот медиа запрос, будут работать столько для экранов шириной 30em и шире. Мы будем использовать эту точку, для разбивки наших столбцов, на правильную ширину.
% ширины
Какой длины должен быть каждый столбец? Это зависит от того, как много у нас столбцов. В этом примере, я собираюсь работать с двенадцатью столбцами, таким образом каждый из них, должен быть шириной одну двенадцатую (1/12) от обёртки. Для столбца, который охватывает две ширины, это будет две двенадцатых и т.д. Вот что это нам даёт:
1 |
@media only screen and (min-width: 30em) { |
2 |
|
3 |
.wrapper { |
4 |
width: 95%; |
5 |
max-width: 65em; |
6 |
}
|
7 |
|
8 |
.column-1 { |
9 |
width: 8.33333%; |
10 |
}
|
11 |
|
12 |
.column-2 { |
13 |
width: 16.66667%; |
14 |
}
|
15 |
|
16 |
.column-3 { |
17 |
width: 25%; |
18 |
}
|
19 |
|
20 |
.column-4 { |
21 |
width: 33.33333%; |
22 |
}
|
23 |
|
24 |
.column-5 { |
25 |
width: 41.66667%; |
26 |
}
|
27 |
|
28 |
.column-6 { |
29 |
width: 50%; |
30 |
}
|
31 |
|
32 |
.column-7 { |
33 |
width: 58.33333%; |
34 |
}
|
35 |
|
36 |
.column-8 { |
37 |
width: 66.66667%; |
38 |
}
|
39 |
|
40 |
.column-9 { |
41 |
width: 75%; |
42 |
}
|
43 |
|
44 |
.column-10 { |
45 |
width: 83.33333%; |
46 |
}
|
47 |
|
48 |
.column-11 { |
49 |
width: 91.66667%; |
50 |
}
|
51 |
|
52 |
.column-12 { |
53 |
width: 100%; |
54 |
}
|
55 |
|
56 |
}
|
Мы также видите, что мы сделали элемент .wrapper
меньше, чем вся ширина экрана и задали ему max-width
. Посмотрите, что мы сделали с нашей сеткой.



Подчищаем с помощью Sass
Наша CSS-сетка работает, но что произойдет, если мы на самом деле хотели шестнадцать столбцов для нашей сетки? Или даже больше? Нам нужно будет каждый раз пересчитывать каждый столбец и вручную вводить это в наш CSS-файл. Не говоря уже о том, что наш CSS будет становиться все длиннее и длиннее, и им будет сложнее управлять. К счастью, Sass (или любой другой препроцессор) может нам помочь.
Настройка Sass
Этот урок не о настройке Sass, подразумевается, что вы уже знаете как это делать. Если это не ваш случай и вам нужна с этим помощь, взгляните на Mastering Sass: Lesson 1 или SASS and Compass for Web Designers: Introduction.
Как только вы настроите проект Sass, переходите к следующему шагу.
Определение переменных
Sass поможет нам очистить наш CSS разными способами, но первое, что мы можем сделать, это извлечь любые полезные значения и сохранить их в переменных. Начинаем с нового частичного файла Sass «_variables.scss»; который не будет скомпилирован непосредственно в CSS, но мы будем ссылаться на другие наши файлы.
1 |
// grid variables |
2 |
$grid-columns: 12; |
3 |
$grid-max-width: 65em; |
4 |
|
5 |
|
6 |
// breakpoints |
7 |
$breakpoint-small: "only screen and (min-width: 20em)"; |
8 |
$breakpoint-medium: "only screen and (min-width: 30em)"; |
Эти переменные дают нам количество столбцов, с которыми мы хотим работать; на данный момент — 12, но их можно легко изменить на 16, возможно и 32 (что бы вы ни захотели). Мы также сохранили некоторые точки разделения в переменных как строки, хотя в настоящий момент мы используем только одну.
Мы будем использовать их в ближайшее время, но сначала мы настроим некоторое смешивание — mixins.
Mixins
Sass mixins — это фрагменты кода, которые мы можем определить один раз, а затем повторно использовать в другом месте в нашем проекте. Например, мы могли бы взять самый первый набор правил, где мы устанавливаем border-box
и извлекаем большую часть этого в mixin. Начнем с:
1 |
*,
|
2 |
*:after, |
3 |
*:before { |
4 |
margin: 0; |
5 |
padding: 0; |
6 |
-webkit-box-sizing: border-box; |
7 |
-moz-box-sizing: border-box; |
8 |
box-sizing: border-box; |
9 |
}
|
Затем мы помещаем часть, которую мы можем повторно использовать, определяя mixin, который я назвал «border-box» следующим образом:
1 |
@mixin border-box { |
2 |
-webkit-box-sizing: border-box; |
3 |
-moz-box-sizing: border-box; |
4 |
box-sizing: border-box; |
5 |
}
|
Затем мы @import
наши переменные и mixins в наш главный "grid.scss", и используем mixin через @include
.
1 |
@import "variables"; |
2 |
@import "mixins"; |
3 |
|
4 |
*,
|
5 |
*:after, |
6 |
*:before { |
7 |
margin: 0; |
8 |
padding: 0; |
9 |
|
10 |
@include border-box; |
11 |
|
12 |
}
|
@extend Clearfix
Мы можем сделать аналогичную вещь с правилами clearfix, как предложил Себастьян Экстрём. В этом случае мы берём правила clearfix, рекомендованные Николасом Галлахером, и добавляем их в наш файл mixin с селектором-заполнителем (%
):
1 |
%clearfix { |
2 |
*zoom: 1; |
3 |
&:before,
|
4 |
&:after { |
5 |
content: " "; |
6 |
display: table; |
7 |
}
|
8 |
&:after { |
9 |
clear: both; |
10 |
}
|
11 |
}
|
Селектор-заполнитель позволяет нам определять целые куски стиля, которые выводятся только тогда, когда мы дополняем их в другом месте, например:
1 |
.wrapper, |
2 |
.row { |
3 |
@extend %clearfix; |
4 |
}
|
После компиляции эти аккуратные несколько строк Sass выглядят так:
1 |
.wrapper, |
2 |
.row { |
3 |
*zoom: 1; |
4 |
}
|
5 |
.wrapper:before, |
6 |
.row:before, |
7 |
.wrapper:after, |
8 |
.row:after { |
9 |
content: " "; |
10 |
display: table; |
11 |
}
|
12 |
.wrapper:after, |
13 |
.row:after { |
14 |
clear: both; |
15 |
}
|
Использование наших переменных
Давайте используем некоторые из тех переменных, которые мы установили, давайте? Для начала мы можем поменять значение max-width
для обёртки. Это:
1 |
.wrapper { |
2 |
width: 95%; |
3 |
max-width: 65em; |
4 |
}
|
становится этим:
1 |
.wrapper { |
2 |
width: 95%; |
3 |
max-width: $grid-max-width; |
4 |
}
|
Теперь давайте сделаем то же самое с нашим медиа-запросом. Это:
1 |
@media only screen and (min-width: 30em) { |
будет улучшено нашей переменной $breakpoint-medium
:
1 |
@media #{$breakpoint-medium} { |
Примечание: вы увидите, что мы завернули нашу переменную в #{}
. Это называется интерполяцией. Обычно это делается, если нам нужно вывести переменную в другую, но это необходимо в данном случае, потому что компилятор Sass отключает медиа-запросы, если после @media
напрямую не следуют скобки ()
. Вы можете больше узнать об этом в All You Ever Need to Know About Sass Interpolation от Hugo Giraudel.
Чтобы использовать нашу конечную переменную $grid‑columns
, нам нужно использовать ещë несколько функциональных возможностей Sass — циклы.
Циклы в Sass
Наши определения ширины столбцов абсолютно одинаковы, кроме фактических значений. Будет намного более лучше, если мы зададим определение столбца, для стольких столбцов, сколько нам нужно, изменяя значения каждый раз. Для этого мы можем использовать цикл Sass @for
, который выглядит так:
1 |
@for $i from 1 through 12 { |
2 |
// looped content |
3 |
}
|
Это сделает свыше 12 повторов и, каждый раз, значение $i
будет отражаться в этом цикле. Мы можем вывести $i
вот так:
1 |
@for $i from 1 through 12 { |
2 |
|
3 |
.column-#{$i} { |
4 |
|
5 |
}
|
6 |
|
7 |
}
|
И снова, вы заметите, что мы используем #{}
вокруг $i
, чтобы вывести значение как строку, которую мы добавляем в селектор .column-
. При компилировании это даст нам следующее:
1 |
.column-1 { |
2 |
|
3 |
}
|
4 |
|
5 |
.column-2 { |
6 |
|
7 |
}
|
8 |
|
9 |
.column-3 { |
10 |
|
11 |
}
|
12 |
|
13 |
.column-4 { |
14 |
|
15 |
}
|
16 |
|
17 |
.column-5 { |
18 |
|
19 |
}
|
20 |
|
21 |
.column-6 { |
22 |
|
23 |
}
|
24 |
|
25 |
.column-7 { |
26 |
|
27 |
}
|
28 |
|
29 |
.column-8 { |
30 |
|
31 |
}
|
32 |
|
33 |
.column-9 { |
34 |
|
35 |
}
|
36 |
|
37 |
.column-10 { |
38 |
|
39 |
}
|
40 |
|
41 |
.column-11 { |
42 |
|
43 |
}
|
44 |
|
45 |
.column-12 { |
46 |
|
47 |
}
|
Блестяще! Давайте теперь используем некоторые вычисления для вывода правильных стилей в этих селекторах.
Операторы Sass
Пока все хорошо, но теперь нам нужно вывести что-то вроде следующего для каждого селектора:
1 |
.column-5 { |
2 |
width: 41.66667%; |
3 |
}
|
Эта ширина столбца вычисляется как 100%, поделённое на общее количество столбцов, умноженное на номер столбца. В этом случае 100% / 12 * 5 = 41.66667%.
Поэтому мы должны применять вычисления, переключая соответствующие значения для переменных.
1 |
@for $i from 1 through 12 { |
2 |
|
3 |
.column-#{$i} { |
4 |
width: 100% / 12 * $i; |
5 |
}
|
6 |
|
7 |
}
|
Sass сейчас выполняет вычисления для нас, давая нам следующее:
1 |
.column-1 { |
2 |
width: 8.33333%; |
3 |
}
|
4 |
|
5 |
.column-2 { |
6 |
width: 16.66667%; |
7 |
}
|
8 |
|
9 |
.column-3 { |
10 |
width: 25%; |
11 |
}
|
12 |
|
13 |
.column-4 { |
14 |
width: 33.33333%; |
15 |
}
|
16 |
|
17 |
.column-5 { |
18 |
width: 41.66667%; |
19 |
}
|
20 |
|
21 |
.column-6 { |
22 |
width: 50%; |
23 |
}
|
24 |
|
25 |
.column-7 { |
26 |
width: 58.33333%; |
27 |
}
|
28 |
|
29 |
.column-8 { |
30 |
width: 66.66667%; |
31 |
}
|
32 |
|
33 |
.column-9 { |
34 |
width: 75%; |
35 |
}
|
36 |
|
37 |
.column-10 { |
38 |
width: 83.33333%; |
39 |
}
|
40 |
|
41 |
.column-11 { |
42 |
width: 91.66667%; |
43 |
}
|
44 |
|
45 |
.column-12 { |
46 |
width: 100%; |
47 |
}
|
В качестве момента зачистки, мы можем использовать переменную $grid-columns
вместо значения 12
:
1 |
@for $i from 1 through $grid-columns { |
2 |
|
3 |
.column-#{$i} { |
4 |
width: 100% / $grid-columns * $i; |
5 |
}
|
6 |
|
7 |
}
|
Теперь, если мы хотим изменить количество столбцов, мы просто изменим значение переменной, а вычисления будут выполнены для нас! Например, изменение $grid-columns
на 4
даст нам следующий CSS:
1 |
@media only screen and (min-width: 30em) { |
2 |
.wrapper { |
3 |
width: 95%; |
4 |
max-width: 65em; } |
5 |
|
6 |
.column-1 { |
7 |
width: 25%; } |
8 |
|
9 |
.column-2 { |
10 |
width: 50%; } |
11 |
|
12 |
.column-3 { |
13 |
width: 75%; } |
14 |
|
15 |
.column-4 { |
16 |
width: 100%; } |
17 |
}
|
Заключение
Наш окончательный grid.scss это ничтожные 42 строки кода; меньше, чем наш начальный CSS.
1 |
@import "variables"; |
2 |
@import "mixins"; |
3 |
|
4 |
*, *:after, *:before { |
5 |
margin: 0; |
6 |
padding: 0; |
7 |
@include border-box; |
8 |
}
|
9 |
|
10 |
img { |
11 |
width: auto; |
12 |
max-width: 100%; |
13 |
height: auto !important; |
14 |
}
|
15 |
|
16 |
.wrapper { |
17 |
width: 100%; |
18 |
margin: 0 auto; |
19 |
}
|
20 |
|
21 |
.wrapper, .row { |
22 |
@extend %clearfix; |
23 |
}
|
24 |
|
25 |
[class*='column-'] { |
26 |
float: left; |
27 |
padding: 1em; |
28 |
width: 100%; |
29 |
min-height: 1px; |
30 |
}
|
31 |
|
32 |
@media #{$breakpoint-medium} { |
33 |
.wrapper { |
34 |
width: 95%; |
35 |
max-width: $grid-max-width; |
36 |
}
|
37 |
@for $i from 1 through $grid-columns { |
38 |
.column-#{$i} { |
39 |
width: 100% / $grid-columns * $i; |
40 |
}
|
41 |
}
|
42 |
}
|
В течение этого процесса мы рассмотрели переменные Sass, mixins, заполнители, расширения, циклы, операторы и даже интерполяцию. Это невероятно мощный набор функций и отличное начало, если вы только начинаете работать с Sass.
Как ещë можно улучшить сетку, которую мы построили? Что ещë вы бы добавили или может убрали бы? Дайте нам знать об этом в комментариях!