Адаптивный сайт и медиа-запросы

Адаптивный сайт — сайт, которым удобно и приятно пользоваться на любом устройстве.

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

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

Иногда адаптивную верстку путают с резиновой.

Резиновая вёрстка – верстка, обеспечивающая изменение размера сайта под разные устройства, растягивая его или сжимая. Для достижения этого эффекта используют относительные единицы измерения – проценты.

В данном случае советуется использовать max-width и min-width, чтобы сайт был удобно читаемый. Длинные строки текста во весь экран с разрешением 3840px – не лучшее решение.

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

Это довольно широкая тема, так что рассмотрим пока  лишь медиа-запросы.

Что такое медиа-запросы

Медиа-запросы (Media queries) — это модуль CSS, который определяет выражения, позволяющие адаптировать вид для различных устройств, без изменения самого контента.

Синтаксис медиа-запросов

Правило @media связывает набор операторов, определенных в css блоке с условием, называемым медиа-запросом (media query).

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

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

@media all and (min-width: 24em) {
  body {
    margin: 0;
    border: 3px solid red;
  }
}

В данном случае условие: all and (min-width: 24em) , следовательно, данное правило применяется для всех браузеров, размер которых больше 24em.

all — медиa-тип, а (min-width: 24em) проверка конкретной характеристики страницы браузера.

Актуальные на данный момент медиа-типы

all Подходит для всех устройств
screen Прежде всего предназначен для цветных экранов
print Предназначен для страничных материалов и документов, просматриваемых на экране в режиме предварительного просмотра печати.
speech

 

Предназначен для устройств основанных на речевом синтезе

Наиболее популярные медиа характеристики

Атрибут Результат
min-width Правило применяется к браузеру, ширина которого больше или равна значению, указанному в запросе.
max-width Правило применяется к браузеру, ширина которого меньше или равно значению, указанному в запросе.
min-height Правило применяется к браузеру, высота которого больше или равна значению, указанному в запросе.
max-height Правило применяется к браузеру, высота которого меньше или равно значению, указанному в запросе.
orientation=portrait Правило применяется к браузеру, высота которого не меньше его ширины.
orientation=landscape  Правило применяется к браузеру, ширина которого больше высоты.

Что лучше использовать в медиа-запросах min-width или max-width?

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

Логические операторы в медиа-запросах

Для написания составных медиа-запросов мы можем использовать логические операторы.
Например, оператор and объединяет два запроса:

@media (min-width: 700px) and (orientation: landscape) { ... }

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

.@media (min-width: 700px), handheld and (orientation: landscape) { ... }

Оператор not  применяется ко всему запросу и возвращает true, если запрос вернул false.
Т.е. запрос обрабатывается таким образом:

@media not (all and (monochrome)) { ... }

Если нужно скрыть @media правило от старых браузеров, то используют оператор only:

@media only all and (not handheld) { ... }

Мета-тег Viewport

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

<meta name="viewport" content="width=device-width">;

В данном случае мы говорим браузеру, чтобы он сделал ширину просмотра равной ширине экрана устройства

Какие единицы измерения использовать в медиа-запросах?

Сначала рассмотрим варианты

Пиксели

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

Определять font-size в px не желательно, так как пользователи не могут изменить шрифт через настройки браузера. Например, пользователь с плохим зрением, может захотеть увеличить шрифт. Он идет в настройки браузера, меняет размер шрифта со значения ‘Средний’ на “Крупные” и ожидает, что все его любимые ресурсы теперь раз и навсегда будут отображаться с увеличенным шрифтом. Однако, ничего не происходит, так как многие до сих пор указывают размер шрифта в px.

Em

С помощью em шрифт назначается динамически.
1em = размеру шрифта родителя элемента. Если нигде на странице шрифт не обозначен, то берется значение в браузере по умолчанию.
Допустим, оно равно 16px. Значит 1em = 16px, а 2em = 32px. Т.е. по сути мы умножаем значение em на впереди стоящую цифру. Для того, чтобы рассчитать em эквивалентное определенному значению px можно воспользоваться формулой:

em = желаемый размер элемента в px / font-size родителя в пикселях

А можно воспользоваться специальным онлайн калькулятором.

Для удобства можно ставить у body font-size 62.5%, что в случае шрифта по умолчанию 16px будет давать 10px.
В таком случае 8px=0.8em, 12px = 1.2em и т.д.
Относительность em помогает не хило уменьшить количество кода в media request, так как вместо прописывания каждого нового значения в px, достаточно прописать значение em для html, остальные элементы относительно подстроятся под родителя.

Рассмотрим два примера.

Шрифт в px

html { font-size: 16px; }
h1 { font-size: 33px; }
h2 { font-size: 28px; }
h3 { font-size: 23px; }
h4 { font-size: 19px; }
small { font-size: 13px; }
.box { padding: 20px; }

@media screen and (min-width: 1400px) {
html { font-size: 20px; }
h1 { font-size: 41px; }
h2 { font-size: 35px; }
h3 { font-size: 29px; }
h4 { font-size: 24px; }
small { font-size: 17px; }
.box { padding: 25px; }
}

Шрифт в em

html { font-size: 1em; }
h1 { font-size: 2.074em; }
h2 { font-size: 1.728em; }
h3 { font-size: 1.44em; }
h4 { font-size: 1.2em; }
small { font-size: 0.833em; }
.box { padding: 1.25em; }

@media screen and (min-width: 1400px) {
   html { font-size: 1.25em; }
}

Разница заметна, но использовать em где-то кроме размера шрифта, не всегда бывает разумно. Зачем вам зависимость от шрифта, который заказчик захочет вдруг увеличить?
Важным моментом является, что для расчёта em берется значение родительского шрифта, т.е. в том случае если мы имеем стили

body {
   font-size: 62.5%; /* font-size 1em = 10px on default browser settings */
}
span {
   font-size: 1.6em; /* 1.6em = 16px */
}

а структуру html



<div>
   <span>Outer <span> inner </span> outer </span>
</div>


то на вложенный span будет оказывать влияние родительский span.
Рассчитаем inner = 1.6 em * 1.6 em. Следовательно, внутренний span будет иметь шрифт 2.56em. Вряд ли мы к этому стремились.
Называется такой эффект многокомпонентность.(compounding)

Rem

Rem единицы введены для решения проблемы многокомпонентности. Они аналогичны em, за исключением того, что значение рассчитывается относительно корневого элемента html, а не родителя.
Таким образом, с использованием rem, размер вложенного span останется идентичным span родительскому

.body {
   font-size: 62.5%; /* font-size 1rem = 10px on default browser settings */
}
span {
   font-size: 1.6rem; /* 1.6rem = 16px */
}

Минус rem в том, что эта единица не поддерживается IE 8, 9.
Но в данном случае мы можем сначала указать значение в px, зачем в rem.

html { font-size: 62.5%; }
body { font-size: 16px; font-size: 1.6rem; }

Полезные ссылки

Поддержка медиа-запросов
Использование медиа-запросов
Про viewport

Хотите быть в курсе новых статей?