Skip to content

Latest commit

 

History

History
344 lines (257 loc) · 12.1 KB

06. Адаптивность.md

File metadata and controls

344 lines (257 loc) · 12.1 KB

Адаптивность

Приводим сетку к продакшен-реди решению, изучаем адаптивность

Доделываем сетку

Базовую версию сетки мы сделали. Напомню, где мы остановились:

iframe: https://jsfiddle.net/y29uhtbL/22/embedded/result,html,css/

  1. сделали 12 колонок,
  2. сделали .row,
  3. сделали контейнер .container, чтобы фиксировать ширину контента

Но есть один нюанс: если мы зададим контейнеру бэкграунд, чтобы проверить как всё отработало, мы заметим один мерзкий баг — у контейнера есть отступы слева и справа.

iframe: https://jsfiddle.net/y29uhtbL/21/embedded/result,html,css/

Отступы есть по очевидной причине: у наших .col-*-классов есть padding-left и padding-right. Но как от них избавиться только в контейнере?

В этом нам помогут отрицательные марджины. Отрицательные марджины — зло и показатель непонимания блочной модели, но любое зло всегда имеет право на реализацию в каких-то пограничных случаях (edge cases).

Мы повесим отрицательные марджины слева и справа на .row:

.row {
  margin-left: -8px;
  margin-right: -8px;
}

iframe: https://jsfiddle.net/y29uhtbL/23/embedded/result,html,css/

Всё сразу же стало по красоте. Подчистим наш код, приведём в порядок — получим готовую сетку.

.container {
  max-width: 976px;
}

.row {
  display: flex;
  flex-wrap: wrap;
  margin-left: -8px;
  margin-right: -8px;
}

.col-1,
.col-2,
.col-3,
.col-4,
.col-5,
.col-6,
.col-7,
.col-8,
.col-9,
.col-10,
.col-11,
.col-12 {
  padding-left: 8px;
  padding-right: 8px;
  box-sizing: border-box;
}

.col-1 {
  flex-basis: 8.3333%;
}
.col-2 {
  flex-basis: 16.6666%;
}
.col-3 {
  flex-basis: 24.9999%;
}
.col-4 {
  flex-basis: 33.3333%;
}
.col-5 {
  flex-basis: 41.6665%;
}
.col-6 {
  flex-basis: 49.9998%;
}
.col-7 {
  flex-basis: 58.3331%;
}
.col-8 {
  flex-basis: 66.6664%;
}
.col-9 {
  flex-basis: 74.9997%;
}
.col-10 {
  flex-basis: 83.3333%;
}
.col-11 {
  flex-basis: 91.6663%;
}
.col-12 {
  flex-basis: 100%;
}

Красиво? Удобно? Да.


Резюмируя: мы не только поняли, что такое модульная сетка, но и научились сами её собирать на флексбоксах, разобрались, зачем нужен .row и как вместить наш контент в фиксированный контейнер.


Кстати, частый кейс — как сделать бэкграунд во всю ширину, а контент — в контейнере? Я думаю, вы догадались об ответе, но всё-таки.

<style>
  header {
    background-color: #6041FB;
  }
</style>

<header>
  <div class="container">
    <h1>Курс по вёрстке</h1>
  </div>
</header>

Адаптивность

Поговорим об адаптивности.

Когда делают сайты и веб-приложения, очень редко делают отдельные мобильные версии (типа mobile.twitter.com), чаще всего делают адаптивную вёрстку.

Что такое адаптивность? Способность приспосабливаться к изменениям. Адаптивная вёрстка? Способная приспосабливаться к изменениям!

Вы спросите: «да к каким изменениям-то?», а я отвечу «ко многим, но давайте разберемся с примитивами».

В ЦСС есть мощная штука медиакверис (media queries). Это условия, при которых выполняется, эээ, код, если ЦСС можно назвать таковым.

Семантика у неё простая:

@media <media-query-list> {
  /* css */
}

Где <media-query-list> это набор правил.

media-type

Всё просто: тип устройства. Нет, это не разграничение на айфоны и андроиды, макбуки и синкпады, это

  • all — любое устройство,
  • screencolor computer screens,
  • print — стили для печати,
  • speech — скринридеры.

Примеры:

@media print {
  body {
    font-size: 10pt;
  }
}

@media screen {
  body {
    font-size: 13px;
  }
}

@media screen, print {
  body {
    line-height: 1.2;
  }
}

media-feature

Их очень много, но в основном используют min-width — определить ширину экрана.

Примеры:

body {
  color: orange;
}

@media (min-width: 768px) {
  body {
    color: red;
  }
}

@media (min-width: 992px) {
  body {
    color: green;
  }
}

@media (min-width: 1200px) {
  body {
    color: blue;
  }
}

По-умолчанию (на маленьких устройствах) цвет текста будет оранжевым, при ширине от 768 пикселей — красным, от 992 пикселей — зеленым, а от 1200 — синим.

Как разобраться, какие размеры прописывать? Есть два способа: запомнить самые общие популярные параметры или подсматривать на screensiz.es.

Брейкпоинты

Такие параметры называются брейкпоинтами (breakpoints, точки слома): точки, когда поведение должно поменяться. Но, например, Миша Капанага с этим не согласен и я тоже с ним соглашусь — всегда нужно смотреть на конкретном сайте и исправлять конкретные проблемы, просто популярные брейкпоинты помогают ориентироваться.

Так какие значения-то? Они бьются по размерам:

  • xs это экраны до 576 пикселей (смартфоны),
  • sm — от 576 до 768 (большие смартфоны и планшеты в вертикальной ориентации),
  • md — от 768 до 991 (планшеты в горизонтальной),
  • lg — от 991 до 1200 (десктопы),
  • xl — от 1200 и выше (большие десктопы).

Есть небольшое уточнение: хоть и фактическая ширина тех же айфонов — 750 пикселей, она делится на два (375 пикселей) и вписываются в xs, потому что там Ретина. Как разобраться? Смотреть на значения pixel ratio и CSS width на сайте mydevice.io/devices.

Как строить адаптивность или mobile first

Существует подход mobile first, когда вы учитываете сначала мобильные девайсы и постепенно увеличиваетесь.

Честно говоря, сам термин давно устарел, я бы его назвал low first — сначала мы разбираемся с возможностями слабых (маленьких) устройств, а потом наращиваем мощности.

В нашем примере выше мы сначала объявили body { color: orange; }, а потом на брейкпоинтах ломали это значение, когда увеличивалась ширина экрана.

Примеры практики:

  • на маленьких девайсах мы размеры заголовков ставим в 26 пикселей, а на больших можем разогнаться и поставить 72,
  • на маленьких девайсах мы можем блоки разместить друг под другом (display: block), а на больших они вместятся рядом — поставим display: inline-block.

Поэтому всегда пишите код через mobile first: его легче будет дебажить (debug, отладка) и читать, он остаётся предсказуемым — ведь если мы видим чёткую нисходящую картину по размерам, то это легче понять, чем кучу свойств max-width.

Плохо: тяжело читать.

@media (min-width: 1200px) {
  body {
    color: blue;
  }
}

body {
  color: orange;
}

@media (max-width: 992px) {
  body {
    color: green;
  }
}

@media (max-width: 768px) {
  body {
    color: red;
  }
}

Хорошо: правила идут по увеличению экранов.

body {
  color: orange;
}

@media (min-width: 768px) {
  body {
    color: red;
  }
}

@media (min-width: 992px) {
  body {
    color: green;
  }
}

@media (min-width: 1200px) {
  body {
    color: blue;
  }
}

Задание

Сделайте планшетную и мобильную версии UberEats.

Но дополнительное задание: вернемся к сетке — пора её сделать адаптивной!

Если мы останемся с нашими .col-*, то у нас будут проблемы: на xs нам нужны элементы, которые идут друг за другом, на md они могут вместиться по 2 на строку, а на lg — вообще по 4 в одну строку. Текущая сетка этого не поддерживает.

Задание: сделать классы .col-[size]-*, где size это брейкпоинты.

Примеры использования:

<div class="row">
  <div class="col-xs-11 col-md-6 col-lg-3">test</div>
  <div class="col-xs-11 col-md-6 col-lg-3">test</div>
</div>

<div class="row">
  <div class="col-xs-11 col-sm-4 col-xl-2">test</div>
  <div class="col-xs-11 col-sm-4 col-xl-2">test</div>
</div>

Кстати, в первом примере я опустил sm значение, а во втором — md. Почему?

Потому что действует тот же принцип mobile first: то, что объявлено ниже, наследуется, пока не встретится брейкпоинт.

Не забывайте задавать вопросы в чате — там обязательно помогут 💪🏻

Помните: нет глупых вопросов, есть лишь страх их задавать.

Подсказка:

.col-xs-7 {
  flex-basis: 58.3331%;
}

... @media (min-width: 768px) {
  .col-md-3 {
    flex-basis: 24.9999%;
  }
}

Итог

Мы доделали сетку: исправили баг с контейнером и разобрались, когда нужно использовать отрицательные марджины.

Плюс изучили адаптивность через медиакверис и познакомились с принципом mobile first.