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

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

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

Краткая история

Еще 15 лет назад, когда первые айфоны ввозились в Россию частниками и требовали установки джейлбрейка для работы с местными сотовыми операторами, большинство сайтов не могло похвастаться удобным интерфейсом в мобильном браузере. Открываешь страницу — а на ней ужасно мелкий текст, который невозможно прочесть, или горизонтальный скролл в дополнении к привычному вертикальному. А иногда и скролла нет. Для больших картинок эта проблема актуальна и по сей день.

Скриншоты страницы с широкой картинкой, которую невозможно прокрутить по горизонтали

Но количество пользователей смартфонов росло, и статистика посещений сайтов подсказывала бизнесу, что мобильная версия становится всё более востребована. Сейчас больше половины посещений веб‑страниц происходит через браузеры смартфонов. Поэтому нам нужно поддерживать разные размеры экранов для адекватного отображения контента.

Статистика запросов по данным https://radar.yandex.ru/

HTML или текст по умолчанию «отзывчивы»: строки текста могут иметь любую ширину и занимают всё отведенное им пространство. Но стоит сравнить книгу и журнал и мы увидим, что для удобного чтения нужно разбить текст на не слишком длинные и не слишком короткие строки, поэтому шаблон страницы меняется в зависимости от её физического размера. На сайтах всё очень похоже, только иногда по бокам остаётся много пустого места.

Первое, что придумали веб‑разработчики — это адаптивный дизайн (adaptive design). Конечно, правильный перевод — это дизайн, адаптированный к новым размерам экрана, но как это часто бывает в айти, здесь закрепилось испольование англицизма. Адаптивный дизайн основан на создании отдельных шаблонов страниц, по которым генерируется контент сайта, а также отдельных файлов стилей и скриптов. Получая запрос от браузера, серверное приложение определяет, какие темплейты использовать, чтобы вернуть правильный http‑response. И для каждого поддерживаемого браузера, для каждого типа контента нужно было делать отдельные заготовки. При этом одна часть кода, стилей и скриптов дублировалась, а другая отличалась, и это затрудняло разработку и сопровождение проекта.

А затем пришли новые смартфоны разных размеров, планшеты, 4К мониторы и часы — вариантов экранов появилось так много, что поддерживать подобный подход стало совершенно невыгодно. На смену ему пришел отзывчивый дизайн (responsive design). Для его реализации используется общий код сайта и общий css, и совсем не используются скрипты. Всё это стало возможным благодаря новым стандартам CSS, и их поддержке в веб‑браузерах.

Раньше приходилось устанавливать расширения для разработчиков, которые позволяли изменять поле User‑Agent в запросе к серверу. Тогда сервер распознавал request как запрос от «мобильного браузера» и генерировал ответ, используя шаблоны адаптивного дизайна. Отзывчивый дизайн проще проверять и отлаживать, т.к. вы можете изменить размер окна браузера прямо на своем рабочем месте. Для примера, вы можете прямо сейчас изменить ширину окна и увидеть как изменится интерфейс этой страницы. Кстати, на многих сайтах при уменьшении ширины окна скрываются боковые блоки с рекламой.

Почему важно обсуждать новые технологии с точки зрения разных специалистов

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

Однако разработчик, получивший эти макеты для реализации, сталкивается с рядом проблем. Например, один из экранов приложения включает в себя сложную анимацию перехода между состояниями, которая выглядит великолепно на статичном изображении, но оказывается труднореализуемой с точки зрения кода. Более того, некоторые элементы дизайна не учитывают разные размеры экранов: кнопки слишком маленькие для использования на смартфонах, а текст — слишком мелкий для чтения.

В результате разработчик вынужден сообщить команде о необходимости пересмотра дизайна. Это приводит к разочарованию и недопониманию: дизайнеры не понимают, почему их идеи нельзя реализовать так, как они задумали. Разработчик же чувствует давление из‑за нехватки времени на доработку.

Мы уверены, что если дизайнеры познакомятся со стандартными — быстрыми — техническими возможностями, а разработчики посмотрят на проектирование интерфейса глазами дизайнера, то им будет легче договориться. И это поможет избежать ненужных переделок и сохранить творческий настрой.

Проектирование отзывчивого дизайна

Теперь поговорим о том, как создаётся отзывчивый дизайн для веб‑приложения. Он должен обеспечивать оптимальное взаимодействие пользователю на различных устройствах. Это означает, что изображения, текст и другие элементы контента меняют свое расположение и пропорции в соответствии с размером экрана и его разрешением, подстраиваясь под высоту и ширину области отображения.

Итак, как сделать отзывчивое приложение? Все начинается с проектирования интерфейса. В дизайне нужно учитывать несколько принципов:

  1. Проектируем страницы для разных типоразмеров;

  2. Учитываем особенности навигации;

  3. Адаптируем экраны с формами;

  4. Начинаем с «мобилки».

Рассмотрим каждый из них подробнее.

Дизайн для разных типоразмеров экранов

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

Для ширины выбираются следующие граничные значения:

  1. маленькие — от 320 px или 480 px;

  2. средние — 768 px;

  3. нормальные — 1024 px;

  4. большие — 1280 px, 1600 px;

  5. очень большие — 1920 px.

Эти значения называют breakpoint»ы, и используют их в запросах media query.

Иногда макеты разных типоразмеров называют как устройства, из‑за которых они появились: «смартфоны, планшеты, нетбуки, компьютеры и 4К‑мониторы». Эти названия подразумевают дополнительные сведения о вариантах использования, скорости и методах взаимодействия, которые могут оказаться неверными. Поэтому лучше использовать названия вариантов дизайна по размеру.

Отдельного дизайна (или хотя бы проверки применимости маленького макета) требует вариант отображения с небольшой высотой. Легко представить его как сайт, открытый на смартфоне в пейзажной ориентации. Для такого макета нельзя использовать фиксированные колонтитулы (хидер и футер), даже если на всех остальных макетах они подходят.

Проектируем навигацию

Следующее, что нужно продумать — это навигационные элементы. Важно обеспечить возможность перемещения по разделам приложения на всех экранах. В привычном вебе меню отображается часто в шапке сайта: логотип, он же ссылка на home, и далее основные разделы, иногда с подразделами в виде выпадающих списков. Для экранов смартфонов меню прячется под кнопку гамбургера, и отображается поверх остального контента только по нажатию пользователем. Благодаря своей компактности и удобству, гамбургер‑меню быстро завоевало популярность в мобильных сайтах и сейчас превратилось в стандартное решение для маленьких экранов. Мы считаем, что не обязательно делать его на чистом css, без javascript. Но это возможно, и если хотите, мы напишем об этом в одной из следующих статей.

Для средних экранов можно выбрать промежуточное решение. Важно обратить внимание на выпадающие списки, поскольку они могут оказаться выше области отображения, и в таких случаях на них должен работать скролл.

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

Пример хлебных крошек с сайта Justinmind

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

Адаптируем экраны с формами

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

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

Для всех имеющихся кнопок и ссылок необходимо выполнить дизайн, который позволит удобно пользоваться ими на устройствах с тачскрином. Раньше это означало существенно большую, чем на десктопах, область взаимодействия с контролом. Парадокс, но кнопки на маленьких экранах нужны больше! Однако, теперь подобная проблема почти никогда не возникает, потому что выполняется четвертый принцип:

Сначала проектируем для «мобилки»

При проектировании дизайна основного содержимого лучше начать с «мобильной версии» — самого маленького экрана в портретной ориентации. Раньше пользователи просматривали сайты с десктопных браузеров, и они открывали по несколько страниц из результатов поиска. Если сайт долго загружался, то пользователь переходил к следующему, а к этому возвращался позже. С переходом на мобильные устройства поведение по умолчанию изменилось: теперь пользователи не открывают много страниц разом, а предпочитают открывать по одной ссылке из топа выдачи. Если приложение долго загружается, то пользователь закрывает страницу и открывает следующую ссылку из поиска. Медленный сайт теряет шанс на просмотр. Именно поэтому необходимо делать веб‑приложение, адаптированное к мобильным устройствам и по размеру исходников, и по скорости отображения, и по дизайну интерфейса. Необходимо с одной стороны показать всю важную информацию на маленьком экране, а с другой — не перегружать интерфейс и внимание пользователя избытком элементов.

Подход Mobile First помогает сосредоточиться на основном содержимом. Применение этого принципа начинается еще на этапе анализа и влияет не только на отображение элементов интерфейса, но и на формулировки юс‑кейсов и выбор данных.

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

Разработка отзывчивого дизайна

Когда у нас спроектирован интерфейс, можно приступать к разработке. Чтобы сделать отзывчивый дизайн, можно использовать напрямую средства css, а можно подключить библиотеки, которые облегчают написание кода. Основные возможности, благодаря которым мы реализуем отзывчивый интерфейс, следующие: мета тег viewport, grid view и box‑sizing, media query. Рассмотрим подробнее, как они работают.

Что делает viewport

Meta тег viewport позволяет задать начальное масштабирование контента и ширину. Размеры элементов: шрифтов, блоков, картинок могут задаваться в пикселях, но физический размер пикселей на устройствах отличается. Это зависит от плотности пикселей: на экранах ретина или 4К плотность выше, поэтому без указания масштабирования текст становится чересчур мелким для чтения. Браузер может вычислить соответствие между указанным (или взятым из значений по умолчанию) размером в пикселях, и соответствующим ему ожидаемому размеру в реальном мире. Благодаря установке initial-scale=1, мы получаем читабельные тексты и нормальные размеры для всех элементов, чьи размеры указаны в пикселях.

<meta name="viewport"content="width=device-width, initial-scale=1.0" />
Примеры с сайта W3Schools

Поскольку у нас есть такой инструмент, мы можем легко сделать на экранах с различной плотностью пикселей масштабирование объектов, чьи размеры заданы в абсолютных величинах. Это стоит учитывать в дизайне и не задавать непропорциональные размеры шрифтов или блочных элементов.

Как используются grid view и box-sizing

Box-sizing это свойство блочных элементов, которое позволяет установить, как правильно рассчитать размер блока. Значение по умолчанию это content-box, оно означает, что ширина и высота блока соответствуют размерам его внутреннего содержимого. И при отображении блока, к его размеру добавляются внутренние отступы (padding) и границы. Если мы хотим, чтобы размеры, указанные через width и height, включали в себя padding и border, нужно использовать значение border-box. Удобно задать его для всех элементов сразу, используя вайлдкард *.

* { box-sizing: border-box; }

Grid view помогает нам реализовать дизайн, который можно наложить на сетку. Представьте таблицу: какие-то ячейки объединены по вертикали, какие-то по горизонтали. У каждой получившейся области есть свой идентификатор. И любой блок на странице помещается в соответствующую область указанием этого идентификатора.

.item1 { grid-area: header; }
.item2 { grid-area: menu; }
.item3 { grid-area: main; }
.item4 { grid-area: right; }
.item5 { grid-area: footer; }

.grid-container {
  grid-template-areas:
    'header header header header header header'
    'menu main main main main right'
    'menu footer footer footer footer footer';
}
Пример расположения элементов по именованной сетке 6х3.

Мы можем не задавать имена отдельным ячейкам, а указать только количество колонок в сетке, и далее размещать элементы в ней. Строка будут добавляться при заполнении предыдущей, и общее количество строк вычисляется автоматически. Неименованные колонки можно задавать точками. Если в такой сетке нужно указать блоку расположение, требующее «слияния» ячеек, то используются свойства, наподобие координат, задающие верхний левый угол блока и нижний правый угол. Координат служат воображаемые линии между колонками и строками, занумерованными от 1. Например, укажем значения grid-row-start, grid-column-start, grid-row-end и grid-column-end, используя короткую запись grid-area. Следующий код делает точно такую же композицию, как на картинке выше:

.container {
display: grid;
grid-template-areas:
    '. . . . . .';
}
.item1 { grid-area: 1 / 1 / 2 / 7; }
.item2 { grid-area: 2 / 1 / 4 / 2; }
.item3 { grid-area: 2 / 2 / 3 / 6; }
.item4 { grid-area: 2 / 6 / 3 / 7; }
.item5 { grid-area: 3 / 2 / 4 / 7; }

Количество строк и колонок в сетке Grid контейнера может быть любым, а если нужна только одна колонка или только одна строка, то можно использовать более простой шаблон под названием flex container.

.flex-container {
  display: flex;
  flex-direction: row;
}

У flex контейнера есть свойства, позволяющие определить порядок наполнения и относительные или абсолютные размеры элементов. Все дивы внутри блока‑контейнера называются flex item»ами и имеют свойства для позиционирования внутри контейнера и изменения порядка. Но это уже особенности реализации. Вернемся к нашему разговору о том, что мы можем сделать легко и просто, чтобы реализовать отзывчивый интерфейс сложнее одномерного списка блоков. Итак, представим, что у нас есть сетка как в первом примере, и теперь мы хотим сделать дизайн для экрана шире и уже задизайненного брейкпоинта. Тут‑то нам и пригодится Media query.

Какие возможности даёт Media query

Media query это инструмент css3, который позволяет описывать правила или условия, при выполнении которых будет применяться вложенный код css‑стилей. Это условный оператор в коде css! Например, если ширина окна браузера не более 600px, то мы можем перестроить структуру grid контейнера, так чтобы каждая зона занимала целую строку:

@media only screen and (max-width: 600px) {
  .grid-container {
    grid-template-areas:
      'header'
      'menu'
      'main'
      'right'
      'footer';
  }
}
Упрощенная структура для интерфейса на маленьком экране

Или мы можем описать расположение item»ов таким образом, чтобы каждый занимал, к примеру, 6 колонок — результат будет тот же.

@media only screen and (max-width: 600px) {
  .item1 { grid-area: 1 / span 6; }
  .item2 { grid-area: 2 / span 6; }
  .item3 { grid-area: 3 / span 6; }
  .item4 { grid-area: 4 / span 6; }
  .item5 { grid-area: 5 / span 6; }
}

А что делать с очень широкими экранами? Самый простой вариант — задать максимальную ширину для контейнера, и установить внешние боковые отступы в auto, тогда слева и справа останется поровну пустого места, а всё содержимое сайта отобразится по центру. Кроме того, мы можем задать ширину отдельных колонок (например, меню и правого сайдбара), и тогда колонка с основным содержимым будет подстраиваться по ширине, растягиваясь между фиксированными боковыми колонками.

@media only screen and (min-width: 800px) {
    .container {
        max-width: 1000px;
        margin: 0 auto;
        grid-template-columns: 150px auto auto auto auto 160px;
    }
}
При ширине страницы больше, чем max-width контейнера, по бокам появляются отступы

Полный код страницы выглядит так:

<!DOCTYPE html>
<html lang='en-US'>
<head>
<meta content='width=content-width' name='viewport'/>

<style>
body {
    background-color: #fcfcff;
    font-family: sans-serif;
}

* {
    margin: 0;
    box-sizing: border-box;
}

.container {
    display: grid;
    gap: 10px;
    padding: 10px;
    grid-template-areas: '. . . . . .';
}

.container > div {
    padding: 10px;
    font-weight: bold;
    color: white;
    min-height: 100px;
}

.item1 { grid-area: 1 / 1 / 2 / 7; }
.item2 { grid-area: 2 / 1 / 4 / 2; }
.item3 { grid-area: 2 / 2 / 3 / 6; }
.item4 { grid-area: 2 / 6 / 3 / 7; }
.item5 { grid-area: 3 / 2 / 4 / 7; }

.container > div.item5 {
    color: #444;
}

.item1 { background-color: #1D4FD8; }
.item2 { background-color: #4F1DDA; }
.item3 { background-color: #2C0A8D; }
.item4 { background-color: #037C87; }
.item5 { background-color: #6DDDE8; }

.item2 ul li {
    list-style: none;
    padding: 0 0 10px;
}
.item2 ul {
    padding: 0;
}

@media only screen and (max-width: 600px) {
  .item1 { grid-area: 1 / span 6; }
  .item2 { grid-area: 2 / span 6; }
  .item3 { grid-area: 3 / span 6; }
  .item4 { grid-area: 4 / span 6; }
  .item5 { grid-area: 5 / span 6; }
}

@media only screen and (min-width: 800px) {
    .container {
        max-width: 1000px;
        margin: 0 auto;
        grid-template-columns: 150px auto auto auto auto 160px;
    }
}
</style>

</head>
<body>
<div class="container">
  <div class="item1">Лого и заголовок</div>
  <div class="item2">
	<ul>
	<li>Меню 1</li>
	<li>Меню 2</li>
	<li>Меню 3</li>
    </ul>
  </div>
  <div class="item3">Основной контент</div>
  <div class="item4">Колонка справа</div>
  <div class="item5">Нижний колонтитул</div>
</div>
</body>
</html>

Главный принцип создания отзывчивого приложения — тестирование

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

То же самое касается и тестирования перед публикацией приложения для пользователей. Необходимо проверить следующие аспекты:

  1. Просмотрите сайт на различных устройствах: откройте сайт на своем смартфоне, планшете, Smart TV и т. д., чтобы убедиться, что он масштабируется надлежащим образом.

  2. Попробуйте изменять размер окна браузера, чтобы посмотреть, как меняется структура отображения.

  3. Попробуйте увеличивать или уменьшать масштаб изображения. Нажмите Command + на Mac или Control + на Windows, чтобы увеличить масштаб, и Command — или Control — для уменьшения, чтобы убедиться, что все нужные элементы видны и доступны.

  4. Используйте Inspector в браузере для проверки дизай. В большинстве браузеров нажмите клавишу F12 или щелкните правой кнопкой мыши на странице и выберите Inspect, чтобы открыть инструменты разработчика. Нажмите на значок устройства, обычно это телефон или планшет, на панели инструментов разработчика, чтобы перейти в режим проверки отзывчивого дизайна. Измените ширину экрана, и посмотрите, как меняется сайт.

Итоги

Но почему так важно опираться на стандартные подходы? Не только потому что это быстрее кодить, а потому что приложение, созданное на основе стандартных средств, быстрее работает. Когда появились первые смартфоны, разработчиком приходилось изобретать решения. Удобные, быстро реализуемые решения стандартных задач распространялись и включались в технологический стек сначала на уровне библиотек или систем управления контентом, таких как WordPress, Drupal. Но масштаб изменился, и сейчас отзывчивый дизайн это требование, которое реализуется на уровне языков и браузеров.

В итоге, освоение принципов адаптивного дизайна и базовых технологий открывает перед нами новые горизонты в разработке веб‑приложений. Мы не только создаём удобные интерфейсы для пользователей, но и строим более эффективное взаимодействие внутри команды.