Вёрстка адаптивного макета

Вы собрались верстать макет сайта. Но вот первый вопрос: какую выбрать ширину макета? Несколько лет назад популярны были резиновые макеты, занимающие всю ширину экрана. Но в современном Вебе применение исключительно «резины» в 40% случаев приведёт к неприятному эффекту: на телефонах с шириной экрана 400px всё «слипнется», а на широких мониторах (свыше 1300px) будет трудно находить начало новой строки текста после окончания предыдущей.

В Метрике для одного из сайтов сконструировал отчёт на выборке в 400 000 посетителей (Рунет). Только 60% визитов отличились тем, что их ширина окна браузера была в диапазоне 400px — 1300px. У вас могут быть другие значения.

«Резину» использовать можно, но в установленных границах (CSS-свойства min-width и max-width понимают все современные браузеры). В условиях такого широкого диапазона клиентской ширины окна браузера хорошим тоном является вёрстка адаптивного макета.

В идеале, адаптивный макет должен иметь 4 варианта отображения, соответствующие 4-м типам устройств веб-сёрфинга:

  • маленькие экраны: телефоны (до 767px);
  • небольшие экраны: планшеты (от 768px до 991px);
  • нормальные экраны: ноутбуки, домашние компьютеры (от 992px до 1199px);
  • широкие экраны: компьютеры, телевизоры (от 1200px).

Числа не являются каноническими и всего лишь соответствуют техническим тенденциям на данный момент. Стандартов адаптивной вёрстки я не нашёл. Значения взяты с сайта Bootstrap — движка адаптивного макета на базе HTML5 и CSS3 (оригинал — английский).

Эти ориентировочные цифры позволят нам ответить на вопрос, заданный вначале.

Какую выбрать ширину макета?

Но ответ будет не один, а четыре:

  • маленькие экраны — 95% ширины;
  • небольшие экраны: — 750px;
  • нормальные экраны: — 970px;
  • широкие экраны: — 1170px.

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

Исходя из этих значений делаем выводы о ширине колонок. На маленьких экранах колонка будет одна, расположится по центру экрана и займёт 95% его ширины. На небольших экранах вы сами решаете насчёт целесообразности дополнительной колонки. Я бы сделал узкий сайдбар (не больше 250px). На нормальных и широких экранах можно сделать широкий сайдбар (300px и более). Если зарабатываете на Adsense, в такой сайдбар хорошо поместится «вкусный» вертикальный блок 300×600. На широких экранах можно сделать 2 сайдбрара.

Как выполнить адаптивную вёрстку?

Адаптивный веб-дизайн (англ.: responsive Web design) обеспечивает смотрибельность и удобочитаемость сайта на любых устройствах. В двух словах, улучшает юзабилити. Ключевое слово «адаптивный» значит, что дизайн «приспосабливается» под устройство, на котором отображается. Т.е. сайт выглядит по-разному, но наиболее подходящим образом для того устройства, на котором отображается.

HTML5 & CSS3 & JS фреймворки для адаптивной вёрстки

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

  • требуется время на освоение;
  • макет получается перегружен стилями и скриптами, большую часть которых вы даже использовать не будете;
  • в Интернете есть неоднозначные высказывания на счёт кроссбраузерности такого решения.

CSS @media queries

Я считаю, что лучшее решение — самое простое. Потому я воспользовался CSS-возможностью media queries, поддержку которой обеспечивают все современные браузеры. А для поддержки браузерами IE младше 9-й версии можно воспользоваться такой хитростью (добавить в <head>):

<!--[if lt IE 9]>
<script src="http://css3-mediaqueries-js.googlecode.com/svn/trunk/css3-mediaqueries.js"></script>
<![endif]-->

Скрипт загрузят только браузеры IE младше 9-й версии, для остальных браузеров это просто комментарий в HTML-коде.

Media queries в действии

Для примера я указал правила только для #layout. Это контейнер <div id="layout"> ... </div>, в который «обёрнут» весь отображаемый контент сайта. Т.е. ширина блока #layout соответствует ширине макета. Также для простоты я манипулирую только шириной макета — вы можете применять любые правила CSS.

/* CSS-правила по-умолчанию
Для обычных экранов и браузеров без поддержки CSS @media */
#layout { width: 970px; margin: 0 auto; }
...
/* CSS-правила для телефонов */
@media screen and (max-width: 767px) {
#layout { width: 95%; }
...
}
/* CSS-правила для планшетов */
@media screen and (min-width: 768px) and (max-width: 991px) {
#layout { width: 750px; }
...
}
/* CSS-правила для широких экранов */
@media screen and (min-width: 1200px) {
#layout { width: 1170px; }
...
}

Там, где в коде многоточие, вы напишите любые свои CSS-правила. В частности, управление размером шрифтов, отступов, отображением и скрытием сайдбаров, шириной колонок и прочее.

Принцип заключается в следующем. Сначала браузер учитывает те стили, которые указаны в верхнем разделе CSS-файла, названном мной «CSS-правила по-умолчанию». Затем идут конструкции @media screen and (...) { ... }, которые заставят браузер учесть новые стили, если выполнится условие вхождения ширины экрана в указанный диапазон. Если же используется какой-то браузер без поддержки media queries (редкий случай) — он просто проигнорирует эти инструкции, отобразив «CSS-правила по-умолчанию» (так решается отсутствие кроссбраузерной поддержки). Потому по-умолчанию я указал правило, соответствующее ширине обычных экранов: ширина макета 970px.

Для телефонов (имеются ввиду любые устройства с шириной экрана до 767px) браузер применит CSS-правило, согласно которому ширина макета станет 95% (от ширины экрана). А назначенное ранее для #layout правило margin: 0 auto; послужит тому, чтобы макет выровнялся посередине окна, оставив по краям отступы. Для планшетов ширина макета будет 750px, а для широких экранов — 1170px.

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

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

Хитрости и тонкости адаптивной вёрстки

Браузеры мобильных устройств обычно стараются подогнать ширину сайта под ширину экрана. Даже если у вашего макета ширина 1500px, браузер Android или Chrome подгонит размер сайта под размер экрана. Конечно, при использовании media queries тут можно получить неожиданный результат. Чтобы запретить браузеру масштабировать сайт, если мы сами управляем размером сайта, нужно прописать в <head> инструкцию:

<meta name="viewport" content="width=device-width, initial-scale=1">

А как быть с картинками, которые вы загружаете на сайт в размере 600px в ширину? Как управлять их масштабом при уменьшении контентной колонки до 500px (например, для планшетов)?

Достаточно в общих правилах написать:

img {
max-width: 95%;
height: auto;
}

И тогда картинки займут не более 95% ширины контейнера, в котором находятся.

Разные рекламные блоки в зависимости от ширины контента

Одним из минусов адаптивного макета считают то, что один и тот же HTML-код страницы отправляется всем посетителям. Точнее, минусом это является лишь в некоторых аспектах — например, в вопросе размещения рекламы. К счастью, JS-код позволяет обходить это ограничение. Решению посвящена отдельная статья: Рекламный блок в зависимости от разрешения экрана в адаптивном дизайне

Обнуление и нормализация предустановленных стилей

При вёрстке любого дизайна необходимо учесть, что у каждого браузера есть предустановленные стили для многих элементов. Например, даже если мы не укажем никаких CSS-правил, заголовки будут жирными и крупными, между абзацами будет отступ, цитата отобразится курсивом и т.д. Только предустановленные стили разных браузеров отличаются. Если мы пишем свои стили, дополняя предустановленные в своём браузере, велика вероятность, что в другом браузере на другой системе сайт будет выглядеть иначе. Перед тем, как писать свои CSS-правила, предустановленные стили надо обнулить и нормализовать (привести к единому виду). У меня для этого служат 2 CSS-файла:

Эти файлы подключаю в начале основного style.css таким образом:

@import url("reset.css");
@import url("normalize.css");

Import необходимо реализовать до любых CSS-инструкций. В дальнейшем, чтобы немного ускорить загрузку работающего сайта, все файлы CSS можно объединить в один и сжать. Сервис csscompressor.com сжал normalize.css в 4 раза, потому что в этом файле много комментариев.

Преобразование меню в список на маленьких экранах

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

<ul id="menu-big-screens">
<li><a href="/item1">Пункт 1</a></li>
...
</ul>
<select id="menu-small-screens">
<option value="" selected="selected">Выберите пункт</option>
<option value="/item1">Пункт 1</option>
...
</select>

Затем в CSS просто отображаем один из вариантов в зависимости от ширины экрана:

/* CSS-правила по-умолчанию */
#menu-small-screens { display: none; }
...
/* CSS-правила для телефонов */
@media screen and (max-width: 767px) {
#menu-big-screens { display: none; }
#menu-small-screens { display: block; }
...
}

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

Преобразование двухколоночного макета в одноколоночный на маленьких экранах

Создание многоколоночного макета (с фиксированной ширины сайдбаром и «резиновым» контентом, с двумя сайдбарами и т.д.) — тема отдельной статьи. Для простоты в качестве примера предлагаю двухколоночный макет.

Выше я уже показывал адаптивные CSS-правила для #layout — слоя, в который обёрнут контент. Не буду усложнять код повторением. Просто имейте ввиду, что описанный ниже код обёрнут в слой layout, и для layout описаны CCS-правила.

Назовём основную колонку #content, а боковую колонку #sidebar. HTML:

<div id="content">
<!-- содержимое основной колонки -->
</div>
<div id="sidebar">
<!-- сайдбар -->
</div>

Главное тут — расположить сайдбар под контентом, чтобы на маленьких экранах он отображался ниже, а не выше. А хотите вы расположить боковую колонку на больших экранах слева или справа — за это отвечает CSS:

/* CSS-правила по-умолчанию */
#content {
width: 70%;
float: left;
}
#sidebar {
width: 27%;
float: right;
}
...
/* CSS-правила для телефонов */
@media screen and (max-width: 767px) {
#content, #sidebar {
width: 95%;
margin: 0 auto;
float: none;
}
}

Макет в этом примере представляет собой левую колонку 70% ширины и сайдбар справа 27% ширины. Между ними расстояние в 3% достаточно, чтобы визуально не «слипались». Кстати, если думаете, что указаны проценты ширины окна — это не совсем так. На самом деле, это проценты ширины родительского слоя. Как уже писал, на практике всё содержимое <body> обёрнуто в слой layout. Т.о. если задам для layout ширину 1000px, то content будет размером 700px, а sidebar — 270px.

Как вы уже догадались, магия смещения сайдбара под контент на телефонах заложена в конструкции @media. При ширине окна меньше 768px контент и сайдбар прекращают располагаться слева и справа и занимают 95% ширины с расположением по центру (за это отвечает правило margin: 0 auto).

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

Запись опубликована в рубрике Web-мастеринг с метками , , . Короткая ссылка для добавления в закладки: Вёрстка адаптивного макета.

9 Responses

  1. x64 говорит:

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

    На мой взгляд, главная «проблема» адаптивности — нужно чётко представлять, какой элемент куда девается при изменении размеров экрана. И просто офигенно, если всё и правда подгоняется под заранее определённые числа. А то встречаешь и 900px, и 1280px, и 320px, и 640px... Фиг поймёшь, где что расположено и как отобразится код при изменении размеров окна браузера.

    По поводу meta/viewport встречал такой вариант:

    width=device-width, initial-scale=1.0, maximum-scale=1

    т. е. добавляется maximum-scale. Может ли влиять его отсутствие — не знаю.

    Кстати, есть ещё один интересный класс устройств — новый мак с ретиной и разрешением 5к. Покупать его для того, чтобы только потестировать, рука не поднимется. А для работы обычный ноутбук или ПК обойдутся гораздо дешевле. Так что мне остаётся лишь догадываться, как там отображаются сайты у «щасливых» обладателей маков.

    • Павлуха говорит:

      На счёт viewport-а — мало информации в Рунете. И в Бурже подробности практического использования только на вебмастерских форумах. Основная идея того, что удалось найти, наиболее полно описана тут:

      html5.by/blog/viewport-meta-tag/

      Как раз в качестве наиболее распространённого варианта указан тот, который у меня в статье. width=device-width, initial-scale=1 — указание мобильному браузеру отобразить сайт на всю ширину экрана и не масштабировать. maximum-scale=1 — это тоже указание «не масштабировать» (при значении «1»), но использовать его не рекомендуется, если точно не уверен, зачем это нужно. В Бурже много вопросов о проблемах в работе maximum-scale. И вообще, как я понял, параметр этот полезен для создания мобильных веб-приложений, где надо запретить браузеру и юзеру что-либо делать с масштабом страницы.

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

  2. Марина говорит:

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

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

  3. Павел, то, что Вы пишете, для меня высший пилотаж. Понимать — многое понимаю, но за реализацию не взялась бы никогда. Учиться и набивать руку поздно. А так, как ответ на мой детский лепет о ширине шапки, все понятно. Сейчас у меня на новом сайте шапка зафигачена, извините, вообще огромная, но дизайн шаблона адаптивный, потому все width откроются, как надо.

    • Павлуха говорит:

      Надежда, вы способны на большее, чем сами думаете

      • Павел, Вы заставите меня начать жалеть, что так поздно родилась. Да и уже жалею тихонько. :) Просто невозможно постичь все! Вчера, например, пришлось восстанавливать сайт самой. Знаете, как ручки-ножки тряслись, когда удаляла на сервере папки и файлы?! Естественно, сначала скачала их на комп. А толку? Я же не знаю, что в них должно быть, а что лишнее.

  4. Арутр говорит:

    а что насчет размеров шрифтов? нужно использовать em??

    • Павлуха говорит:

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

      Как правило, удобно бывает указать базовый размер шрифта (например, для body) в px или pt, а остальные — в относительных величинах (например, 70% равнозначно 0.7em). Тогда, в зависимости от ширины экрана, достаточно будет изменить размер базового шрифта, чтобы остальные подстроились автоматически.

  5. Василий говорит:

    Смысл писать в статье код если я не могу его скопировать? Или Вы думаете, что его кто-то будет перепечатывать?

    Зачем вообще запрет на копирование? боитесь текст украдут? Тот кто не знает как это обойти, тому и текст не нужен, да и Ctrl+U еще не кто не отменял

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Иногда ваш комментарий может не отобразиться сразу после публикации - будто пропал. Не волнуйтесь, он не пропадёт и появится потом, после моего одобрения.