Как сделать скролл слева

Обновлено: 08.07.2024

. Многие из вас скажут, что нет ничего проще, достаточно установить фиксированную высоту блока и задать его свойству overflow-y значение auto или scroll . Действительно, этого вполне достаточно, но, в большинстве случаев, полосы прокрутки нарушают дизайн веб-страницы.

В этой статье я расскажу вам, как сделать прокрутку контента в блоке и сам скроллбар c помощью JavaScript используя событиt scroll . Подробно рассмотрим HTML-вёрстку, CSS и сам код на чистом JavaScript.

Составим техническое задание на создание прокрутки контента внутри блока:

  1. Прокрутка должна осуществляется колёсиком мыши при наведении на выбранный блок или перетаскиванием ползунка скроллбара.
  2. Блок должен иметь кастомный скроллбар с высотой ползунка, зависящей от размера контента внутри блока.
  3. При прокрутке контента в блоке использовать стандартное событие scroll.
  4. На странице может быть несколько блоков с прокруткой контента.
  5. Ширина и высота блоков с прокруткой не должна влиять на работу скрипта.

HTML-разметка блока с прокруткой.

HTML-код блока с прокруткой контента:

Кратко рассмотрим назначение каждого элемента:

container Родительский элемент, задаёт ширину, высоту и дизайн блока с прокруткой контента. viewport Область просмотра, которая определяет границы контента, за которыми контент не виден. Кроме этого, вьюпорт обрезает и делает невидимой дефолтную полосу прокрутки контейнера contentBox . contentBox Контейнер, в котором размещён и будет прокручиваться контент. Именно у этого контейнера стандартная полоса прокрутки будет заменена на кастомную.

Обратите внимание — показ дефолтной полосы прокрутки мы запретили, а HTML-вёрстку кастомного скроллбара не сделали. Он будет формироваться JS-скриптом в случае необходимости, т. е., если высота контента больше высоты контейнера contentBox . Такое решение предоставляет большую гибкость в применении, отсутствует зависимость от высоты контента. Это удобно, когда на странице несколько таких блоков с разным наполнением контентом.

Таблица стилей для блока с прокруткой.

Ниже я приведу только те стили, которые непосредственно относятся к блоку с прокруткой контента.

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

Начинаем писать JavaScript для блока с прокруткой контента.

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

При написании JS-скрипта мы будем использовать конструкцию Class . Это позволит создать несколько экземпляров блоков с прокруткой на одной странице.

Создание экземпляров блоков с прокруткой контента.

В-первую очередь, создадим коллекцию блоков, в которых может понадобиться прокрутка контента. Далее, с помощью метода for. of переберём полученную коллекцию, при этом мы выполним следующие действия:

  1. создадим экземпляр текущего блока, используя конструктор класса ScrollBox ;
  2. создадим HTML-вёрстку скроллбара, если высота контента в текущем блоке больше высоты родительского контейнера.
  3. зарегистрируем обработчики событий.

Весь дальнейший JS-код мы будем писать внутри конструкции class ScrollBox < . >.

Прежде всего рассмотрим конструктор класса ScrollBox . Конструктор инициализирует ряд объектов и переменных, содержащих информацию об экземпляре блока прокрутки. В качестве аргумента конструктор принимает объект блока с контентом, экземпляр которого создаётся в данный момент.

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

Конструктор, кроме инициализации объектов и переменных, вызывает функцию init() . Алгоритм работы данной функции:

Сравнивает высоту контента с высотой вьюпорта. Если высота контента окажется меньше или равна высоте вьюпорта, то функция прекращает работу, т. к. необходимость в прокрутке отсутствует.

Определяет максимальную прокрутку контента.

Вычисляет соотношение между высотами вьюпорта и контента.

Вызывает функцию createScrollbar() для создания полосу прокрутки.

Вызывает функцию registerEventsHandler() регистрирующую обработчики событий для управления прокруткой как вращением колёсика мыши, так и перетаскиванием ползунка скроллбара.

Рассмотрим код функции init() и комментарии к нему:

Создание скроллбара для блока с прокруткой контента.

Как я писал выше, скроллбар и его ползунок формируются с помощью функции createScrollbar() .
Рассмотрим алгоритм работы данной функции:

Используя встроенный в JavaScript метод document.createElement , создаёт новые DOM-элементы DIV , из которых будут сформированы полоса прокрутки и ползунок.

Присваивает созданным элементам классы — scrollbar и scroller соответственно.

Вставляет созданные элементы во вьюпорт.

Получает DOM-объект ползунка полосы прокрутки, вычисляет и устанавливает его высоту.

Высота ползунка зависит от соотношения высот вьюпорта и контента (коэффициент ratio ), при этом чем больше высота контента, тем меньше высота ползунка полосы прокрутки.

Код функции createScrollbar() и комментарии к нему:

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

Запомните, это очень важно.
При использовании метода addEventListener теряется контекст вызова — this , который ссылается на текущий объект. Используя встроенный в JavaScript метод bind , можно напрямую передать контекст вызова в функцию обработчика события.

Регистрировать мы будем следующие события:

scroll вращение колёсика мыши, при этом курсор должен быть над вьюпортом; mousedown нажатие на левую кнопку мыши, когда курсор находится на ползунке; mousemove перемещение мыши по полосе прокрутки и документу в целом, т. е., если при перемещении курсор покинет область полосы прокрутки, перемещение ползунка не прервётся; mouseup отпускание левой кнопки мыши, при этом курсор может находиться над любой частью документа.

Код функции registerEventsHandler() и комментарии к нему:

Как видно из кода, событие mousedown привязывается к элементу scroller . А вот события mousemove и mouseup привязаны к объекту document , т. е. событие может наступить при положении курсора над любой частью страницы. Такое поведение предусмотрено при дефолтной прокрутке контента внутри блока при назначении ему стиля overflow-y: scroll . Логично, что я постарался сохранить его.

Управление прокруткой контента внутри блока по событию ‘scroll’.

При возникновении события scroll прокрутка будет осуществляться стандартными методами встроенными в браузер. Нам потребуется только изменить положение ползунка.
Изменять положение ползунка будем меняя значение свойства top пропорционально изменению значения текущей прокрутки контента с учётом, полученного ранее, коэффициента ratio . Давайте ещё раз посмотрим на функцию, которая вызывается при наступлении события scroll :

Далее я расскажу вам, как перетаскивается ползунок по полосе прокрутки и как меняется прокрутка контента в зависимости от текущего положения ползунка.

Прокрутка контента перемещением ползунка скроллбара.

Перетаскивание ползунка начинается с наступления события mousedown . При обработке этого события запоминается координата по оси Y — e.clientY , которая будет считаться точкой начала перемещения ползунка. Кроме этого, выставляется флаг сигнализирующий о нажатии левой кнопки мыши.
JS-код, реализующий это, находится в функции, являющейся вторым параметром регистратора обработчика события mousedown . Напомню этот код, чтобы вам не листать страницу:

За перетаскивание ползунка отвечает функция drop , которая вызывается при возникновении события mousemove . Давайте рассмотрим алгоритм работы этой функции:

Проверяет установку флага нажатия левой кнопки мыши pressed . Если флаг не установлен, то прекращает свою работу.

Вычисляет величину перемещения мыши, как разницу между координатой старта this.start и текущей координатой курсора по оси Y — e.clientY .

Изменяет положение бегунка на величину перемещения курсора, меняя его смещение по вертикали путём изменения CSS-свойства top .

Ограничивает перемещение ползунка верхней и нижней границей вьюпорта.

Прокручивает контент на величину пропорциональную перемещению ползунка.

Устанавливает координату Y начала движения мыши равной текущей координате Y.

Прежде чем начнём писать код функции drop , давайте подробнее разберём п. 4 представленного алгоритма.

Ранее нами было получено максимально возможное смещение ползунка от верхней границы вьюпорта — scrollerMaxOffset , вычисленное как разность высоты вьюпорта и высоты ползунка. Давайте посмотрим на рисунок:

Прокрутка блока. Максимально смещение ползунка.

Из рисунка видно, что если попытаться ещё увеличить смещение ползунка, то его нижняя часть выйдет за пределы вьюпорта. Другими словами, сумма высоты ползунка и его смещения не должна превышать высоту вьюпорта.

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

Теперь можно представить полный код функции drop :

if ( totalheightScroller > = this . viewportHeight ) this . scroller . style . top = maxOffsetScroller + 'px' ;

При отпускании левой кнопки мыши, наступает событие mouseup и перетаскивание ползунка скроллбара прекращается. При этом флаг pressed получает значение false .

Напомню этот код, чтобы вам не листать страницу:

На этом изучение прокрутки контента в блоке можно считать законченным. Посмотреть пример различных вариантов прокрутки блока, скачать HTML-вёрстку и полный JS-код, Вы можете по ссылкам, указанным в начале страницы.

Комментарии

  1. Комментарии должны содержать вопросы и дополнения по статье, ответы на вопросы других пользователей.
    Комментарии содержащие обсуждение политики, будут безжалостно удаляться.
  2. Для удобства чтения Вашего кода, не забываейте его форматировать. Вы его можете подсветить код с помощью тега

А есть такое для горизонтального скролла?

Можно архив не rar пожалуйста)

Спасибо автору за прекрасный урок.

В секцию fn.registerEventsHandler = function(e) // document resize (добавил в самом низу)
// возможно ли отказаться от window, заменив его на document?
window.addEventListener(‘resize’, () => this.refreshScrollbar();
>);
>;

ниже функции
fn.createScrollbar = function() …
>;
добавил функцию
fn.refreshScrollbar = function() this.content = this.viewport.querySelector(‘.content’);
this.viewportHeight = this.viewport.offsetHeight;
this.contentHeight = this.content.scrollHeight;
// возможная максимальная прокрутка контента
this.max = this.viewport.clientHeight — this.contentHeight;
// соотношение между высотами вьюпорта и контента
this.ratio = this.viewportHeight / this.contentHeight;
// устанавливаем его высоту
this.scroller = this.viewport.querySelector(‘.scroller’);
this.scrollerHeight = parseInt(this.ratio * this.viewportHeight);
this.scrollerHeight = (this.scrollerHeight Егор Ответить 8 августа 2019 в 11:31

Также замечен недостаток, что при resize прячется индикатор прокрутки, если конента много и ранее была прокрутка вниз.

аффтор убей себя об стену. это двумя строчками делается, губошлёп.

Для этого нужно зарегистрировать touch-события touchstart, touchmove, touchend и при их срабатывании вызывать функции, соответствующие событиям мыши mousedown, mousemove, mouseup.

Скроллер — фигня.
Если контент прокручиваемый контент будет очень большой, начнет заметно подтормаживать.
Не нужно придумывать прокрутку за браузер, у вас все-равно не выйдет его оптимизировать лучше, если только не будете весь свой контент на canvas рисовать.
А сказать браузеру, что содержимое элемента нужно прокрутить, можно изменяя свойство scrollTop и scrollLeft соответственно, привязав его к рукописному скроллеру.
И если вешаете событие при помощи addEventListener, особенно на документ, удаляйте его после использования removeEventListener, особенно если вешаете на такое событие как mousemove.

Добрый день!
Вопрос со стороны автоматизации.
Можно ли такой блок скроллить как-то, например, скриптом?
Столкнулся с подобным на странице, есть блок, не факт, что такой, но похожий, внутри элемент, находящийся за видимой областью экрана, нужно его вытащить.
При использовании рядовых методов Selenium WebDriver (scrollIntoView, scrollTo) скроллится вся страница, но не блок

А нельзя шаг прокрутки привязать к якорям? Чтобы прокрутка блоками выполнялась?

Вернёмся назад, когда вы могли настроить скроллбары в IE (5.5) с помощью нестандартных свойств типа scrollbar-base-color , которые применялись к элементам с полосами прокрутки (вроде body ), и делать потрясные штуки. IE теперь не тот.

Необходимое

Разные части

Вот псевдоэлементы, отвечающие за разные части полос прокрутки.


Различные состояния

Это псевдоселекторы, они позволяют точнее выбирать разные части полосы прокрутки, когда они находятся в различных состояниях.

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

:horizontal — применяется к любому скроллбару, который имеет горизонтальную ориентацию.

:vertical — применяется к любому скроллбару, который имеет вертикальную ориентацию.

:decrement — применяется к кнопкам и к видимой части трека, сообщает, что нет кнопок или видимая часть трека уменьшена в процессе использования (вверх для вертикального скроллбара и влево для горизонтального).

:increment — применяется к кнопкам и к видимой части трека, сообщает, что нет кнопок или видимая часть трека увеличена в процессе использования (вниз для вертикального скроллбара и вправо для горизонтального).

:start — применяется к кнопкам и к видимой части трека, сообщает, что объект находится перед ползунком.

:end — применяется к кнопкам и к видимой части трека, сообщает, что объект находится после ползунка.

:double-button — применяется к кнопкам и к видимой части трека, используется для определения того, что кнопка является частью пары кнопок, которые находятся вместе в конце скроллбара. Для видимой части трека сообщает, что она примыкает к паре кнопок.

:single-button — применяется к кнопкам и к видимой части трека, используется для определения того, что кнопка в конце скроллбара единственная. Для видимой части трека сообщает, что он примыкает к этой единственной кнопке.

:no-button — применяется к видимой части трека, сообщает, что видимая часть трека приближается к краю скроллбара, другими словами, нет кнопки в конце трека.

:corner-present — применяется ко всем элементам скроллбара и сообщает, что имеется уголок.

:window-inactive — применяется ко всем элементам скроллбара и сообщает, что окно со скроллбаром в данный момент активно. В последних версиях этот псевдокласс хорошо сочетается с ::selection. Мы планируем расширить его работу для любого контента и предложить в качестве нового стандартного псевдокласса.

Теперь всё вместе

Эти псевдоэлементы и псевдоклассы работают совместно. Вот несколько случайных примеров.

Очень простой пример

Чтобы сделать действительно простой пользовательский скроллбар мы добавим это.

И получим следующий результат на простом


В диких условиях

Отмечу очень тонкий и симпатичный скроллбар в блоге Тима Ван Дамма Maxvoltar (сайт Тима больше не использует этот дизайн).

Особенно приятно, что скроллбар применяется к элементу body, но полосы прокрутки не прилипают к верхнему, нижнему или правому краю окна браузера, где они обычно находятся. Я сделал тестовую страницу скопировав и вставив код для достижения аналогичного эффекта.

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

Как изменить полосу прокрутки на CSS

На сегодняшний день, можно очень простым способом изменить внешний вид всем надоевшей серой полосы прокрутки. И для этого не нужно подключать сторонние библиотеки или писать JavaScript код, а достаточно запомнить несколько CSS свойств. Правда, такой способ имеет поддержку, только у популярных -webkit браузеров - Chrome, Safari, Opera.

Данные CSS свойства не будут работать в IE и Firefox, но поскольку большинство пользователей, сегодня выбирают Chrome, то можно смело эти свойства применять в своих проектах. Ничего страшного не произойдет, если немногочисленные пользователи других браузеров, увидят не кастомную полосу прокрутки (scrollbar), а дефолтную.

Свойство -webkit-scrollbar

Свойство -webkit-scrollbar служит контейнером для всех элементов полосы прокрутки: ползунка и дорожки. Его стандартная ширина равна 17 пикселям, но мы можем задавать любую ширину.

::-webkit-scrollbar width: 25px; /* ширина нового скроллбара */
>

Свойство -webkit-scrollbar-track

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

Мы видим, что дорожка покрасилась в светло-розовый цвет.

Как изменить полосу прокрутки на CSS.

Свойство -webkit-scrollbar-thumb

Свойство -webkit-scrollbar-thumb кастомизирует ползунок, который бегает по дорожке. Теперь покрасим наш ползунок в темно-розовый цвет, скруглим у него углы и зададим рамку.

Как изменить полосу прокрутки на CSS.

В качестве дополнения на ползунок можно повесить картинку.

Как изменить полосу прокрутки на CSS.

Очень круто будет смотреться линейный градиент.

Как изменить полосу прокрутки на CSS.

Свойство -webkit-scrollbar-button

Свойство -webkit-scrollbar-button отвечает за навигационные стрелочки, которые были сверху и снизу у стандартной полосы прокрутки.

Как изменить полосу прокрутки на CSS.

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


Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

Она выглядит вот так:

Комментарии ( 0 ):

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

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

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

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

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

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

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

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

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

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

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

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

mCustomScrollbar

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

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

  1. jquery.mCustomScrollbar.min.css
  2. jquery.mCustomScrollbar.concat.min.js
  3. mCSB_buttons.jpg

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

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

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

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

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

Настройки

Темы mCustomScrollbar

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

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

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

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

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

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

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

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

CSS Scroll Snap

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

Читайте также: