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

В CSS3 были добавлены новые относительные единицы измерения, такие как vh , vw , vmin , vmax . Эти единицы вычисляются относительно размеров окна браузера. Для настольных компьютеров ширина окна браузера больше ширины области просмотра (добавляется ширина скроллбара), поэтому если для элемента установить ширину 100vw , то он выйдет за пределы html.



Рис. 1. Полноэкранное фоновое изображение с шириной 100vw

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

IE: 9.0 кроме vmax, вместо vmin используйте vm
Edge: 12.0 кроме vmax, вместо vmin используйте vm
Firefox: 19.0
Chrome: 26.0
Opera: 15.0
Safari: 6.1
iOS Safari: 8.0
Android: 4.4
Chrome for Android: 55.0

1. Единицы vh и vw

Приёмы отзывчивого веб-дизайна базируются на использовании процентных значений. Но проценты далеко не лучшее решение для каждого случая, так как они вычисляются относительно размеров ближайшего родительского элемента. Поэтому, если вы хотите использовать высоту и ширину окна браузера, лучше воспользоваться единицами vh и vw . Например, если высота окна браузера равна 900px , то 1vh будет равен 9px . Аналогично, если ширина окна браузера равна 1600px , то 1vw будет равен 16px .

1.1. Адаптивное полноэкранное фоновое изображение

Так как ширина элемента, указанная с помощью 100vw больше ширины области просмотра, то для создания полноэкранных фоновых изображений лучше использовать ширину 100% , которая будет равна ширине корневого элемента html.

Fullscreen-bg { background: url(image.jpg); background-position: center; background-size: cover; width: 100%; height: 100vh; } Рис. 2. Адаптивно полноэкранное фоновое изображение

1.2. Эффект полностраничного слайда

Чтобы сделать блок на всю высоту окна браузера, необходимо задать height: 100%; для трёх элементов — html, body и непосредственно для самого блока:

Html, body { height: 100%; } section { height: 100%; }

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

Section { height: 100vh; }

Эффект перелистывания слайдов при клике на стрелку реализуется с помощью небольшого скрипта jQuery:

JQuery(document).ready(function($) { $("nav").on("click", function() { if ($(this).hasClass("down")) { var movePos = $(window).scrollTop() + $(window).height(); } if ($(this).hasClass("top")) { var movePos = $(window).scrollTop() - $(window).height(); } $("html, body").animate({ scrollTop: movePos}, 600); }); });

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

: vw , vh , и vmin . С недавних пор dev-версия Chrome (под номером 20) тоже поддерживает их , а это дарует некоторую надежду, что и разработчики других браузеров последуют этому примеру. На самом деле, это было бы кстати, ведь это очень удобно и практично, а я попробую рассказать, почему это так.

Почему это клево?

Много причин. Вот две из них:

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

Как это работает?

Единица каждого из этих трех значений составляет 1% от размера экрана. Например, если размер экрана составляет 40 сантиметров по ширине, то 1vw равен 0.4 см.

1vw = 1% ширины окна
1vh = 1% высоты окна
1vmin = 1vw или 1vh, в зависимости от того, что меньше

Использование

О, это очень просто:

H1 { font-size: 5.9vw; } h2 { font-size: 3.0vh; } p { font-size: 2vmin; }

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

Chrome 20+ и IE 10+
Я проверял в Opera Next (12), Safari 5.2 и Firefox Beta (13) - безрезультатно.

Демо

Небольшое видео, в котором показывается использование vw:

Можно попробовать самому (убедитесь, что Ваш браузер поддерживает данные единицы измерения)

Баги

Поддержка есть в Chrome 20, но немного кривая. Когда окна браузера изменяется, шрифт не приспосабливается в соответствии с новым размером окна. Спецификация говорит:

Если высота или ширина окна изменится, они масштабируются соотвественно

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

Чтобы устранить эту проблему (разрешить изменение размеров без перезагрузки страницы), Вам необходимо вызвать перерисовку элемента. Я использовал jQuery и просто поэкспериментировал с z-index значениями каждого элемента, который вызывает перерисовку.

CauseRepaintsOn = $("h1, h2, h3, p"); $(window).resize(function() { causeRepaintsOn.css("z-index", 1); });

Не только font-size

Между прочим, это всего лишь единицы. Как em , px , что угодно. Вы можете их использовать повсеместно, дело не ограничивается только размером шрифта.

Используйте!

Нативное использование

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

H1 { font-size: 36px; font-size: 5.4vw; }

Проверка поддержки

У Modernizr пока еще нет теста для данной проверки, но вы можете проверить самостоятельно, используя небольшой скрипт на JS.

Var testEl = $("#vw-test"); var viewport = $(window); testEl.css({ width: "100vw" }); if (testEl.width() == viewport.width()) { $("html").addClass("vw-support"); } else { $("html").append("vw-unsupported"); };

Имитация функциональности с FitText.js

Эта идея заключается в том, что связывает общую ширину заголовка с шириной родительского элемента, что и делает FitText.js . Правда он делает это через Javascript, математику, span-теги и еще кучу всего. Теоретически, Вы можете запустить проверку и использовать Modernizr.load для загрузки FitText.js, если поддержки не обнаружено.

От автора: с первого показа вьюпорт единиц в CSS прошло несколько лет. Это реально адаптивные единицы измерения длины, их значение меняется под размеры окна браузера. Если вы слышали о них, но никогда не вдавались в детали, эта статья для вас.

Единицы измерения и их значение

В CSS есть 4 типа вьюпорт единиц: vh, vw, vmin и vmax.

Viewport height (vh) – основаны на высоте вьюпорта. Значение 1vh равно 1% высоты вьюпорта.

Viewport width (vw) – основаны на ширине вьюпорта. Значение 1vw равно 1% ширины вьюпорта.

Viewport minimum (vmin) – основаны на минимальной стороне вьюпорта. Если высота вьюпорта меньше ширины, значение 1vmin будет равно 1% от высоты. Точно так же если ширина меньше высоты, то 1vmin будет равен 1% от ширины вьюпорта.

Viewport maximum (vmax) – основаны на большой стороне вьюпорта. Если высота вьюпорта больше ширины, то значение 1vmax будет равно 1% от высоты вьюпорта. Если ширина вьюпорта больше высоты, то 1vmax будет равен 1% от ширины.

Давайте посмотрим, какие значения мы получим в разных ситуациях:

Если вьюпорт 1200px в ширину и 1000px в высоту, то значение 10vw будет равно 120px, а 10vh – 100px. Ширина вьюпорта больше высоты, поэтому 10vmax будет равно 120px, а 10vmin – 100px.

Если повернуть устройство, чтобы ширина стала 1000px, а высота 1200px, то 10vh будет равно 120px, а 10vw превратится в 100px. Интересно, но 10vmax так и останется 120px, потому что теперь значение определяется по высоте вьюпорта. Значение 10vmin также останется 100px.

Если сузить окно браузера до 1000px в ширину и 800px в высоту, то 10vh будет 80px, а 10vw будет 100px. Точно так же значение 10vmax станет 100px, и 10vmin – 80px.

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

В демо видно, как ширина первого дочернего элемента занимает 80% ширины от родителя. У второго дочернего элемента ширина равна 80vw, что делает его шире родителя.

Применение вьюпорт единиц измерения

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

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

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

Разберем следующий пример HTML:

a

< div class = "fullscreen a" >

< p > a < p >

< / div >

CSS ниже растянет секцию под фоновое изображение на всю ширину:

Fullscreen { width: 100%; height: 100vh; padding: 40vh; } .a { background: url("path/to/image.jpg") center/cover; }

Fullscreen {

width : 100 % ;

height : 100vh ;

padding : 40vh ;

background : url ("path/to/image.jpg" ) center / cover ;

Идеально подходящие заголовки

Вы могли слышать или даже использовать jQuery плагин FitText . С помощью этого плагина можно масштабировать заголовки таким образом, чтобы они занимали всю ширину родительского элемента. Как я сказала раньше, значение вьюпорт единиц напрямую зависит от размеров вьюпорта. То есть если указывать font-size заголовков во вьюпорт единицах, то они идеально будут подходить под каждый экран. Если изменится ширина вьюпорта, браузер автоматически изменит заголовок. Нужно лишь определить правильное первоначальное значение для font-size.

Главная проблема с font-size и вьюпорт единицами заключается в том, что размер текста будет сильно варьироваться в зависимости от вьюпорта. Например, font-size со значением 8vw сделает заголовок размером в 96px для вьюпорта с шириной 1200px, 33px для ширины в 400px и 154px для ширины вьюпорта в 1920px. Шрифт может быть, как слишком большим, так и слишком маленьким для удобного чтения. Более подробно прочитать о правильной установке размеров текста с помощью единиц измерения и функции calc() можно в замечательной статье о типографике на вьюпорт единицах .

Легкое центрирование элементов

Вьюпорт единицы могут очень сильно помочь, когда необходимо поместить элемент точно в цент экрана пользователя. Если высота элемента известна, то нужно всего лишь задать верхнее и нижнее значение свойства margin в [(100 - height)/2]vh.

Centered {

width : 60vw ;

height : 70vh ;

margin : 15vh auto ;

Что нужно помнить

Если вы решили использовать вьюпорт единицы в своих проектах, вам нужно помнить о нескольких вещах.

В CSS3 появились новые единицы измерения. (Я, кажется, уже говорил об этом. eng ) Вы уже слышали о px, pt, em и новых rem. Давайте рассмотри еще несколько: vw и vh.

Часто в макете есть элементы, которые гарантировано должны умещаться во вьюпорт браузера. В общем случае для этого используется JavaScript. Проверям размер вьюпорта и изменяем размеры элементов соответствующим образом. Если пользователь изменяет размер окна браузера, то процедура повторяется.

С помощью vw/vh мы можем устанавливать размер элементов относительно размера вьюпорта. Единицы vw/vh интересны тем, что 1vw - единица равная 1/100"ой ширины вьюпорта. Что бы присвоить элементу ширину, равную ширине вьюпорта, например, надо установить width:100vw.

Как это можно использовать

Лайтбоксы - прекрасный кандидат для использования vw и vh, так как обычно позиционируется относительно вьюпорта, однако мне кажется, что position:fixed со значениями top, bottom, left и right использовать проще, так как можно вообще не устанавливать высоту и ширину .

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

Img { max-height:95vh; }

В данном случае я устанавливаю высоту 95vh что бы оставить немного места вокруг, когда они на экране.

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

Если rem поддерживаются почти всеми основными браузерами включая IE9, то с использованием vw и vh стоит повременить. На данный момент их поддерживает только Internet Explorer 9.