Введение
Задача, которую решает модульная CSS сетка, очень проста и должна быть понятна всем уже на этом этапе: предоставить удобный механизм расположения контента по виртуальной сетке.
Статья будет разбита на две части: в первой будут рассмотрены технологии, применяемые в нашей сетке, а во второй части мы, наконец-то, её построим.
Итак, поехали!
Словарь
Для начала необходимо будет усвоить несколько простых, но очень важных возможностей CSS, а дальше уже мы построим простейшую сетку, которую можно будет использовать прямо сейчас.
Box-sizing
Теория
Box-sizing - это свойство, позволяющее изменять алгоритм расчёта ширины и высоты элемента.
Это свойство, помимо наследования значения родителя, может принимать ещё три значения:
- content-box (по умолчанию) - Значение свойств width и height задают размеры контента, при этом не включают в себя отступы, поля и границы.
- border-box - Значение свойств width и height задают размеры всего блока, при этом включают в себя поля и границы, но не отступы.
- padding-box - Значение свойств width и height задают размеры всего блока, при этом включает в себя поля, но не отступы и границы.
Практика
Использовать это свойство очень просто - для начала добавьте код, приведённый ниже, после normalize.css (разумеется, если используете его) до начала блока ваших стилей. Да и всё на этом - готово!
*,
*:before,
*:after {
box-sizing: border-box;
}
При этом ко всем селекторам будет применяться это свойство. Да, тут три раза использован универсальный селектор, да ещё и вместе с псевдоклассами, которые все боятся использовать. Однако, спешу развеять ваши сомнения об его уместности, так как байка про скорость универсального селектора ушла в небытие и актуальна лишь для браузера, чьё название произносить нельзя, до восьмой версии включительно.
Кстати, этот способ получил наибольшее распространение благодаря фреймворку Bootstrap. Сейчас же, использование этого свойства - хороший тон вёрстки.
К счастью, вы можете использовать box-sizing
без префиксов, конечно, если вы не поддерживаете тот самый браузер. Об этом нам напоминает Can I use.
Но зачем всё это для нашей сетки?
Отличный вопрос!
Как вы могли уже догадаться, использование box-sizing: border-box
, даёт нам независимость от полей и границ блока. Именно это нам и понадобится при построении нашей сетки.
Media queries
Теория
Media queries (Медиа-запросы) - часть спецификации CSS3, которая позволяет нам задавать некую область действия селектора.
Медиа-запросы очень мощная штука, поддерживающая различные технические параметры устройств, отображающих контент. Прочитать обо всех поддерживаемых параметрах можно на htmlbook, при этом не предавая мысли о том, что поддержка IE ниже 9-ой версии - зло.
Практика
На деле же, в основном используется лишь малая часть возможностей, а именно: ширина и высота окна браузера, разрешение и плотность пикселей устройства и его ориентация в пространстве.
Нам понадобится только лишь параметр ширины окна браузера:
@media (min-width: значение) { ... }
@media (max-width: значение) { ... }
@media (min-width: значение) and (max-width: значение) { ... }
На месте значений
вписывается, как бы это банально не звучало, значение (px, em, rem). Например:
@media (min-width: 768px) { background-color: #000 }
Важно учесть, что при использовании свойства min-width
имеет место наследование свойств родителя. Это очень важное замечание, так как не стоит заново указывать все свойства - достаточно лишь указать те, что следует изменить.
Графически можно изобразить это так:
И всё же, давайте рассмотрим пример.
На холсте у нас всего лишь один div
:
<div class="demo-block">Demo Text</div>
Зато присутствует простыня стилей:
/* Basic styles */
.demo-block {
background-color: #ccc;
color: #fff;
padding: 25px;
}
/* Screen > 768px */
@media (min-width: 768px) {
.demo-block {
text-align: center;
}
}
/* Screen > 992px */
@media (min-width: 992px) {
.demo-block {
text-align: right;
}
}
/* Screen > 1200px */
@media (min-width: 1200px) {
.demo-block {
background-color: #fff;
color: #000;
text-align: left;
}
}
Если не терпится посмотреть результат, то перейдите по ссылке и изменяйте ширину блока с помощью мыши.
Итак, у нас есть базовый стиль поля, цвет текста и фон. При изменении размеров окна браузера, внешний вид блока не будет меняться до тех пор, пока ширина окна меньше 768px
. Как только значение перевалит через эту отметку, наш блок получит новое свойство (вернее сказать, получит переопределение стандартного свойства) - выравнивание текста по центру. Мы изменяем ширину окна ещё больше. Достигаем значения 992px
и наш текст выравнивается по правому краю. Меняем размер снова. На этот ширина будет больше 1200px
. получается, что отрабатывает новый блок, в котором меняется фон, цвет текста и его выравнивание.
Просто же, неправда ли?
Используемый выше подход называется сначала мобильные
, то есть сначала мы задаём стиль для мобильных устройств и с увеличением разрешения добавляем или переопределяем какие-то стили.
К сожалению, не всегда можно ограничиться таким подходом и приходится использовать какие-то конечные промежутки. Иначе говоря, использовать сразу два переломных значения.
@media (min-width: значение) and (max-width: значение) { ... }
Допустим, так:
.class {
background-color: #000;
color: #fff;
}
@media (min-width: 540px) and (max-width: 767px) {
.class {
background-color: #fff;
color: #000;
}
}
@media (min-width: 768px) {
.class {
color: red;
}
}
Изначально имеется чёрный фон и белый цвет текста до тех пор, пока ширина окна браузера не преодолеет отметку в 540px . Если это произойдёт, то фон станет белым, а цвет текста чёрным. Но, так как у нас задан чёткий отрезок, то при достижении отметки в 768px фон изменится снова на изначальный (белый), а цвет текста станет красным.
Но зачем всё это для нашей сетки?
И снова в точку!
С помощью медиа-запросов мы сможем менять свойства контейнера, в зависимости от ширины окна браузера, но об этом немного позже.
Плавающие элементы
Теория
Замечательно, теперь мы можем изменять свойства селектора, в зависимости от ширины окна браузера. Однако, этого недостаточно. Нам же нужно сделать наши будущие столбцы плавающими. А тут возникают проблемы.
Давайте рассмотрим такую проблему и её решение.
У нас есть следующая разметка:
<div class="row">
<div class="col-one">Col #1</div>
<div class="col-two">Col #2</div>
</div>
И вот такие вот стили:
.row {
background-color: #cfcfcf;
padding: 25px;
}
.col-one,
.col-two {
float: left;
width: 50%;
background-color: #fff;
}
В результате имеет вот такое вот поведение:
Но постойте-ка! Почему родительский элемент имеет разный размер поля вокруг дочерних? А ответ прост - особенность float: left
и его родительского класса.
Один из способов переназначить элементам тип обтекания — это использование свойства float. В этом примере мы задаём обтекание по левому краю и величина родительского класса считается по наименьшей высоте блочного элемента. Получается, что родительский элемент не знает своей реальной высоты, так как берёт высоту у неплавающих блоков.
Посчитаем:
- Высота - 0px
- Поле сверху - 25px
- Поле снизу - 25px
Итого: 50px.
Для того, чтобы исправить эту ситуацию, используется так называемый clearfix, который запрещает обтекание элементов с обеих сторон.
Типичный clearfix для современных браузеров выглядит следующим образом:
.clearfix:before,
.clearfix:after {
content: " ";
display: table;
}
.clearfix:after {
clear: both;
}
Вот теперь другое дело!
Псевдоэлементы :before
и :after
создают пустую ячейку таблицы и предотвращают вертикальное схлопывание отступов. В то же время, псевдоэлемент :after
дополняется объявлением свойства clear: both
, которое прерывает обтекание с обеих сторон.
Как-то запутанно? Так и есть, но я уверен, что большинство использует clearfix и даже не знает как он работает. Теперь же, вы не все :)
Внимание!
Одним из вариантов использования
clearfix
- создание отдельного класса.group
для элементов, которые подразумевают наличие плавающих блоков. Однако, если вы используете какой-либо препроцессор или в макете таких элементов меньше трех, тогда проще будет прописать их для каждого элемента отдельно.
Заключение
В первой части статьи мы разобрались со всем тем, что нам предстоит использовать при построении сетки. Наконец-то узнали, зачем необходимо свойство box-sizing
, разобрались с базовой возможностью медиа-запросов @media
и в довесок теперь понимаем что такое clearfix
.
Продолжение статьи будет находиться тут.