image Скроллбар (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. Стилизуются только фиксированные скроллбары.

Уважаемые читатели! Как вы стилизуете скроллбары в своих проектах?


Комментарии (14)


  1. Loki3000
    24.09.2019 13:25
    +2

    Как же хочется найти того, кто притащил эту заразу с узкими скроллбарами на десктоп, и крепко пожать ему горло! Даже если у тебя монитор такого размера, что его не обхватить руками, все равно приходится целится в эти микроскопические полоски!
    Причем, и под виндой эта зараза лезет (да-да, Adobe, это ваши поделки!), так и в линукс просачивается (привет, Cinnamon).
    Как все эти дизайнеры не могут понять, что на мобильном устройстве узкий скроллбар выполняет чисто функции индикации (реальный скроллбар намного шире).
    Странно это констатировать, но в плане скроллбара мне подход Майкрософта кажется самым здравым.


    1. amarao
      24.09.2019 14:21

      А меня вполне устраивает. Размер скролл-бара в циннамоне примерно полторы m, так что по нему вполне можно попасть. Если не попадаете — плохая мышка, либо надо accessibility включать (сочувствую).


    1. bromzh
      24.09.2019 15:32
      +1

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


    1. profesor08
      24.09.2019 19:23
      +3

      Это не самое страшное, попасть можно, если аккуратно, и поведение при прокрутке колесиком или тачем сохраняется. Но вот когда полностью отключают стандартный скролбар и заменяют его поделкой на js, вот тут то и начинается жесть. Многое не учтено, особенности браузера не учтены, особенности системы не учтены, баганет — жопа. Привыкнув к стандартной прокрутке, становится не комфортно пользоваться кастомными, в них все не так.


      1. sanchezzzhak
        25.09.2019 13:42

        Сейчас хром предупреждения в консоль отправляет при использование js, что-то о mousewhile… Немного раздражает, сам больше не использую плагины они тупые, то медленные, то глючит..


        Ниже в комментариях есть мой коммент, как я использую скроллы


    1. stalinets
      24.09.2019 21:04
      +1

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


    1. ehots
      25.09.2019 07:58
      -1

      Page up, Page down, ctrl + home, ctrl + end, ну и ctrl + f конечно.
      Как говорят интернет духи — программисту клавиатура ближе, чем мышь.


      1. FibYar
        25.09.2019 08:37
        +2

        А если вы хотите прокрутить страницу в середину (а она очень длинная)? А если у вас не подключена клавиатура (привет, планшетные компьютеры, под которые всё якобы и затачивается)?


        1. ehots
          25.09.2019 18:14

          В какой ситуации нужно на очень длинной странице прокрутить в середину и при этом неизвестно что Вы ищите?

          Как же хочется найти того, кто притащил эту заразу с узкими скроллбарами на десктоп

          Речи о планшетах не было, да и когда это мир перешел на планшетные компьютеры? Смартфоны еще можно сказать, а вот планшеты сомнительно.


          1. SlimShaggy
            28.09.2019 07:40

            В какой ситуации нужно на очень длинной странице прокрутить в середину и при этом неизвестно что Вы ищите?

            Например, когда возвращаешься к чтению комментариев к статье на Хабре, прочитав примерно половину на другом устройстве.


      1. Loki3000
        25.09.2019 09:18

        Ну попробуйте такую штуку провернуть в том же лайтруме, в котором постоянно на экране 3-4 разных скролла.


        1. ehots
          25.09.2019 19:36

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


  1. Andrusha
    24.09.2019 15:31
    +3

    Эх, помню, в старших классах делал проект по информатике — сайт для школы (который так и не был выложен в интернет) и решил раскрасить скроллбары, как до этого сделал на своей домашней страничке, ну и вообще по-полной заюзал свежие возможности тогдашнего CSS, сильно не задумываясь о совместимости. В итоге хорошую оценку-то я получил, но пришлось придти пораньше и обновить на всех компьютерах Internet Explorer на 6-й.


  1. sanchezzzhak
    25.09.2019 13:37

    Использую нативные скролы только в десктопе, при след. кейсе:


    Слева или справа настройки, в противоположной стороне предпросмотор.


    Для девайсов убираю скролл.
    Раньше для кастомизации использовал плагины на жс, сейчас нет.
    Кастомизация есть в ff, chrome, ie.