Динамические единицы вьюпорта: dvh, lvh и svh

Прощай, обрезанный футер: Укрощаем вьюпорт с помощью dvh, lvh и svh

Признайся, сколько раз ты проклинал мобильный Safari? Ты верстаешь идеальный полноэкранный лендинг, ставишь секции height: 100vh, открываешь на iPhone и… твоя главная кнопка «Купить» стыдливо прячется под динамической панелью браузера. Пользователь пытается скроллить, панель то уменьшается, то увеличивается, контент прыгает, а ты сидишь и думаешь: «Ну почему 100% высоты экрана — это не 100% того, что я вижу?».

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

Как мы страдали раньше: Эпоха костылей и JavaScript-хаков

До появления современных единиц измерения у нас было два пути, и оба вели в никуда. Первый — смириться. Второй — городить огород из JavaScript. Мы писали скрипты, которые высчитывали window.innerHeight, делили его на 100 и прокидывали это значение в CSS-переменную --vh. Выглядело это примерно так:


let vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty('--vh', `${vh}px`);

// И не забудь навесить обработчик на resize, чтобы всё не поехало!
window.addEventListener('resize', () => {
  let vh = window.innerHeight * 0.01;
  document.documentElement.style.setProperty('--vh', `${vh}px`);
});

В CSS мы использовали это через height: calc(var(--vh, 1vh) * 100). Это работало, но вызывало микро-лаги при ресайзе и заставляло браузер лишний раз пересчитывать лейаут. Точно так же, как мы когда-то мучились с сетками до появления гридов (кстати, если хочешь копнуть глубже, почитай про скрытые возможности CSS Grid Layout), проблема с высотой вьюпорта требовала нативного и элегантного решения.

Как делать правильно в 2026 году

Спецификация CSS Values and Units Module Level 4 подарила нам три новые суперсилы, которые теперь поддерживаются всеми актуальными браузерами. Теперь нам не нужны скрипты, чтобы понять, сколько места на экране осталось на самом деле.

  • svh (Small Viewport Height): Минимально возможная высота вьюпорта, когда все интерфейсы браузера (адресная строка, табы) максимально развернуты. Это твой «безопасный» вариант.
  • lvh (Large Viewport Height): Максимальная высота, когда интерфейсы браузера скрыты. По сути, это старый добрый vh, каким он задумывался изначально.
  • dvh (Dynamic Viewport Height): Самая умная единица. Она динамически меняется прямо в процессе скролла, подстраиваясь под текущее состояние интерфейса браузера.

Именно dvh — это тот самый «золотой стандарт» для создания Hero-секций. Он гарантирует, что твой контент всегда будет занимать ровно столько места, сколько видит пользователь в данный момент. Это так же важно для современного UI, как и грамотная адаптивная типографика с помощью функции clamp(): вы просто один раз задаете правила, а браузер берет всю рутину на себя.

Готовый сниппет кода

Вот как должен выглядеть современный полноэкранный блок, который не «сломается» в мобильном Safari и при этом будет иметь фоллбек для старых систем:


.hero-section {
  /* Фоллбек для старых браузеров (Internet Explorer, мы тебя помним) */
  height: 100vh;
  
  /* Современный стандарт: динамическая высота */
  height: 100dvh;
  
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background: linear-gradient(135deg, #6e8efb, #a777e3);
  color: white;
  padding: 2rem;
  box-sizing: border-box;
}

.hero-title {
  font-size: clamp(2rem, 5vw, 4rem);
  text-align: center;
}

Частая ошибка новичков

Главный подвох dvh — это его избыточное использование. Помни, что dvh заставляет браузер пересчитывать размеры элементов при каждом изменении состояния интерфейса (когда пользователь начинает скроллить и адресная строка уезжает вверх). Если ты привяжешь к dvh размер шрифта или сложные параметры внутренних отступов у сотен элементов на странице, ты можешь получить неприятные «дергания» контента.

Совет от Senior-разработчика: Используй dvh только для контейнеров верхнего уровня (Hero-блоки, модальные окна, боковые меню). Для всего остального внутри этих контейнеров лучше использовать проценты или обычные относительные единицы. И всегда прописывай 100vh первой строкой как фоллбек — CSS просто проигнорирует dvh, если браузер его не понимает, и твой макет не развалится.

🔥 Больше фишек, готовых сниппетов и передовых подходов к CSS мы публикуем в нашем Telegram-канале. Подписывайтесь, чтобы не пропустить!

🚀 Прокачай свой код

Готовые CSS-сниппеты, разбор продвинутых фишек и эксклюзивные материалы — в нашем Telegram-канале.

Подписаться
error: Content is protected !!
Прокрутить вверх