Стилизация Скролла

Сегодня будем стилизовать скролл с помощью CSS для webkit браузеров (Google Chrome / Safari / Opera / Яндекс.Браузер) и Mozilla Firefox. А так же рассмотрим изменение скролла при помощи плагина mCustomScrollbar.

Содержание:

  1. стилизация скролла для Firefox;
  2. стилизация скролла для остальных браузеров;
  3. кроссбраузерная стилизация с помощью плагина mCustomScrollbar;
  4. добавление скролла (принудительно);
  5. скрыть скролл, но оставить возможность прокрутки;
  6. CSS Scroll Snap;
    1. Scroll Snap Type;
    2. Scroll Snap Align;
    3. Scroll Snap со стрелками;
    4. примеры использования.

Стилизация скролла для Mozilla Firefox

Чтобы изменить скролл в Firefox, используйте следующий код.

html, body {
    scrollbar-color: #458245 #714826; /* «цвет ползунка» «цвет полосы скроллбара» */
    scrollbar-width: auto | thin | none;  /* толщина */
}

Первое значение scrollbar-color изменяет цвет ползунка, второе — цвет скроллбара.

Стилизация скролла в Mozilla Firefox

Значения scrollbar-width изменят толщину (ширину — для вертикального скроллбара, высоту — для горизонтального):

  • auto — толщина скролла по умолчанию;
  • thin — более тонкий вариант скролла;
  • none — скрыть скролл.

Пример. Обратите внимание, данный пример предназначен для просмотра в Firefox.

Выберите цвет скроллбара
Выберите цвет ползунка скроллбара
Выберите толщину скролла


Какой-то контент. Текст, изображения или что-то ещё.



Стилизация скролла для webkit браузеров

Чтобы стилизовать скролл для Google Chrome, Яндекс.Браузер, Safari и Opera используйте следующие CSS свойства.

/* полоса прокрутки (скроллбар) */
::-webkit-scrollbar {
    width: 24px; /* ширина для вертикального скролла */
    height: 8px; /* высота для горизонтального скролла */
    background-color: #143861;
}

/* ползунок скроллбара */
::-webkit-scrollbar-thumb {
    background-color: #843465;
    border-radius: 9em;
    box-shadow: inset 1px 1px 10px #f3faf7;
}

::-webkit-scrollbar-thumb:hover {
    background-color: #253861;
}

/* Стрелки */

::-webkit-scrollbar-button:vertical:start:decrement {
    background: linear-gradient(120deg, #02141a 40%, rgba(0, 0, 0, 0) 41%),
        linear-gradient(240deg, #02141a 40%, rgba(0, 0, 0, 0) 41%),
        linear-gradient(0deg, #02141a 30%, rgba(0, 0, 0, 0) 31%);
    background-color: #f6f8f4;
}

::-webkit-scrollbar-button:vertical:end:increment {
    background:
        linear-gradient(300deg, #02141a 40%, rgba(0, 0, 0, 0) 41%),
        linear-gradient(60deg, #02141a 40%, rgba(0, 0, 0, 0) 41%),
        linear-gradient(180deg, #02141a 30%, rgba(0, 0, 0, 0) 31%);
    background-color: #f6f8f4;
}

::-webkit-scrollbar-button:horizontal:start:decrement {
    background:
        linear-gradient(30deg, #02141a 40%, rgba(0, 0, 0, 0) 41%),
        linear-gradient(150deg, #02141a 40%, rgba(0, 0, 0, 0) 41%),
        linear-gradient(270deg, #02141a 30%, rgba(0, 0, 0, 0) 31%);
    background-color: #f6f8f4;
}

::-webkit-scrollbar-button:horizontal:end:increment {
    background:
        linear-gradient(210deg, #02141a 40%, rgba(0, 0, 0, 0) 41%),
        linear-gradient(330deg, #02141a 40%, rgba(0, 0, 0, 0) 41%),
        linear-gradient(90deg, #02141a 30%, rgba(0, 0, 0, 0) 31%);
    background-color: #f6f8f4;
}

mCustomScrollbar

Теперь рассмотрим, как кроссбраузерно стилизовать скролл при помощи плагина mCustomScrollbar.

Сначала скачайте архив и извлеките к себе в проект файлы:

  • jquery.mCustomScrollbar.min.css
  • jquery.mCustomScrollbar.concat.min.js
  • mCSB_buttons.png

Затем подключите jQuery и файлы плагина.

Или же можете подключить все файлы через CDN jsdelivr:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="//cdn.jsdelivr.net/jquery.mcustomscrollbar/3.0.6/jquery.mCustomScrollbar.min.css">
<script src="//cdn.jsdelivr.net/jquery.mcustomscrollbar/3.0.6/jquery.mCustomScrollbar.concat.min.js"></script>

Инициализация

Инициализация через JavaScript

(function ($) {
    $(window).on("load", function () {
        $(".mycustom-scroll").mCustomScrollbar();
    });
})(jQuery);

Инициализация в HTML

<div class="mycustom-scroll" data-mcs-theme="3d-dark">
    <!-- Ваш контент -->
</div>

Настройки

$(".mycustom-scroll").mCustomScrollbar({
    axis: "y",              // вертикальный скролл
    theme: "rounded-dark",  // тема
    scrollInertia: "330",   // продолжительность прокрутки, значение в миллисекундах
    setHeight: "100%",      // высота блока (переписывает CSS)
    mouseWheel: {
        deltaFactor: 300    // кол-во пикселей на одну прокрутку колёсика мыши
    }
});

Темы mCustomScrollbar

Выбрать подходящую тему можно здесь.

Если же готовых тем недостаточно, то можете проинспектировать нужный элемент скролла и стилизовать как вам это необходимо.

Добавление скролла

Чтобы принудительно добавить скролл для блока, необходимо ограничить его по высоте/ширине и добавить overflow:

  • overflow-y: auto; — для создания вертикального скролла (+ max-height);
  • overflow-x: auto; — для создания горизонтального скролла (+ max-width).

При создании горизонтального скролла для текстового блока может понадобится добавление следующего css: white-space: nowrap;.

Как скрыть скролл

Скроем скролл, но оставим возможность прокрутки блока.

.el {
    scrollbar-width: none; /* firefox */
}
.el::-webkit-scrollbar { /* webkit */
    width: 0;
    height: 0;
}

CSS Scroll Snap

Позволяет прокручивать не попиксельно, а целыми блоками. Базовое использование.

<div class="parent-container">
    <div class="children"></div>
    <div class="children"></div>
    <div class="children"></div>
    <div class="children"></div>
</div>
.parent-container {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x proximity;
}

.children {
    scroll-snap-align: start;
}

Scroll Snap Type

Пример с горизонтальным Scroll Snap:

1
2
3

Вертикальный Scroll Snap.

.parent-container {
    overflow-y: auto;
    scroll-snap-type: x proximity;
}

.children {
    scroll-snap-align: start;
}
1
2
3

Scroll Snap Align

Свойство Scroll Snap Align применяется к дочерним элементам контейнера, которые будем скролить. Мы можем указать какая сторона дочернего элемента будет прижата к родительскому блоку.

Примеры по оси X:

.parent-container {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x proximity;
}
.children {
    scroll-snap-align: start; /* start/center/end */
}
1
2
3

Примеры по оси Y:

.parent-container {
    overflow-y: auto;
    scroll-snap-type: y proximity;
}
.children {
    scroll-snap-align: start; /* start/center/end */
}
1
2
3

Примеры использования Scroll Snap

Ниже приведены примеры использования Scroll Snap для реальных проектов.

Горизонтальный слайдер

.parent-container {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
}

.children {
    scroll-snap-align: center;
}

Полноэкранная вертикальная прокрутка секций

.parent-container {
    scroll-snap-type: y mandatory;
}

.children {
    height: 100vh;
    width: 100vw;
    scroll-snap-align: start;
}

Полноэкранная горизонтальная прокрутка секций

.parent-container {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x proximity;
}

.children {
    height: 100vh;
    width: 100vw;
    scroll-snap-align: start;
}

Scroll Snap с навигацией

Реализуем Scroll Snap с навигацией, добавим стрелки для прокрутки.

Структура:

<div class="testimonials">
    <div class="scroller">
        <div class="item">1</div>
        <div class="item">2</div>
        <div class="item">3</div>
    </div>
    <span class="btn prev">&lt;</span>
    <span class="btn next">&gt;</span>
</div>

JavaScript:

const testimonials = document.querySelector(".testimonials");
const scroller = testimonials.querySelector(".scroller");
const nextBtn = testimonials.querySelector(".btn.next");
const prevBtn = testimonials.querySelector(".btn.prev");
const itemWidth = testimonials.querySelector(".item").clientWidth;

nextBtn.addEventListener("click", scrollToNextItem);
prevBtn.addEventListener("click", scrollToPrevItem);

function scrollToNextItem() {
    if (scroller.scrollLeft < (scroller.scrollWidth - itemWidth)) {
        // Позиция прокрутки не в начале последнего элемента
        scroller.scrollBy({ left: itemWidth, top: 0, behavior: "smooth" });
    } else {
        // Достигнут последний элемент
        // Вернёмся к первому элементу, установив положение прокрутки на 0
        scroller.scrollTo({ left: 0, top: 0, behavior: "smooth" });
    }
}

function scrollToPrevItem() {
    if (scroller.scrollLeft != 0) {
        // Позиция прокрутки не в начале первого элемента
        scroller.scrollBy({ left: -itemWidth, top: 0, behavior: "smooth" });
    } else {
        // Это первый элемент (отзыв)
        // Перейдём к последнему элементу, установив положение прокрутки на ширину «.scroller»
        scroller.scrollTo({ left: scroller.scrollWidth, top: 0, behavior: "smooth" });
    }
}