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

Наш блок имеет один недостаток — у него нет адаптивности. Под адаптивностью понимают способность блоков адаптироваться к разным размерам экранов.

Рассмотрим проблему подробней.

Пусть у нас есть экран десктопа — обычно это ширина от 1200px и выше. Классы layout ограничивают контент именно этой шириной. Можно, конечно сделать и больше, но нормальная ширина, которую легко воспринимает человек — это примерно размер обычного листа A4. Просто приложи его к экрану своего монитора и ты увидишь, что текст хорошо читается. Если увеличить этот размер, то многие тексты окажутся вытянутыми в одну строчку. Это некрасиво и элементарно неудобно читать — придётся крутить головой, чтобы прочитать всю строчку.

Котик
Автор котика: Jérôme Decq

Ладно, с этим определились — так или иначе нужно ограничивать максимальную ширину. Теперь посмотрим размеры планшетов. Очевидно, что это размеры от 1200px (наш максимум) до 1024px — это типовой размер планшета по горизонтальной ориентации. В целом разница между ними не очень большая. Но если повернуть планшет вертикально, то будет 768px — это довольно узко.

Двигаемся дальше — телефоны/смартфоны. Большинство по горизонтали имеют ширину 620-680px, а по вертикали 320-360px. Всё что ниже 320px следует рассматривать как small-устройства. Экран там совсем мизерный.

Задача верстальщика сделать так, чтобы блоки на всех этих экранах отображались корректно. Понятно, что мы не сможем сделать это путём масштабирования (так работали старые браузеры), поэтому используется другой приём — изменение компоновки блоков.

На экране десктопа (1200px) пусть будет так:

название
меню
иконки

На экране планшета уже так:

название
иконки
меню

А на телефоне:

название
иконки
меню

По факту это один и тот же html-блок, но для каждой ячейки (и, возможно, контейнера) прописываются специальные классы, которые меняют поведение при определенной ширине экрана. В CSS для этого используется специальная конструкция @media.

Media-условия

Медиа-условия похожи на обычные css-классы, но на самом деле являются ограничивающим блоком, задающим css-классы в пределах своего условия.

@media условие {
	класс1 {}
	класс2 {}
	класс3 {}
} 

Рассмотрим пример:

@media (max-width: 640px) {
	.w50-phone { width: 50%; }
	.w100-phone { width: 100%; }
}

Условие max-width: 640px указывает на то, что оно будет выполнено для максимальной ширины экрана 640px (телефоны). Как только ширина браузера окажется в этом диапазоне (от 0 до 640px), то браузер подключит классы w50-phone и w100-phone. Если же условие не соблюдается, то классов как будто бы и не существует.

Сами условия можно комбинировать между собой. Например:

@media (max-width: 768px) and (min-width: 640px) {
	.w50-tablet { width: 50%; }
	.w100-tablet { width: 100%; }
}

В данном примере условие ограничивает экраны от 640px до 768px (планшет в портретной ориентации). Таким образом, если у блока задать:

<div class="w50-table w100-phone"></div>

то ширина этого блока для телефона будет 100%, а для планшета 50%, поскольку классы сработают только в пределах своих условий.

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

В Berry адаптивность реализуется с помощью классов, которые имеют специальный суффикс:

  • -tabletmax-width: 768px
  • -phonemax-width: 667px
  • -smallmax-width: 360px

Работает это так: вначале выполняется вёрстка для больших экранов (называется desktop-first) c помощью обычных классов, как мы и делали.

После этого прописываются классы адаптивности под каждый экран. При этом действие класса распространяется «вниз». Например можно не указывать w100-tablet w100-phone, поскольку w100-tablet будет действовать и на меньшую ширину.

Конечно не все классы Berry поддерживают суффиксы адаптивности, но их всё равно хватает для 99% вёрстки.

Добавляем адаптивности

Код из прошлого примера, только я убрал внутренне содержимое, чтобы не отвлекаться на него.

<div class="layout-center-wrap bg-blue700">
    <div class="layout-wrap">
        <div class="flex flex-ai-center pad20-tb">
            <div class="w2col flex">
                лого + Название
            </div>

            <div class="w8col t-center">
                меню
            </div>

            <div class="w2col t-right t130">
                иконки
            </div>
        </div>
    </div>
</div>

Вначале разрешим в основном flex-контейнере wrap-перенос. Нужен он будет для tablet и меньше — это класс flex-wrap-tablet:

...
<div class="flex flex-ai-center pad20-tb flex-wrap-tablet">
...

Теперь, когда размер экрана станет меньше, чем 768px, flex-ячейки смогут переноситься друг под друга.

Ячейки названия и иконок на планшете будут иметь ширину по 50%. На телефоне — по 100%. А ячейка меню будет 100% уже на планшете.

...
<div class="w2col flex w50-tablet w100-phone">
    лого + Название
</div>

<div class="w8col t-center w100-tablet">
    меню
</div>

<div class="w2col t-right t130 w50-tablet w100-phone">
    иконки
</div>
...

Теперь мы помним, что нужно поменять порядок ячеек. За порядок во flex-сетке отвечают классы flex-orderN, что соответствует css-свойству order: N, где N — число, указывающее на порядок в сетке. По умолчанию order равен 1, значит, чтобы сместить ячейку под остальные, достаточно будет для блока меню указать 2.

...
<div class="w8col t-center w100-tablet flex-order2-tablet">
    меню
</div>
...

В блоке иконок на телефонах также меняется выравнивание текста с right на center.

...
<div class="w2col t-right t130 w50-tablet w100-phone t-center-phone">
    иконки
</div>
...

Выравнивание меняется и в блоке названия, но у нас там своя flex-сетка, поэтому пока оставим как есть. Вот что должно получиться на этот момент:

<div class="layout-center-wrap bg-blue700">
    <div class="layout-wrap">
        <div class="flex flex-ai-center pad20-tb flex-wrap-tablet">
            <div class="w2col flex w50-tablet w100-phone">
                <img class="filter-invert" src="atom.svg" width="40" alt="">
                <div class="w90 mar10-l t200 t-white">Название</div>
            </div>

            <div class="w8col t-center w100-tablet flex-order2-tablet">
                <a class="mar10-rl t-white hover-t-blue200" href="#">Линк 1</a>
                <a class="mar10-rl t-white hover-t-blue200" href="#">Линк 2</a>
                <a class="mar10-rl t-white hover-t-blue200" href="#">Линк 3</a>
                <a class="mar10-rl t-white hover-t-blue200" href="#">Линк 4</a>
            </div>

            <div class="w2col t-right t130 w50-tablet w100-phone t-center-phone">
                <a class="mar10-l t-white hover-t-blue200 hover-no-underline fab fa-twitter" href="#"></a>
                <a class="mar10-l t-white hover-t-blue200 hover-no-underline fab fa-instagram" href="#"></a>
                <a class="mar10-l t-white hover-t-blue200 hover-no-underline fab fa-tiktok" href="#"></a>
                <a class="mar10-l t-white hover-t-blue200 hover-no-underline fab fa-facebook" href="#"></a>
            </div>
        </div>
    </div>
</div>

Проверь этот код в Berry Builder: поиграй шириной браузера.

Центрирование во flex-сетке

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

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

...
<div class="w2col flex w50-tablet w100-phone">
    <div class="w0 w40-tablet"></div>
    <img class="filter-invert" src="atom.svg" width="40" alt="">
    <div class="w90 mar10-l t200 t-white">Название</div>
</div>
...

Здесь растяжка 40% на phone, но 0% в обычном режиме. В зависимости от реального текста, можно будет подобрать ширину растяжки или основных ячеек.

Конечно же такой вариант лишь один из возможных. Просто остальные будут сложнее для новичка.

Что ещё можно добавить? Думаю, что не хватает отступов между ячейками. Сейчас они смотрятся скомкано. Для этого используем класс mar10-b-phone.

Итоговый код

<div class="layout-center-wrap bg-blue700">
    <div class="layout-wrap">
        <div class="flex flex-ai-center pad20-tb flex-wrap-tablet">
            <div class="w2col flex w50-tablet w100-phone mar10-b-phone">
            	<div class="w0 w40-tablet"></div>
                <img class="filter-invert" src="atom.svg" width="40" alt="atom">
                <div class="w90 mar10-l t200 t-white">Название</div>
            </div>

            <div class="w8col t-center w100-tablet flex-order2-tablet mar10-b-phone">
                <a class="mar10-rl t-white hover-t-blue200" href="#">Линк 1</a>
                <a class="mar10-rl t-white hover-t-blue200" href="#">Линк 2</a>
                <a class="mar10-rl t-white hover-t-blue200" href="#">Линк 3</a>
                <a class="mar10-rl t-white hover-t-blue200" href="#">Линк 4</a>
            </div>

            <div class="w2col t-right t130 w50-tablet w100-phone t-center-phone mar10-b-phone">
                <a class="mar10-l t-white hover-t-blue200 hover-no-underline fab fa-twitter" href="#"></a>
                <a class="mar10-l t-white hover-t-blue200 hover-no-underline fab fa-instagram" href="#"></a>
                <a class="mar10-l t-white hover-t-blue200 hover-no-underline fab fa-tiktok" href="#"></a>
                <a class="mar10-l t-white hover-t-blue200 hover-no-underline fab fa-facebook" href="#"></a>
            </div>
        </div>
    </div>
</div>

Как работать с адаптивностью

Сейчас кажется, что код получился сложным, но на самом деле он состоит из простых классов. Вот чтобы упростить себе задачу, старайся работать примерно по такой схеме.

  • Вначале вёрстка делается без учёта адаптивности — desktop-вариант.
  • Добавляем адаптивность для контейнера и основных ячеек. Не обращая внимания на содержимое, добиваемся чтобы ячейки корректно занимали свои позиции на планшете и телефоне.
  • После этого занимаемся внутренним содержимым каждой ячейки.
  • И в конце тестируем вёрстку на разных экранах.

Если ты работаешь в браузере Chrome, то нажми F12 — это панель разработчика. В ней нажми Ctrl+Shift+M — это режим мобильности. Здесь ты можешь менять разрешение экрана и так тестировать отображение страницы.

Ещё важный момент, который ты должен сразу знать. Когда мы меняем ширину браузера (а именно так часто работают верстальщики), то могут быть такие положения, когда страница отображается некорректно. Есть желание подкорректировать media-точки или размеры. Но на самом деле так поступают только разработчики — в реальности пользователи не меняют ширину браузера, не говоря уже о том, что сделать это на планшете или телефоне крайне затруднительно.

Поэтому правильно тестировать адаптированную вёрстку нужно на конкретных точках, без промежуточных состояний. Обычно это 1024px, 768px, 668px и 360px. Если в этих точках страница отображается корректно, то скорее всего проблем у посетителей не возникнет.

Задания

Посмотри панель разработчика в Chrome (или FireFox) и разберись как пользоваться режимом мобильности. Протестируй страницы и отметь проблемные точки. Если получится, подумай как их можно исправить. В любом случае адаптивность для новичка достаточно сложная тема, поэтому ничего страшного, если что-то не получается.