Customizable compact left panel (sidebar) for Twitch.tv
Twitch.tv Compact Left Panel by pabli
Details
Authorpabli
LicenseMIT
Categorytwitch.tv
Created
Updated
Size9.7 kB
Statistics
Learn how we calculate statistics in the FAQ.
Failed to fetch stats.
Description
Notes
Features:
- Change width
- Show left panel on hover over the edge (useful in Theatre Mode)
- Hide offline channels
- Hide channels without unfollowing them
- Favorite channels
- Square avatars
- Hide headers, red dot
- Display lines with alternating background colors
- Change colors of background and text
- Features for "Previews (For TTV & YT)" extension:
- Put YT channels under the Followed channels
- Set the text color for favorite/youtube channels (useful when headers are hidden)
You can change all of that stuff in ⚙️ Configure
Chrome/Edge 105+, Opera 91+, Firefox 121+ or your browser has to support :has() selector.
Source code
/* ==UserStyle==
@name Twitch Compact Left Panel
@namespace https://github.com/pabli24
@version 2.0.4
@description Twitch.tv Smaller sidebar with many customization options
@author Pabli (https://ko-fi.com/pabli)
@license MIT
@preprocessor stylus
@var checkbox _compact "Compact Left Panel" 1
@var number _width "Width (rem)" [16, -1, null, 0.1, "rem"]
@var number _widthCollapse "Width when collapsed (rem)" [4, -1, null, 0.1, "rem"]
@var select _showOnHover "Show left panel on hover" ["Disabled", "Enabled", "thm:In Theatre Mode*"]
@var number _showOnHoverOpacity "➥ Opacity on hover" [0.9, 0, 1, 0.1]
@var checkbox _hideChannels "❌ Hide channels" 1
@var text _hiddenChannels "" "'ChannelName1, ChannelName2'"
@var checkbox _favorite "⭐ Favorite channels" 1
@var text _favChannels "" "'ChannelName1, ChannelName2'"
@var checkbox _favTop "Favorite channels at the top of the following list (Extension that can 'Auto Expand Followed Channels List (show more)' is recommended)" 1
@var color _favColor "Favorite channels name text color" #ffd700
@var text _favIcon "Favorite channels icon (e.g. ★ ♥ 🖈 📌 ❤️)" "'⭐'"
@var number _squareAvatars "Square avatars □" [0, -1, 50, 1, "%"]
@var checkbox _hideCollapse "Hide Collapse button ⟻" 0
@var checkbox _hideHeaders "Hide Headers" 1
@var checkbox _hideLiveDot "Hide Red dot 🔴" 1
@var checkbox _hideOfflineChannels "Hide Offline channels" 0
@var checkbox _hideStories "Hide Stories" 0
@var checkbox _bgOdd "Alternating Background (can impact performance)" 0
@var color _bgOddColor "" rgba(128, 128, 128, .06)
@var checkbox _bg "Background color" 0
@var color _bgColor "" #000
@var checkbox _bgOnHover "Background color on hover" 0
@var color _bgColorOnHover "" #222
@var checkbox _isNameColor "Channel name text color" 0
@var color _nameColor "" #fff
@var checkbox _isViewsColor "Viewer count text color" 1
@var color _viewsColor "" #ff8282
@var checkbox _isGameColor "Game name text color" 0
@var color _gameColor "" #aaa
@var number _h0 "▼ --- Previews (For TTV & YT) EXTENSION --- ▼" [0,0,0]
@var checkbox _isPreviewsFavColor "Channel name text color in 'Favorite Channels'" 1
@var color _previewsFavColor "" #ffd700
@var checkbox _isPreviewsYTColor "Channel name text color in 'YouTube Channels'" 1
@var color _previewsYTTColor "" #ff4e45
@var checkbox _previewsYTUnder "Put YouTube channels under the Followed channels" 0
@var number _p0 "☕ ko-fi.com/pabli - If you like this style and would like to support me, you can buy me a coffee. Thank You!" [0,0,0,1]
==/UserStyle== */
@-moz-document domain("twitch.tv") {
i = !important
if _width != -1 {
.side-nav {
width: _width
}
}
if _widthCollapse != -1 {
.side-nav--collapsed:not(.side-nav--hover-exp) {
width: _widthCollapse
}
}
if _hideHeaders {
#tp_favorites_section, #tp_YTsidebar_section {
> div > [style*="color: grey"] {
display: none i
}
}
.followed-side-nav-header, .side-nav__title, .side-nav-header {
display: none i
}
}
if _hideCollapse {
.collapse-toggle {
display: none i
}
}
if _isViewsColor {
.side-nav-card__live-status > div > div > span {
color: _viewsColor i
}
}
if _hideLiveDot {
.tw-channel-status-indicator {
display: none i
}
}
if _compact {
.collapse-toggle {
unless _hideHeaders {
top: 2rem i
}
right: -1.3rem i
}
// dots ...
[data-a-target="side-nav-card-metadata"] > div > p {
text-overflow: clip i
overflow: unset i
}
.side-nav-header {
margin: 0 0.2rem i
padding-top: 0 i
}
.followed-side-nav-header, .followed-side-nav-header--expanded, [data-a-target="side-nav-header-expanded"] {
margin: 0 i
}
// For you
#side-nav > div > div > div.side-nav__title {
display: none
}
#side-nav > div > div > div[class*="storiesLeftNavSection"] {
margin-top: 0 i
height: 3.4rem i
button > div {
margin: 0 i
}
}
[data-a-target="side-nav-card-metadata"] {
margin-left: 0.2rem i
}
.side-nav-card__link {
height: 3.4rem
padding: 0 0.2rem i
}
.side-nav-card__live-status {
min-width: 0 i
margin-left: 0 i
}
.kaXoQh {
margin-left: 0.2rem i
}
.side-nav-card__link > * {
height: 100%
margin: 0 i
}
[data-a-target="side-nav-game-title"] > p {
position: absolute
}
// show less show more
.side-nav-show-more-toggle__button {
padding: 0 i
}
#side-nav\.find-friends {
height: 2.2rem i
}
// sponsored stream
.side-nav-card__link--promoted-followed {
.tw-image:not(.tw-image-avatar),
[style*="background-color:"]
.side-nav-promoted-followed-card__sponsorship {
display: none i
}
> div > div {
padding-top: 0 i
}
.side-nav-promoted-followed-card__title {
position: absolute
top: -6px
left: 34px
}
.side-nav-promoted-followed-card__content {
position: absolute
top: 13px
left: 34px
}
}
// hype train
.side-nav-card-hype-train-bottom {
margin: 0 i
padding: 0 i
> :not(div:has(>[class*="hype-train-icon__"])) {
display: none i
}
[class*="hype-train-icon__"] {
position: absolute
right: 0
top: 15px
}
}
}
if _showOnHover != Disabled {
thmode = _showOnHover == thm ? ":has(.channel-root__scroll-area--theatre-mode)" : ""
body{thmode} {
> .previews_app_previewDiv {
z-index: 9999 i
}
div:has(>.side-nav), div[style="z-index: 10;"] {
z-index: 99999 i
}
.side-nav, .side-nav--collapsed:not(.side-nav--hover-exp) {
position: fixed i
top: 0 i
width: 1rem
opacity: 0
transition: width 0.3s, opacity 0.5s
&:hover {
width: _width
opacity: _showOnHoverOpacity
}
}
.side-nav--collapsed:not(.side-nav--hover-exp):hover {
width: _widthCollapse
}
}
}
if _hideOfflineChannels {
#side-nav > div > div > div > div > div:has(.side-nav-card__avatar--offline) {
display none i
}
}
if _hideStories {
#side-nav > div > div > div[class*="storiesLeftNavSection"] {
display none i
}
}
if _squareAvatars != -1 {
.tw-image-avatar, .tw-avatar, .tw-halo, .tw-halo::before {
border-radius: _squareAvatars i
}
if _squareAvatars != 50 {
#side-nav > div > div > div[class*="storiesLeftNavSection"] > button > div > div > div > div {
border-radius: _squareAvatars i
}
}
}
if _isNameColor {
#side-nav .side-nav-card__title > p,
#side-nav [data-a-target="side-nav-card-metadata"] p {
--color-text-alt: _nameColor
color: _nameColor i
}
}
if _isGameColor {
#side-nav .side-nav-card__metadata > p {
--color-text-alt-2: _gameColor
color: _gameColor i
}
}
if _bg {
.tw-root--theme-dark .side-nav__overlay-wrapper, .side-nav__overlay-wrapper, .side-bar-contents {
background: _bgColor i
}
}
if _bgOdd {
//.side-nav-card[style="display: none;"] --> Previews (For TTV & YT) Sidebar Favorite Channels - Hide favorite channels from followed list
#side-nav .tw-transition-group > div:nth-child(odd of :not(:has(:is({t} .side-nav-card[style="display: none;"])))) {
background: _bgOddColor i
}
}
if _bgOnHover {
.tw-root--theme-dark .side-nav-card__link:hover, .side-nav-card__link:hover {
background: _bgColorOnHover i
}
}
// --- Previews (For TTV & YT) extension ---
body > .previews_app_previewDiv:not([style*="margin-left: 6rem"]) {
margin-left: _width + 1 i
}
.tp-tooltip-sidebar {
height: auto
}
if _isPreviewsFavColor {
#tp_favorites_section [data-a-target="side-nav-title"] {
color: _previewsFavColor i
}
}
if _isPreviewsYTColor {
#tp_YTsidebar_section [data-a-target="side-nav-title"] {
color: _previewsYTColor i
}
}
if _previewsYTUnder {
#side-nav > div > div {
display: flex
flex-direction: column
}
#tp_favorites_section {
order: -5 i
}
#side-nav > div > div > div:not([aria-label]) + div[aria-label]:not([id]) {
order: -4 i
}
#side-nav > div > div > div:has(.followed-side-nav-header):not([id]) {
order: -4 i
}
#tp_YTsidebar_section {
order: -3 i
}
}
filter(a) {
a = split(',', replace('^\s+|\s+(?=,)|(?<=,)\s+|\s+$', '', a))
b = ()
for n in a {
if n != '' {
push(b, n)
}
}
return b
}
if _hideChannels {
t = ()
if _hiddenChannels != 'ChannelName1, ChannelName2' {
_hiddenChannels = filter(_hiddenChannels)
for n in _hiddenChannels {
push(t,'[href="/'+ n +'" i]')
}
t = join("\,", t)
#side-nav .side-nav-section > div > .tw-transition:has(:is({t})) {
display none i
}
}
}
if _favorite {
t = ()
if _favChannels != 'ChannelName1, ChannelName2' {
_favChannels = filter(_favChannels)
for n in _favChannels {
push(t,'[href="/'+ n +'" i]')
}
t = join("\,", t)
if _favTop {
#side-nav .side-nav-section:has(> .followed-side-nav-header) > div.tw-transition-group {
display: flex
flex-direction: column
}
#side-nav .side-nav-section:has(> .followed-side-nav-header) > div.tw-transition-group .tw-transition:has(:is({t})) {
order: -1 i
}
}
#side-nav .side-nav-section:has(> .followed-side-nav-header) > div.tw-transition-group .tw-transition:has(:is({t})) :is(.side-nav-card__title, [data-a-target="side-nav-card-metadata"] > div:first-child) > p {
--color-text-alt: _favColor
color: _favColor i
}
if _favIcon != "" {
#side-nav .side-nav-section:has(> .followed-side-nav-header) > div.tw-transition-group .tw-transition:has(:is({t})) :is(.side-nav-card__title, [data-a-target="side-nav-card-metadata"] > div:first-child) > p:first-child::before {
content: _favIcon
}
}
}
}
}