Ultimate ScrollBar

Customizable scrollbar for Chromium based browsers (Chrome/Edge/Brave/Opera/Vivaldi), with minimal Firefox support

/* ==UserStyle==
@name         Ultimate ScrollBar
@namespace    https://github.com/pabli24/
@version      1.2.3
@description  Customizable scrollbar for Chromium based browsers (Chrome/Edge/Brave/Opera/Vivaldi), with minimal Firefox support

@author       Pabli (https://ko-fi.com/pabli)
@license      MIT
@homepageURL  https://github.com/pabli24/ultimate-scrollbar
@supportURL   https://github.com/pabli24/ultimate-scrollbar/issues

@preprocessor stylus
@var          checkbox _button                      "Show arrow buttons (Enable 'Patch CSP to allow style assets' in the stylus options, otherwise the arrows may not show up on some sites)" 1
@var          checkbox _zoom                        "Don't change the size of the scrollbar on zoom (ctrl +)" 1
@var          checkbox _html                        "Main scrollbar only" 0

@var          number   _width                       "Width (px)"                [12, 0, null, null, "px"]
@var          number   _thumbBorderRadius           "Thumb border radius (px)"  [4, 0, null, null, "px"]
@var          number   _thumbBoxShadowWidth         "Thumb border (px)"         [1, 0, null, null, "px"]
@var          number   _thumbBorderWidth            "Thumb margin (px)"         [1, 0, null, null, "px"]
@var          number   _buttonBorderWidth           "Arrow buttons margin (px)" [1, 0, null, null, "px"]

@var          color    _trackBackgroundColor        "Track 🦊"                  hsla(0, 0%, 0%, 0)
@var          color    _thumbBackgroundColor        "Thumb 🦊"                  hsla(0, 0%, 30%, .7)
@var          color    _thumbBackgroundColorHover   "Thumb on hover"            hsla(0, 0%, 35%, .7)
@var          color    _thumbBackgroundColorActive  "Thumb on click"            hsla(0, 0%, 40%, .7)
@var          color    _thumbBorderColor            "Thumb border"              hsla(0, 0%, 40%, .3)
@var          color    _cornerBackgroundColor       "Corner"                    hsla(0, 0%, 30%, .7)

@var          select   _dark                        "Separate style for websites with dark mode (On some sites you may need to change their theme from auto to dark) 🦊" ["Enabled", "Manually:Enabled only on sites added manually below", "All:Enabled on all sites", "Disabled"]
@var          text     _darkWebsite                 "Add sites manually if dark scrollbar isn't working 🦊" "'example.com, example.org'"
@var          color    _trackBackgroundColor2       "Dark - Track 🦊"           hsla(0, 0%, 0%, 0)
@var          color    _thumbBackgroundColor2       "Dark - Thumb 🦊"           hsla(0, 0%, 70%, .7)
@var          color    _thumbBackgroundColorHover2  "Dark - Thumb on hover"     hsla(0, 0%, 75%, .7)
@var          color    _thumbBackgroundColorActive2 "Dark - Thumb on click"     hsla(0, 0%, 80%, .7)
@var          color    _thumbBorderColor2           "Dark - Thumb border"       hsla(0, 0%, 80%, .3)
@var          color    _cornerBackgroundColor2      "Dark - Corner"             hsla(0, 0%, 70%, .7)

@var          checkbox _new                         "Use new standardized, but less customizable way of styling scrollbars (Supported option = 🦊). The scrollbar look may differ from browser to browser (Chrome 121+ / Firefox 64+)" 0
@var          checkbox _thin                        "↳ Width - Thin 🦊"         0

==/UserStyle== */
@-moz-document regexp(".+"), regexp("(chrome|moz)-extension://.+")
	
	i = !important
	
	if _dark == All
		_trackBackgroundColor = _trackBackgroundColor2
		_thumbBackgroundColor = _thumbBackgroundColor2
		_thumbBackgroundColorHover = _thumbBackgroundColorHover2
		_thumbBackgroundColorActive = _thumbBackgroundColorActive2
		_thumbBorderColor = _thumbBorderColor2
		_cornerBackgroundColor = _cornerBackgroundColor2
	
	if _new == 0
		
		p = "--ultimate-scrollbar-"
		
		v(a)
			s("var("+ p + a +")")
		
		wh(a...)
			width: a
			min-width: a
			max-width: a
			height: a
			min-height: a
			max-height: a
		
		h = _html ? ":root, html, body, main, #main, #root" : ":root, *"
		{h}
			scrollbar-width: unset i
			scrollbar-color: unset i
		
		:root
			if _zoom
				{p}dppx: 1
			{p}width: _zoom ? "calc(%s * (1 / %s))" % (_width v(dppx)) : _width
			{p}thumb-box-shadow-width: _zoom ? "calc(%s * (1 / %s))" % (_thumbBoxShadowWidth v(dppx)) : _thumbBoxShadowWidth
			{p}thumb-border-width: _zoom ? "calc(%s * (1 / %s))" % (_thumbBorderWidth v(dppx)) : _thumbBorderWidth
			{p}thumb-border-radius: _zoom ? "calc(%s * (1 / %s))" % (_thumbBorderRadius v(dppx)) : _thumbBorderRadius
			{p}button-border-width: _zoom ? "calc(%s * (1 / %s))" % (_buttonBorderWidth v(dppx)) : _buttonBorderWidth
		
		h = _html ? ":is(html\, body\, main\, #main\, #root)" : ""
		{h}::-webkit-scrollbar
			^[0], &:vertical, &:horizontal
				wh: v(width) i
				background: none i
				border: none i
				outline: none i
				box-shadow: none i
			&-thumb, &-thumb:vertical, &-thumb:horizontal
				all: initial i
				background-color: _thumbBackgroundColor i
				background-clip: padding-box i
				border: solid transparent i
				border-radius: v(thumb-border-radius) i
				box-shadow: inset 0 0 0 v(thumb-box-shadow-width) _thumbBorderColor i
				&:hover, &:active
					all: initial i
					background-clip: padding-box i
					border: solid transparent i
					border-radius: v(thumb-border-radius) i
					box-shadow: inset 0 0 0 v(thumb-box-shadow-width) _thumbBorderColor i
				&:hover
					background-color: _thumbBackgroundColorHover i
				&:active
					background-color: _thumbBackgroundColorActive i
			&-thumb:vertical, &-thumb:vertical:hover, &-thumb:vertical:active 
				border-width: 0 v(thumb-border-width) i
			&-thumb:horizontal, &-thumb:horizontal:hover, &-thumb:horizontal:active
				border-width: v(thumb-border-width) 0 i
			&-track, &-track:vertical, &-track:horizontal
				all: initial i
				background-color: _trackBackgroundColor i
				&:hover, &:active
					all: initial i
					background-color: _trackBackgroundColor i
			&-track-piece, &-track-piece:vertical, &-track-piece:horizontal
				all: initial i
			&-corner
				all: initial i
				background-color: _cornerBackgroundColor i
		
		dataSvg = "data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' "
		if _button
			{h}::-webkit-scrollbar-button
				all: initial i
				display: none i
				&:single-button
					all: initial i
					&:vertical
						all: initial i
						&:decrement
							all: initial i
							wh: v(width) i
							border: v(button-border-width) solid transparent i
							background: no-repeat center / contain _trackBackgroundColor url(dataSvg +"width='2' height='1' fill='"+ _thumbBackgroundColor +"'><polygon points='1,0 0,1 2,1'/></svg>") i
							&:hover
								all: initial i
								wh: v(width) i
								border: v(button-border-width) solid transparent i
								background: no-repeat center / contain _trackBackgroundColor url(dataSvg +"width='2' height='1' fill='"+ _thumbBackgroundColorHover +"'><polygon points='1,0 0,1 2,1'/></svg>") i
							&:active
								all: initial i
								wh: v(width) i
								border: v(button-border-width) solid transparent i
								background: no-repeat center / contain _trackBackgroundColor url(dataSvg +"width='2' height='1' fill='"+ _thumbBackgroundColorActive +"'><polygon points='1,0 0,1 2,1'/></svg>") i
						&:increment
							all: initial i
							wh: v(width) i
							border: v(button-border-width) solid transparent i
							background: no-repeat center / contain _trackBackgroundColor url(dataSvg +"width='2' height='1' fill='"+ _thumbBackgroundColor +"'><polygon points='0,0 2,0 1,1'/></svg>") i
							&:hover
								all: initial i
								wh: v(width) i
								border: v(button-border-width) solid transparent i
								background: no-repeat center / contain _trackBackgroundColor url(dataSvg +"width='2' height='1' fill='"+ _thumbBackgroundColorHover +"'><polygon points='0,0 2,0 1,1'/></svg>") i
							&:active
								all: initial i
								wh: v(width) i
								border: v(button-border-width) solid transparent i
								background: no-repeat center / contain _trackBackgroundColor url(dataSvg +"width='2' height='1' fill='"+ _thumbBackgroundColorActive +"'><polygon points='0,0 2,0 1,1'/></svg>") i
					&:horizontal
						all: initial i
						&:decrement
							all: initial i
							wh: v(width) i
							border: v(button-border-width) solid transparent i
							background: no-repeat center / contain _trackBackgroundColor url(dataSvg +"width='1' height='2' fill='"+ _thumbBackgroundColor +"'><polygon points='0,1 1,2 1,0'/></svg>") i
							&:hover
								all: initial i
								wh: v(width) i
								border: v(button-border-width) solid transparent i
								background: no-repeat center / contain _trackBackgroundColor url(dataSvg +"width='1' height='2' fill='"+ _thumbBackgroundColorHover +"'><polygon points='0,1 1,2 1,0'/></svg>") i
							&:active
								all: initial i
								wh: v(width) i
								border: v(button-border-width) solid transparent i
								background: no-repeat center / contain _trackBackgroundColor url(dataSvg +"width='1' height='2' fill='"+ _thumbBackgroundColorActive +"'><polygon points='0,1 1,2 1,0'/></svg>") i
						&:increment
							all: initial i
							wh: v(width) i
							border: v(button-border-width) solid transparent i
							background: no-repeat center / contain _trackBackgroundColor url(dataSvg +"width='1' height='2' fill='"+ _thumbBackgroundColor +"'><polygon points='0,0 0,2 1,1'/></svg>") i
							&:hover
								all: initial i
								wh: v(width) i
								border: v(button-border-width) solid transparent i
								background: no-repeat center / contain _trackBackgroundColor url(dataSvg +"width='1' height='2' fill='"+ _thumbBackgroundColorHover +"'><polygon points='0,0 0,2 1,1'/></svg>") i
							&:active
								all: initial i
								wh: v(width) i
								border: v(button-border-width) solid transparent i
								background: no-repeat center / contain _trackBackgroundColor url(dataSvg +"width='1' height='2' fill='"+ _thumbBackgroundColorActive +"'><polygon points='0,0 0,2 1,1'/></svg>") i
		else
			{h}::-webkit-scrollbar-button
				^[0], &:single-button, &:single-button:vertical, &:single-button:horizontal
					all: initial i
					display: none i
		
		if _zoom
			zoom = ("0.1" "0.2" "0.25" "0.30000001192092896" "0.3125" "0.3333333432674408" "0.375" "0.4000000059604645" "0.4166666865348816" "0.4375" "0.45000001788139343" "0.5" "0.5250000357627869" "0.5833333730697632" "0.6000000238418579" "0.625" "0.6666666865348816" "0.699999988079071" "0.75" "0.800000011920929" "0.8333333730697632" "0.875" "0.8999999761581421" "0.9000000357627869" "0.9375" "1.0" "1.0499999523162842" "1.0500000715255737" "1.100000023841858" "1.125" "1.1666667461395264" "1.2000000476837158" "1.225000023841858" "1.25" "1.2999999523162842" "1.3125" "1.3333333730697632" "1.3499999046325684" "1.375" "1.399999976158142" "1.5" "1.5625" "1.5749999284744263" "1.600000023841858" "1.625" "1.6500000953674316" "1.6666667461395264" "1.7000000476837158" "1.75" "1.7999999523162842" "1.8000000715255737" "1.875" "1.899999976158142" "1.9250000715255737" "1.9499999284744263" "2.0" "2.0999999046325684" "2.1000001430511475" "2.125" "2.1875" "2.200000047683716" "2.25" "2.2749998569488525" "2.299999952316284" "2.3333334922790527" "2.375" "2.4000000953674316" "2.450000047683716" "2.5" "2.5500001907348633" "2.5999999046325684" "2.625" "2.6666667461395264" "2.6999998092651367" "2.700000047683716" "2.75" "2.799999952316284" "2.8499999046325684" "2.875" "2.9000000953674316" "2.9750001430511475" "3.0" "3.0625" "3.0999999046325684" "3.125" "3.1499998569488525" "3.200000047683716" "3.25" "3.299999952316284" "3.3000001907348633" "3.325000047683716" "3.375" "3.4000000953674316" "3.4499998092651367" "3.5" "3.5999999046325684" "3.6000001430511475" "3.625" "3.674999713897705" "3.700000047683716" "3.75" "3.799999952316284" "3.8500001430511475" "3.875" "3.8999998569488525" "3.9000000953674316" "4.0" "4.025000095367432" "4.050000190734863" "4.099999904632568" "4.125" "4.199999809265137" "4.200000286102295" "4.25" "4.300000190734863" "4.350000381469727" "4.375" "4.400000095367432" "4.5" "4.549999713897705" "4.599999904632568" "4.625" "4.649999618530273" "4.699999809265137" "4.724999904632568" "4.75" "4.800000190734863" "4.875" "4.900000095367432" "4.949999809265137" "5.0" "5.075000286102295" "5.100000381469727" "5.125" "5.199999809265137" "5.25" "5.375" "5.399999618530273" "5.400000095367432" "5.424999713897705" "5.5" "5.550000190734863" "5.599999904632568" "5.625" "5.699999809265137" "5.75" "5.775000095367432" "5.800000190734863" "5.850000381469727" "5.875" "5.950000286102295" "6.0" "6.125" "6.149999618530273" "6.199999809265137" "6.25" "6.299999713897705" "6.400000095367432" "6.450000286102295" "6.474999904632568" "6.599999904632568" "6.600000381469727" "6.650000095367432" "6.75" "6.800000190734863" "6.825000286102295" "6.899999618530273" "7.0" "7.049999713897705" "7.174999713897705" "7.199999809265137" "7.200000286102295" "7.34999942779541" "7.350000381469727" "7.400000095367432" "7.5" "7.52500057220459" "7.599999904632568" "7.700000286102295" "7.800000190734863" "7.875" "8.0" "8.050000190734863" "8.199999809265137" "8.22499942779541" "8.399999618530273" "8.40000057220459" "8.574999809265137" "8.600000381469727" "8.75" "8.800000190734863" "9.0" "9.199999809265137" "9.399999618530273" "9.600000381469727" "9.800000190734863" "10.0" "11.0" "12.0" "13.0" "14.0" "15.0")
			for n in zoom
				s("@media (min-resolution:"+ n +"dppx) {:root{"+ p +"dppx:"+ n +"}}")
		
		dark()
			{h}::-webkit-scrollbar
					&-thumb, &-thumb:vertical, &-thumb:horizontal
						background-color: _thumbBackgroundColor2 i
						box-shadow: inset 0 0 0 v(thumb-box-shadow-width) _thumbBorderColor2 i
						&:hover
							background-color: _thumbBackgroundColorHover2 i
							box-shadow: inset 0 0 0 v(thumb-box-shadow-width) _thumbBorderColor2 i
						&:active
							background-color: _thumbBackgroundColorActive2 i
							box-shadow: inset 0 0 0 v(thumb-box-shadow-width) _thumbBorderColor2 i
					&-track, &-track:vertical, &-track:horizontal
						background-color: _trackBackgroundColor2 i
						&:hover, &:active
							background-color: _trackBackgroundColor2 i
					&-corner
						background-color: _cornerBackgroundColor2 i
					if _button
						&-button:single-button
							&:vertical
								&:decrement
									background: no-repeat center / contain _trackBackgroundColor2 url(dataSvg +"width='2' height='1' fill='"+ _thumbBackgroundColor2 +"'><polygon points='1,0 0,1 2,1'/></svg>") i
									&:hover
										background: no-repeat center / contain _trackBackgroundColor2 url(dataSvg +"width='2' height='1' fill='"+ _thumbBackgroundColorHover2 +"'><polygon points='1,0 0,1 2,1'/></svg>") i
									&:active
										background: no-repeat center / contain _trackBackgroundColor2 url(dataSvg +"width='2' height='1' fill='"+ _thumbBackgroundColorActive2 +"'><polygon points='1,0 0,1 2,1'/></svg>") i
								&:increment
									background: no-repeat center / contain _trackBackgroundColor2 url(dataSvg +"width='2' height='1' fill='"+ _thumbBackgroundColor2 +"'><polygon points='0,0 2,0 1,1'/></svg>") i
									&:hover
										background: no-repeat center / contain _trackBackgroundColor2 url(dataSvg +"width='2' height='1' fill='"+ _thumbBackgroundColorHover2 +"'><polygon points='0,0 2,0 1,1'/></svg>") i
									&:active
										background: no-repeat center / contain _trackBackgroundColor2 url(dataSvg +"width='2' height='1' fill='"+ _thumbBackgroundColorActive2 +"'><polygon points='0,0 2,0 1,1'/></svg>") i
							&:horizontal
								&:decrement
									background: no-repeat center / contain _trackBackgroundColor2 url(dataSvg +"width='1' height='2' fill='"+ _thumbBackgroundColor2 +"'><polygon points='0,1 1,2 1,0'/></svg>") i
									&:hover
										background: no-repeat center / contain _trackBackgroundColor2 url(dataSvg +"width='1' height='2' fill='"+ _thumbBackgroundColorHover2 +"'><polygon points='0,1 1,2 1,0'/></svg>") i
									&:active
										background: no-repeat center / contain _trackBackgroundColor2 url(dataSvg +"width='1' height='2' fill='"+ _thumbBackgroundColorActive2 +"'><polygon points='0,1 1,2 1,0'/></svg>") i
								&:increment
									background: no-repeat center / contain _trackBackgroundColor2 url(dataSvg +"width='1' height='2' fill='"+ _thumbBackgroundColor2 +"'><polygon points='0,0 0,2 1,1'/></svg>") i
									&:hover
										background: no-repeat center / contain _trackBackgroundColor2 url(dataSvg +"width='1' height='2' fill='"+ _thumbBackgroundColorHover2 +"'><polygon points='0,0 0,2 1,1'/></svg>") i
									&:active
										background: no-repeat center / contain _trackBackgroundColor2 url(dataSvg +"width='1' height='2' fill='"+ _thumbBackgroundColorActive2 +"'><polygon points='0,0 0,2 1,1'/></svg>") i
	
	if _new
		:root, *
			scrollbar-color: _thumbBackgroundColor _trackBackgroundColor i
			if _thin
				scrollbar-width: thin
		
		dark()
			^[0], ^[0] *
				scrollbar-color: _thumbBackgroundColor2 _trackBackgroundColor2 i

if _dark == Enabled
	@-moz-document regexp(".+")
		.dark, .dark-bg, .dark-mode, .dark-theme, .darktheme, .theme-dark, .tw-dark, [dark], [dark="true"], [theme="dark"],
		[data-theme="dark"], [data-color-mode="dark"], [data-color-scheme="dark"], [data-scheme="dark"], [data-bs-theme="dark"], [data-ui-theme="dark"],
		[data-dark-mode="true"], [style*="color-scheme: dark"],
		html:has(>:is(.dark\\\,.dark-bg\\\,.dark-mode\\\,.dark-theme,\\\,.darktheme\\\,.theme-dark\\\,.theme-fandomdesktop-dark)),
		html:has(>:is(.theme-default\\\,.theme-contrast\\\,.skin-modern-dark)>:is(\#mastodon\\\,.admin-wrapper)),
		[data-darkreader-scheme="dark"], [native-dark-active], [ml-is-active]
			dark()
	
	@-moz-document regexp("(chrome|moz)-extension://.+")
		[data-ui-theme="dark"]
			dark()
	
	@-moz-document domain("duolingo.com")
		[data-duo-theme="dark"]
			dark()
	
	@-moz-document domain("old.reddit.com"), domain("www.reddit.com")
		.res-nightmode
			dark()
	
	@-moz-document domain("duckduckgo.com")
		[style*="--theme-bg-global: var(--color-gray100)"]
			dark()
	
	@-moz-document domain("runescape.wiki")
		html:has(>body:is(.wgl-theme-dark\\\, .wgl-theme-browntown))
			dark()
	
	@-moz-document url-prefix("https://www.google.")
		html:has([data-darkmode="true"])
			dark()
	
	@-moz-document domain("gitlab.com")
		.gl-dark
			dark()
	
	@-moz-document domain("codeberg.org")
		.theme-codeberg-dark
			dark()
	
	@-moz-document domain("threads.net"), domain("facebook.com")
		.__fb-dark-mode
			dark()

if _dark == Enabled || _dark == Manually
	if _darkWebsite != "example.com, example.org"
		unless _darkWebsite is a "string"
			error("Expected a string. DO NOT remove the quotation marks.")
		_darkWebsite = split(",", replace("^\s+|\s+(?=,)|(?<=,)\s+|\s+$", "", _darkWebsite))
		if _darkWebsite != ""
			domain = ""
			for val, key in _darkWebsite
				domain[key] = "domain('"+ val +"')"
			domain = join(", ", domain)
			s("@-moz-document "+ domain +" {")
			if _new
				:root
					dark()
			else
				dark()
			s("}")