После вступления Edge в доблестные ряды Chromium-браузеров кастомизация скроллбаров через CSS отсутствует только в Firefox. Это здорово, но кроме Firefox у CSS-решения есть масса ограничений. Посмотрите, какую черную магию приходится применять для плавного исчезновения. Чтобы получить полный контроль над внешним видом, по-прежнему нужно прибегать к JavaScript. Давайте разберемся, как это по-хорошему сделать через компонент Angular.  Без нее, конечно, не обойтись. Во-первых, нам нужно скрыть нативные скроллбары. Это уже можно сделать во всех браузерах. Для этого есть стандартное правило scrollbar-width, которое на данный момент работает как раз только в Firefox. Для старых версий Edge и IE есть его аналог -ms-overflow-style. Однако IE мы поддерживать не будем, так как нам понадобится position: sticky. В Chrome и Safari уже давно можно использовать псевдоселектор ::-webkit-scrollbar. Во-вторых, чтобы не нарушать нативную работу и скроллить сам контейнер, нам нужно обойтись без вложенной скроллящейся обертки. А значит, необходимо реализовать что-то вроде локального position: fixed для ползунков. Абсолютное позиционирование не поможет: при прокрутке ползунки будут исчезать из виду вместе с содержимым. Этого мы сможем добиться с помощью хитрой комбинации position: sticky у ползунков и display: flex у самого компонента. Внутри нам понадобятся два контейнера: Для начала мы изолируем контекст наложения. Не все про это знают, из-за чего на проектах часто можно встретить z-index: 1000, 1001, 9999. Чтобы ничто из контента не смогло перекрыть ползунки, мы повесим на него position: relative, z-index: 0. Это создаст в его рамках новый контекст наложения и не позволит внутренним элементам перекрыть что-то снаружи. Ползункам зададим z-index: 1, чтобы поднять их выше контента, а также минимальную ширину 100%. Получим следующую картину:  Ползунки заняли все место, сдвинув содержимое вправо. При этом прокрутка работает и ползунки никуда не деваются. Остается добавить им margin-right: -100%, чтобы они «подвинулись» и освободили место под содержимое компонента. Если вы читали другие мои статьи про Angular, то знаете, что я большой любитель декларативного подхода. Этот случай не станет исключением. Постараемся написать код максимально аккуратно. В качестве примера возьмем вертикальную прокрутку, для горизонтальной все будет идентично. Добавим в шаблон ползунок: Для задания его внешнего вида используются геттеры: Теперь нам нужно просто слушать скролл, чтобы запускать проверку изменений, — и наш компонент начнет работать с колесиком или трекпадом. Осталось научиться двигать ползунки мышкой. Эту логику стоит вынести в отдельную директиву, но для прозрачности сейчас мы это делать не будем. Добавим обработчики на ползунок: А в коде компонента будем обрабатывать эти события и слушать mouseup: Теперь ползунки тоже работают. Бывалый ангулярщик может заметить, что у этого решения крайне низкая производительность. На каждый экземпляр скроллбара мы слушаем все события mousemove на документе и каждый раз запускаем проверку изменений. Так дело не пойдет. К счастью, Angular позволяет работать с событиями иначе, о чем я писал ранее. Воспользовавшись библиотекой @tinkoff/ng-event-plugins, мы избавимся от лишних вызовов проверки изменений. Для этого добавим модификатор .silent к подписке и декоратор @shouldCall к обработчику: Теперь проверка изменений и обработчики событий будут запускаться, только когда мы действительно тянем ползунок. Наш скроллбар готов к использованию. В качестве доработки еще можно следить за изменениями размера самого контейнера, чтобы пересчитать размер ползунков. Для этого отлично подойдет ResizeObserver и наша библиотека @ng-web-apis/resize-observer, о которой вы можете почитать тут. Полноценное демо скроллбара доступно на Stackblitz. Как справедливо заметили в комментариях, получилось не так декларативно, как хотелось бы. Попробуем уложить логику ползунков в директиву. Для этого будет достаточно одного Output объявленного через fromEvent, что избавляет код от состояний и лишней императивности: Обновлённый пример тут. Там же можно увидеть методы, в которые убрана вся математика из кода выше. Google Developer Expert | Angular