Скроллбар (scrollbar, полоса прокрутки) — это простой, но эффективный механизм, который действует как основное средство, с помощью которого можно просматривать большие документы. Но это — далеко не всё, на что способны полосы прокрутки! Эти скромные рабочие лошадки ещё и неплохо подсказывают пользователям о том, каковы размеры документов, с которыми они взаимодействуют. В результате скроллбары несут на себе двойную нагрузку. Они и помогают работать с различными материалами, и информируют пользователя о размерах этих материалов.
Простая и понятная логика скроллбаров может быть изменена при реализации механизмов скроллджекинга. Это происходит тогда, когда стандартное поведение скроллбара меняется, что нарушает ожидаемое пользователем соответствие между длиной документа и высотой скроллбара.
Более того — программы для устройств, обладающих сенсорными экранами, популяризировали идею скрытия скроллбаров. При таком подходе скроллбары оказываются невидимыми до тех пор, пока пользователь не начнёт прокручивать элемент, не помещающийся в некую область просмотра. В результате оказывается, что ради визуальной привлекательности приложений дизайнеры жертвуют понятностью интерфейсов. Пользователю может понадобиться некоторое время на то, чтобы понять, что содержимое в некоем контейнере можно прокручивать. Такой контейнер может выглядеть так, будто прокрутку он не поддерживает, или так, будто прокрутка ему просто не нужна.
Классические настольные операционные системы подхватили этот мобильный тренд, пытаясь свести к минимуму вмешательство традиционных скроллбаров в дизайн приложений.
Материал, перевод которого мы публикуем сегодня, посвящён некоторым особенностям использования скроллбаров в веб-приложениях.
Немного терминологии
Прежде чем мы продолжим — давайте определимся с парой терминов, которые мы будем тут использовать. А именно, мы выделяем две разновидности скроллбаров:
- Фиксированные (obtrusive) скроллбары — такие, которые занимают экранное пространство. Они не накладываются на просматриваемые материалы, вместо этого располагаясь рядом с ними.
- Нефиксированные (unobtrusive) скроллбары — такие, которые накладываются на контент. Они не отнимают экранное пространство у того, что находится в контейнерах, которым они принадлежат.
Стандартное поведение современных скроллбаров
По умолчанию и в iOS, и в Android скроллбары являются нефиксированными.
В macOS (в частности, речь идёт об актуальной на момент написания этого материала macOS Mojave) скроллбары скрыты до момента начала прокрутки элемента. Это — стандартное поведение системы в ситуации, когда к компьютеру не подключена мышь. Существует три варианта отображения скроллбаров (соответствующие настройки можно найти по адресу General > System Preferences
).
Настройки скроллбаров в macOS Mojave
Эти настройки, как удалось выяснить, контролируют поведение скроллбаров в браузерах Chrome, Firefox, и в новом Edge, основанном на Chromium.
Вот видео, посмотрев которое можно узнать о том, как вышеупомянутые настройки влияют на скроллбары, и о том, как скроллбары, помимо того, что позволяют прокручивать контент, на него воздействуют. Вот несколько извлечений из этого видео.
Фиксированный скроллбар в macOS виден всегда и занимает некоторое экранное пространство
Нефиксированный скроллбар в macOS накладывается на контент в процессе прокрутки документа
Нефиксированный скроллбар в macOS скрыт в тот момент, когда документ не прокручивают
В Windows 10, по адресу Settings > Display > Simplify and personalize Windows
, можно обнаружить похожие настройки.
Настройки скроллбаров в Windows 10
К сожалению, даже в том случае, когда включена опция Automatically hide scroll bars in Windows
, она не оказывает влияния на Firefox, Chrome, Internet Explorer и Edge. В случае с Edge речь идёт и о варианте браузера, основанном на Chromium, и о варианте, основанном на EdgeHTML.
Обзор задачи
Вот как выглядит в Windows страница, которую мы рассматривали выше в macOS.
Страница со скроллбаром в Windows
Скроллбары в Windows по умолчанию являются фиксированными. Они, кроме того, выглядят довольно-таки «тяжёлыми» с точки зрения дизайна. Они, в их стандартном варианте, гораздо шире, чем их собратья из macOS. Кроме того, цвет скроллбаров в Windows обычно соответствует системным настройкам, а не цветовой палитре веб-страницы.
Дизайнерам, которые привыкли к окружению macOS, но занимаются разработкой веб-приложений, рассчитанных на различные платформы, может быть нелегко сделать так, чтобы их проекты и хорошо выглядели бы в разных ОС, и при этом не тратили бы на визуализацию слишком много системных ресурсов.
Требования к проекту
Мы хотим разработать веб-приложение, скроллбары, используемые в котором, отличаются следующими особенностями:
- Они должны привлекательно выглядеть при просмотре страниц на настольных ОС. Особенно это важно при отображении контейнеров, содержимое которых в них целиком не помещается. Скроллбары выводятся внутри таких контейнеров, а значит — дизайн этих скроллбаров должен хорошо согласовываться с дизайном контейнеров. Мы полагаем, что в случае со скроллбарами, позволяющими прокручивать всю страницу, это не так важно, но это, несомненно, спорный вопрос.
- Мы хотим минимизировать экранное пространство, которое может занимать скроллбар. В Windows скроллбары, по умолчанию, являются фиксированными и очень широкими.
- Мы хотим ориентироваться на системные настройки. Если пользователь выбирает в настройках нестандартную опцию, задающую поведение скроллбаров, нам нужно всегда, когда это возможно, это учитывать.
- Мы стремимся к тому, чтобы избежать использования тяжёлых JavaScript-решений (таких, как очень приятный плагин OverlayScrollbars), рассчитанных на работу с нефиксированными скроллбарами. Они создают немалую нагрузку на клиентские компьютеры.
Насколько далеко можно продвинуться, используя CSS?
Вот код элемента-контейнера, которому назначен класс overflowing-element
, а также — CSS-код для его стилизации:
<div class="overflowing-element"></div>
.overflowing-element {
overflow-y: auto;
-webkit-overflow-scrolling: touch;
-ms-overflow-style: -ms-autohiding-scrollbar;
}
Если вам нужны нефиксированные скроллбары в Internet Explorer и в Edge, основанном на EdgeHTML, это значит, что вам пригодится свойство -ms-overflow-style: -ms-autohiding-scrollbar;
. С его использованием всё будет работать так, как нужно (это достаточно просто — правда?).
Когда вышла iOS 13, то оказалось, что свойство -webkit-overflow-scrolling: touch может и не потребоваться для улучшения физики скроллинга. Хотя, если нужно поддерживать более старые версии iOS, от использования этого свойства лучше не отказываться.
Если говорить о CSS-свойствах, имеющих отношение к скроллингу, то тут, возможно, полезным будет почитать о свойстве overscroll-behavior. Оно позволяет управлять поведением системы при достижении границы элемента, поддерживающего прокрутку.
▍Firefox
Браузер Firefox поддерживает CSS-свойства без префиксов. Это — scrollbar-color и scrollbar-width.
В следующем примере, для понятности, используются CSS-переменные, которые не поддерживаются в Internet Explorer 11:
:root {
--scrollbar-track-color: transparent;
--scrollbar-color: rgba(0,0,0,.2);
--scrollbar-width: thin; /* or `auto` or `none` */
}
.overflowing-element {
scrollbar-width: var(--scrollbar-width);
scrollbar-color: var(--scrollbar-color) var(--scrollbar-track-color);
}
▍Chrome и Safari, браузер Edge, основанный на Chromium, и прочие браузеры
Браузеры, основанные на Webkit и Blink, поддерживают нестандартные псевдо-элементы, предназначенные для настройки скроллбаров:
:root {
--scrollbar-track-color: transparent;
--scrollbar-color: rgba(0,0,0,.2);
--scrollbar-size: .375rem;
--scrollbar-minlength: 1.5rem; /* Минимальная длина бегунка скроллбара (ширина горизонтального, высота вертикального) */
}
.overflowing-element::-webkit-scrollbar {
height: var(--scrollbar-size);
width: var(--scrollbar-size);
}
.overflowing-element::-webkit-scrollbar-track {
background-color: var(--scrollbar-track-color);
}
.overflowing-element::-webkit-scrollbar-thumb {
background-color: var(--scrollbar-color);
/* Если нужно - добавьте :hover и:active */
}
.overflowing-element::-webkit-scrollbar-thumb:vertical {
min-height: var(--scrollbar-minlength);
}
.overflowing-element::-webkit-scrollbar-thumb:horizontal {
min-width: var(--scrollbar-minlength);
}
Вот пример на CodePen, демонстрирующий возможности по настройке скроллбаров, выполняемой исключительно средствами CSS. А вот — пример, в котором демонстрируется стандартное поведение скроллбаров. Можете их сравнить.
Надо отметить, что у вышеприведённого кода есть одна проблема. Она заключается в том, что при установке свойств height
или width
псевдо-элемента ::-webkit-scrollbar
в macOS производится замена нефиксированного скроллбара на фиксированный (происходит переопределение стандартных настроек). Однако это несложно исправить с помощью небольшого фрагмента JavaScript-кода.
CSS и немного JS
Мы можем добавить в проект небольшой объём JavaScript-кода, который позволяет узнать о том, является ли стандартный скроллбар фиксированным или нет. Выглядит это примерно так:
/*
* Выяснение ширины скроллбара.
* К элементу body добавляется класс `layout-scrollbar-obtrusive`
* в том случае, если скроллбар использует экранное пространство.
*/
var parent = document.createElement("div");
parent.setAttribute("style", "width:30px;height:30px;");
parent.classList.add('scrollbar-test');
var child = document.createElement("div");
child.setAttribute("style", "width:100%;height:40px");
parent.appendChild(child);
document.body.appendChild(parent);
// Измерение дочернего элемента. Если его ширина
// не равняется 30px, то скроллбар является фиксированным.
var scrollbarWidth = 30 - parent.firstChild.clientWidth;
if(scrollbarWidth) {
document.body.classList.add("layout-scrollbar-obtrusive");
}
document.body.removeChild(parent);
Если скроллбар является фиксированным — мы добавляем к элементу документа body
класс layout-scrollbar-obtrusive
. Этот класс можно использовать для того, чтобы настраивать свойства width
и height
только фиксированных скроллбаров. Это позволяет избегать описанного выше вмешательства в поведение скроллбаров. В ходе такого вмешательства скроллбары меняются и проект отходит от системных настроек, выполненных пользователем. Вот стиль для класса layout-scrollbar-obtrusive
:
.layout-scrollbar-obtrusive .layout-scrollbar::-webkit-scrollbar {
height: var(--scrollbar-size);
width: var(--scrollbar-size);
}
Здесь можно найти пример применения методики, предусматривающей совместное использование CSS и JavaScript. Вот, для сравнения, пример, демонстрирующий стандартное поведение системы.
Итоги: обзор решения задачи
На устройствах с сенсорными экранами, на которых применяются нефиксированные скроллбары (то есть — на iOS и Android-устройствах) мы просто пользуемся стандартным поведением скроллбаров.
В macOS у нас появляется возможность учитывать системные настройки, сделанные пользователем. Это означает, что мы не осуществляем непреднамеренного переключения между нефиксированными и фиксированными скроллбарами. Мы применяем стили лишь к фиксированным скроллбарам, которые видны всегда. Это позволяет нам приводить внешний вид страниц в соответствие с нашими требованиями к дизайну проекта.
В Windows, а именно — в браузерах Firefox и Chrome, нет стандартных нефиксированных скроллбаров, но тут можно, как и в других случаях, применить наш подход, предусматривающий использование исключительно возможностей CSS. Благодаря тому, что мы смогли выйти на работающие примеры использования скроллбаров, настраиваемых средствами CSS, нам удалось прийти к согласию с нашей командой дизайнеров. Мы остановились на компромиссном варианте и избежали использования тяжёлых JavaScript-решений.
Вот демонстрационные проекты, суть которых была описана выше:
- Показ стандартного поведения скролл-бара.
- Решение, в котором используется только CSS. Стилизуются все скролл-бары.
- Решение, в котором используются CSS и JavaScript. Стилизуются только фиксированные скроллбары.
Уважаемые читатели! Как вы стилизуете скроллбары в своих проектах?
Автор: ru_vds