Единицы viewport против процентов


Данный материал является переводом статьи:
Ire Aderinokun Viewport vs percentage units

В моей статье «О размерах шрифтов в CSS» я упоминала новые (относительно) единицы измерения. Эти единицы – vw, vh, vmin и vmax, они основаны на размере вьюпорта браузера. Их фактический размер меняется в зависимости от изменения области просмотра браузера, что делает эти единицы идеальными для адаптивного дизайна. Хотя в моем предыдущем посте я выступила против использования этих единиц для указания размеров шрифта, они могут быть очень полезны для работы с элементами макета.

##Единицы измерения viewport

Единицы измерения viewport являются относительными единицами, это означает что они не могут быть измерены объективно. Их размер определяется размером области просмотра в браузере. Существуют четыре единицы, относящиеся к области просмотра.

Название Единица Описание
Ширина Viewport vw 1/100 ширины viewport
Высота Viewport vh 1/100 высоты viewport
Минимум Viewport vmin 1/100 наименьшего значения viewport (по высоте или ширине)
Максимум Viewport vmax 1/100 наибольшего значения viewport (по высоте или ширине)

Я сконцентрирую внимание на первых двух, так как они наиболее часто используются. Во многих случаях единицы viewport (vh и vw) пересекаются с процентами в плане возможностей. Тем не менее, каждая из них имеет свои сильные и слабые стороны.

Если резюмировать, то получится следующее:

Когда имеешь дело с шириной, то лучше подходят %, а если с высотой, то лучше vh.

##Элементы во всю ширину страницы: % > vw

Как я уже говорила vw определяет размер элемента исходят из ширины viewport. Однако, браузеры рассчитывают размер с учетом места для скроллбара.

Если ширина страницы превышает ширину viewport, то появляется полоса прокрутки. Однако на деле ширина viewport больше, чем ширина элемента html

Viewport > html > body

Поэтому если вы установите ширину элемента в 100vw, то элемент выйдет за пределы html и body. в данном примере я сделала красную границу вокруг элемента html и залила разделы разными цветами.

Из-за этого нюанса делать элементы на всю ширину страницы лучше при помощи процентов, а не опираясь на ширину viewport.

##Элементы на всю высоту страницы: vh > %

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

Используя vh добиться такого эффекта достаточно просто:


.example {
	height: 100vh;
}

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

Вот несколько примеров того, как можно использовать единицы измерения vh.

##Полноэкранные фоновые изображения

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


.bg {
  position: relative;
  background: url('bg.jpg') center/cover;
  width: 100%;
  height: 100vh;
}

Аналогичным образом мы можем сделать эффект «страниц», задав каждому разделу размеры области просмотра.


section {
  width: 100%;
  height: 100vh;
}

Мы можем использовать JavaScript чтобы создать иллюзию перелистывания страниц.


$('nav').on('click', function() {

  if ( $(this).hasClass('down') ) {
    var movePos = $(window).scrollTop() + $(window).height();
  }
  if ( $(this).hasClass('up') ) {
    var movePos = $(window).scrollTop() - $(window).height();
  }

  $('html, body').animate({
    scrollTop: movePos
  }, 1000);
})

##Складывающееся изображение

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

Нам понадобится следующий код


img {
  width: auto; /* Автоматическая ширина для пропорциональности высоты */
  max-width: 100%; /* Не больше ширины родительского элемента */
  max-height: 90vh; /* Не превышая высоту viewport */
  margin: 2rem auto; 
}

##Поддержка браузерами

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

Вот как их можно решить.

Браузер Проблема Решение
iOS Safari 7.1 Могут быть баги с “vh” используйте медиа-запросы для конкретных устройств (см pburtchaell Gist)
Opera Mini 8, IE 8 не поддерживается Используйте решение pburtchaell
IE 9 Принимает “vm” вместо “vmin” Задавайте размер используя обе единицы.

.example {
width: 100vm;
width: 100vmin;
}

IE 10-Edge Не поддерживается “vmax” Используйте решение pburtchaell