vw, vh, vmin и vmax - единицы, которые всегда считаются от размера ЭКРАНА (viewport), а не от родительского элемента, как проценты. 1vw - это 1% ширины экрана, 1vh - 1% высоты, vmin и vmax берут меньшую или большую из этих двух величин.
В этом уроке
Попробуй прямо сейчас: числа реальные, их вычисляет браузер. Оба блока получили ОДИНАКОВУЮ ширину, хотя один вложен в другой - vw всегда отсчитывается от ширины экрана блокнота, а не от родителя. В прошлом уроке те же самые вложенные проценты дали бы совсем разные числа.
vw и vh: проценты от экрана, а не от родителя
1vw равен 1% ширины окна просмотра, 1vh - 1% высоты, независимо от того, в каком элементе они используются и насколько глубоко он вложен. Это принципиально отличает их от обычных процентов, с которыми только что разбирались в прошлом уроке: там 50% внутри 50% давало в сумме 25% от самого внешнего блока, потому что каждый процент считался от своего родителя. С vw и vh такого не происходит: 60vw внутри 60vw останется теми же 60vw, потому что оба значения считаются от одного и того же - ширины экрана.
.banner { width: 100vw; } - баннер шириной ровно в экран, независимо от того, насколько глубоко он вложен в разметку.
ожидание, что vw ведёт себя как проценты и зависит от родителя - это разные механизмы: % считается от родителя, vw/vh - всегда от экрана.
vmin и vmax: меньшая и большая сторона экрана
vmin берёт 1% от МЕНЬШЕЙ из двух сторон экрана (ширины или высоты), vmax - 1% от БОЛЬШЕЙ. На экране 1200×800 меньшая сторона - высота 800, поэтому 10vmin даст 80px, а 10vmax возьмёт большую сторону - ширину 1200 - и даст 120px. Практическая польза: элемент, который должен одинаково хорошо вписываться в экран и в портретной, и в альбомной ориентации (например, декоративный круг или иконка), удобно задавать именно в vmin - тогда он не вылезет за меньшую сторону экрана при повороте устройства.
.icon { width: 15vmin; height: 15vmin; } - квадратная иконка всегда вписывается в экран независимо от его ориентации.
.icon { width: 15vw; height: 15vw; } - при повороте в портретный режим, где ширина экрана резко меньше высоты, такая иконка рискует стать непропорционально маленькой или, наоборот, съесть всю ширину экрана.
Классическая проблема 100vh на мобильных
height: 100vh часто используют, чтобы блок занимал весь экран целиком - и на десктопе это работает без сюрпризов. Но на мобильных браузерах есть классическая проблема: адресная строка и панель навигации то появляются, то скрываются при прокрутке, а 100vh считается от МАКСИМАЛЬНОЙ высоты экрана - той, что получается, когда все панели уже скрыты. При первой же загрузке страницы, пока панели ещё видны, реальная видимая область оказывается меньше этих же 100vh - и часть "полноэкранного" блока уезжает под адресную строку. Решение - более новые единицы: svh (наименьшая высота, когда панели видны), lvh (наибольшая, когда скрыты) и dvh (пересчитывается в реальном времени при появлении/скрытии панелей). На 2026 год они уже практически везде поддерживаются, но для старых браузеров разумно оставлять обычный vh как запасной вариант.
.hero { height: 100vh; height: 100dvh; } - вторая строка перекрывает первую в браузерах, которые понимают dvh, а первая остаётся запасным вариантом для старых.
.hero { height: 100vh; } без запасного варианта - на части мобильных браузеров при загрузке страницы контент может оказаться частично скрыт под адресной строкой.
Частые ошибки новичков
| Ошибка | Что происходит | Как исправить |
|---|---|---|
| Путают vw/vh с процентами, ждут зависимости от родителя | vw/vh всегда считаются от размера экрана, а не от родителя | Использовать vw/vh, когда нужен размер относительно экрана, а % - когда относительно родителя |
| Задают квадратному элементу размер только в vw или только в vh | При смене ориентации экрана элемент теряет пропорции | Использовать vmin для элемента, который должен вписываться в экран любой ориентации |
| Задают height: 100vh для полноэкранного блока на мобильных | Часть контента уезжает под адресную строку браузера при первой загрузке | Использовать svh или dvh вместо простого vh для мобильных полноэкранных блоков |
| Не оставляют запасной вариант для dvh/svh/lvh | В старых браузерах, которые их не понимают, свойство просто не сработает | Указывать обычный vh первой строкой, а dvh/svh - следующей, поверх неё |
Шпаргалка
| Что нужно | Как сделать |
|---|---|
| vw | 1% от ширины экрана (viewport) |
| vh | 1% от высоты экрана (viewport) |
| vmin | 1% от МЕНЬШЕЙ стороны экрана |
| vmax | 1% от БОЛЬШЕЙ стороны экрана |
| Отличие от % | не зависят от родителя, не перемножаются при вложенности |
| Проблема 100vh на мобильных | решают svh/dvh (Baseline с июня 2025) с обычным vh как запасным вариантом |
Коротко: отвечаем на вопросы
Чем vw и vh отличаются от процентов?
Проценты считаются от размера ближайшего родителя и перемножаются при вложенности. vw и vh всегда считаются от размера экрана (viewport), независимо от того, в каком элементе и насколько глубоко они использованы, поэтому при вложенности не меняются.
Что такое vmin и vmax?
vmin - это 1% от меньшей из двух сторон экрана (ширины или высоты), vmax - 1% от большей. Они удобны для элементов, которые должны одинаково хорошо вписываться в экран независимо от его ориентации - например, для квадратных иконок.
Почему height: 100vh обрезает контент на телефоне?
100vh считается от максимальной высоты экрана - той, что получается, когда адресная строка браузера скрыта. При первой загрузке страницы, пока панели ещё видны, реальная видимая область меньше, и часть контента уезжает под них. Решают эту проблему более новые единицы svh и dvh.