Ты наверняка не раз ловил раздражающий визуальный дефект: открываешь страницу интернет-магазина или каталог статей, начинаешь листать список, подгружается очередная порция карточек — и весь макет внезапно дергается влево. Кнопки смещаются, заголовки перескакивают, а если в этот момент попытаться нажать на ссылку, курсор легко промахивается мимо цели.
Виновник этого хаоса — обычная полоса прокрутки, внезапно появившаяся у края окна браузера.
Почему макет дергается и при чем тут операционная система
В настольных операционных системах вроде Windows и многих дистрибутивах Linux при использовании мыши браузеры отрисовывают так называемые классические полосы прокрутки. В отличие от мобильных устройств или тачпадов macOS, где скроллбар плавает полупрозрачным слоем поверх страницы, классический скроллбар физически отъедает от ширины контейнера от 12 до 17 пикселей.
Как только содержимое страницы превышает высоту окна, браузер вынужден мгновенно сжать ширину доступной области верстки, вызывая скачок макета. В веб-аналитике этот сдвиг напрямую ухудшает метрику CLS (Cumulative Layout Shift) из набора Google Core Web Vitals, что негативно сказывается на ранжировании сайта.
Многие фронтендеры, работающие на MacBook, годами даже не подозревали о масштабе проблемы у своих пользователей. На macOS оверлейные скроллбары не занимают места в потоке документа, и страница выглядит идеально, пока ее не откроют на рабочем компьютере с Windows.
Раньше разработчикам приходилось городить сомнительные костыли:
- Принудительно включать
overflow-y: scroll, из-за чего на коротких страницах вечно маячила неактивная бледно-серая полоса; - Высчитывать разницу
100vw - 100%с отрицательными внешними отступами через CSScalc(); - Писать скрипты на JavaScript, измеряющие ширину системного скроллбара при загрузке DOM.
Декларативное спасение: scrollbar-gutter
К счастью, спецификация W3C CSS Overflow Module Level 3 подарила нам чистое и стандартизированное решение — свойство scrollbar-gutter.
По спецификации желоб полосы прокрутки (gutter) — это зарезервированное пространство между внутренним краем границы (inner border edge) и внешним краем внутреннего отступа (outer padding edge) элемента. Если скроллбара нет, это пространство просто окрашивается фоном родительского контейнера.
Синтаксис свойства предельно лаконичен:
/* Базовый контейнер со стабильным резервированием места */
.scroll-container {
max-height: 28rem;
overflow-y: auto;
scrollbar-gutter: stable;
}
Значение stable указывает браузеру: заранее выдели пустое место под полосу прокрутки у правого края, даже если контент сейчас целиком помещается на экране. Когда данных станет больше и появится скроллбар, он плавно займет уже подготовленный для него желоб, а ширина текста и соседних блоков не сдвинется ни на один пиксель.
Идеальная симметрия с both-edges
А что делать, если твой макет строго центрирован или состоит из нескольких колонок, где одна колонка статична, а вторая динамически прокручивается?
Если применить просто stable, резерв места появится только справа (в языках с направлением слева направо), и центральная ось страницы слегка съедет. Для таких случаев в спецификацию добавили значение both-edges:
/* Симметричное резервирование для идеального центрирования макета */
.main-wrapper {
max-width: 72rem;
margin-inline: auto;
overflow-y: auto;
scrollbar-gutter: stable both-edges;
}
/* Синхронизация соседних колонок */
.sidebar {
overflow: hidden;
scrollbar-gutter: stable;
}
.content-feed {
overflow-y: auto;
scrollbar-gutter: stable;
}
Значение both-edges указывает браузеру выделить зеркальное пустое пространство и у противоположного края. В результате макет остается безупречно отцентрированным при любых сценариях прокрутки.
Чтобы увидеть реальное поведение scrollbar-gutter на Mac, открой системные настройки macOS: «Рабочий стол и Dock» -> «Показывать полосы прокрутки» и переключи тумблер в режим «Всегда». Это сымитирует классический Windows-скроллбар прямо в твоем браузере.
Свойство получило статус Baseline Newly Available после того, как в декабре 2024 года вышла поддержка в Safari 18.2 (движки Chromium и Firefox поддерживали его еще раньше). Сегодня это надежный инструмент, позволяющий одной строкой стилей сделать поведение интерфейса предсказуемым и спокойным.
