На сегодняшний день различают четыре viewport-единиц:
- vw — процент от ширины вьюпорта
- vh — процент от высоты вьюпорта
- vmax — наибольшее значение viewport по высоте/ширине
- vmin — наименьшее значение viewport по высоте/ширине
В данном случае, подразумевается окно браузера, то есть 1 vw — это 1% от ширины окна браузера, а 100 vw — это уже полная ширина окна. Сконцентрируемся на первых двух, так как они наиболее часто используются.
Viewport-единицы в адаптивной типографике
Плюс viewport-единиц состоит в том, что они автоматически пересчитываются при изменении окна браузера пользователя, например при загрузке или изменении размера окна или при смене ориентации устройства. Что означает, что вам не придется менять размеры шрифта в медиа-запросах.
Рассмотрим следующий пример. В коде ниже мы меняем размер шрифта с 16px на 20px, при достижении окна 800px.
1
2
3
4
5
6
7
8
9
10
|
// Используется SCSS
html {
font-size: 16px;
@media (min-width: 800px) {
font-size: 20px;
}
}
|
Здесь, когда размер окна достигает 800px, размер шрифта меняется с 16px до 20px. Такой вариант мы использовали долгое время и это считается нормальным.
Иногда необходимо добавить ещё один медиа-запрос для указания среднего значения размера шрифта, чтобы всё отображалось как надо:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
// Используется SCCS
html {
font-size: 16px;
@media (min-width: 600px) {
font-size: 18px;
}
@media (min-width: 800px) {
font-size: 20px;
}
}
|
Можно конечно использовать еще больше медиа-запросов , но это уже будет слишком. Но что, если вы хотите получить такой же результат, но без лишних медиа-запросов, без лишнего кода? Вот тут-то viewport-юниты и приходят к нам на помощь. Посмотрим на следующий код:
1
|
html { font—size: 3vw; }
|
Здорово, правда?
Но есть проблема. Если вы укажете размер шрифта 3vw, как в примере выше, то на экране шириной в 320px (мобильные устройства) размер шрифта будет равен 10px ,а на экране шириной в 1440px (ноутбук) будет 43px . Это слишком маленькое и слишком большое значения. Однако, есть способ решения этой проблемы: установим минимальное значение размера шрифта и будем увеличивать его при помощи небольшого viewport-значения, используя calc().
Вот пример:
1
|
html { font—size: calc(18px + 0.25vw) }
|
Круто, не так ли? Этот способ от Mike Riethmuller, а вот и его статья «Precise control over responsive typography». К сожалению, это решение не работает в браузере Safari для Mac. Но исправить это можно следующим образом. Мы совместим использование процентов и viewport-юнитов и это заработает в Safari:
1
|
html { font—size: calc(112.5% + 0.5vw) }
|
Отлично! Теперь мы реально можем отказаться от использования em-ов, rem-ов и медиа-запросов? Не могу дождаться момента, когда попробую!
Следующая интересная задача — указание в viewport-юнитах размеров заголовков (h1-h6).
Размеры других элементов в viewport-единицах
Первое что я попробовал сделать это создать заголовок h1, который в два раза больше основного шрифта. Но оказалось не так всё просто. Я взял значение, указанное в font-size для html, умножил его на два. Но получилось, что размер заголовка стал больше, чем он должен был быть. Оно должно было быть 40px, то есть в два раза больше основного текста.
Давайте рассмотрим это на примере и с другими числами. Представим, что размер нашего окна равен 800px , а значение шрифта — 16px.
- Итак, сначала вычисляется значение font-size для html: 112.5% от 16px = 18px (112.5/100 * 16px);
- Затем значение, указанное в vw: 800px * 0.25 ÷ 100 = 2px;
- Далее значения просто складываются: 18px + 2px = 20px;
Теперь используем этот же метод для вычисления размера нашего заголовка. Обратите особое внимание на значение 112.5% в вычислении:
- 112.5% для h1 превращается в 22.5px (112.5/100 * 20px);
- 0.25vw равно 2px (800px * 0.25 ÷ 100);
- И в итоге мы получаем 49px ((22.5px + 2px) * 2);
Но 49px не равно 40px! Проблема заключается в наследовании значения font-size для h1 от html. Есть два варианта решения проблемы.
Первый вариант — заменить 112.5% на 100% для h1:
1
|
h1 { font—size: calc((100% + 0.25vw) * 2) }
|
Второе вариант — убедитесь, что размер шрифта не наследуется элементами:
1
2
|
h1 { font—size: calc((100% + 0.25vw) * 2) }
p { font—size: calc((100% + 0.25vw)) }
|
Но эти варианты меня не очень устраивали. В итоге, я решил использовать rem и em.
1
2
|
html { font—size: calc(112.5% + 0.25vw) }
h1 { font—size: 2em; }
|
Viewport-единицы в межстрочных интервалах
Как вы могли заметить viewport-юниты используются только для установки значения для корневого элемента html, а во всех остальных случаях мы всё ещё используем rem-ы и em-ы. Это означает, что вы можете использовать их так, как я описывал в своей статье «Everything I know about Responsive Web Typography».
И кстати, была ещё одна проблема, которую я решил: «Как сделать так, чтобы размер шрифта был 20px при размере окна браузера в 800px?». Вопрос можно сократить до слова — «Точность». Другими словами говоря , как я могу быть точно уверен, что размер шрифта станет таким, каким надо, при увеличении окна до 800px?
Точность
Ну что ж, Майк решил эту проблему. Мы просто возьмём его формулу и разберём её.
Итак, цели следующие:
- При viewporte в 600px font-size равен 18px;
- При viewporte в 1000px font-size равен 22px;
Первое что мы cделаем — преобразуем меньшее значение 18px в проценты: 18/16 * 100% = 112.5%.
Теперь мы вычисляем количество vw. Это немного сложнее. Возьмем разницу между font-size (22px — 18px), поделим на разницу viewport-а (1000 — 600) и умножим на 100vw — меньшее значение viewport-а (100vw — 600px).
Вот так это выглядит:
1
2
3
|
html {
font—size: calc(112.5% + 4 * (100vw — 600px) / 400)
}
|
Вам может показаться все это немного сложным, но как только вы поймете, то сможете упростить используя SASS-миксин. А вот уже Indrek Paas сделал это здесь.
Супер точность
А что если вы захотите чтобы шрифт увеличивался с разной скоростью в разных промежутках?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
// Используется SCCS
html {
font-size: 100%;
// Увеличиваем шрифт на 1px каждые 100px от 600px до 1000px
@media (min-width: 600px) {
font-size: calc(112.5% + 4 * (100vw — 600px) / 400)
}
// Увеличиваем шрифт на 0.5px каждые 100px от 1000px до 2000px
@media (min-width: 1000px) {
font-size: calc(137.5% + 5 * (100vw — 1000px) / 1000)
}
}
|
Но в реальной жизни вы, скорее всего,вряд ли будете увеличивать шрифт с разной скоростью. Поэтому вот более реалистичный вариант:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
// Используется SCSS
html {
font-size: 100%;
// Увеличиваем размер шрифта на 1px каждые 100px от 600px и выше
@media (min-width: 600px) {
font-size: calc(112.5% + 4 * (100vw — 600px) / 400)
}
// Устанавливаем размер шрифта в 22px после 1000px
@media (min-width: 1000px) {
font-size: calc(137.5%)
}
}
|
Ну и, под конец, главный вопрос: «Могу ли я это всё использовать в реальных проектах?»
Возможно. Я проработал с viewport-юнитами достаточное время. Прежде чем пускать всё это в продакшн необходимо:
- Сделать SASS-миксин;
- Протестировать в разных браузерах на наличие каких-нибудь багов;
Заключение
Итак, мы поговорили об использовании viewport-юнитов для указания размера шрифтов. Viewport-единицы могут быть очень полезными, поскольку они автоматически пересчитываются при изменении размера окна.
В процессе использования я заметил, что лучше всего их использовать только для html. Для всего остального есть MasterCard лучше всё же использовать em-ы и rem-ы.
Источник: zellwk.com