Skip to content

Instantly share code, notes, and snippets.

@klydeinside
Last active August 12, 2026 05:19
Show Gist options
  • Select an option

  • Save klydeinside/21441df99f4d0f116ee22838295cd76e to your computer and use it in GitHub Desktop.

Select an option

Save klydeinside/21441df99f4d0f116ee22838295cd76e to your computer and use it in GitHub Desktop.
Twitch userscripts - Following Directory Narrow Grid
// ==UserScript==
// @name Twitch – Following Directory Narrow Grid
// @namespace https://cody-tools.local
// @version 1.3
// @description Forces the twitch.tv/directory/following/live grid into 2 or 3 columns so everything stays close to the left instead of spreading across the whole screen, with the hover lift/glow from the Live Follows Grid script. Runs sitewide so it's already active when you arrive via client-side navigation (e.g. the Live Follows Shortcut button), not just on a hard page load of the directory URL.
// @match https://www.twitch.tv/*
// @grant GM_setValue
// @grant GM_getValue
// @updateURL https://gist.githubusercontent.com/klydeinside/21441df99f4d0f116ee22838295cd76e/raw/twitch-following-narrow-grid.user.js
// @downloadURL https://gist.githubusercontent.com/klydeinside/21441df99f4d0f116ee22838295cd76e/raw/twitch-following-narrow-grid.user.js
// ==/UserScript==
(function () {
'use strict';
const STYLE_ID = 'lfDirNarrowGridStyle';
const TOGGLE_ID = 'lfDirNarrowGridToggle';
const COLS_KEY = 'lfDirColumns';
function getCols() {
const v = GM_getValue(COLS_KEY, 3);
return v === 2 ? 2 : 3;
}
function setCols(n) {
GM_setValue(COLS_KEY, n);
applyStyle();
updateToggleLabel();
}
function applyStyle() {
let style = document.getElementById(STYLE_ID);
if (!style) {
style = document.createElement('style');
style.id = STYLE_ID;
document.head.appendChild(style);
}
const cols = getCols();
const pct = (100 / cols).toFixed(4);
style.textContent = `
.tw-tower {
justify-content: flex-start !important;
}
.tw-tower > div {
box-sizing: border-box !important;
flex: 0 0 ${pct}% !important;
width: ${pct}% !important;
max-width: ${pct}% !important;
}
.tw-tower article {
border-radius: 8px;
transition:
transform 0.18s cubic-bezier(0.16, 1, 0.3, 1),
box-shadow 0.18s cubic-bezier(0.16, 1, 0.3, 1),
border-radius 0.18s ease;
}
.tw-tower article:hover {
transform: translateY(-4px) scale(1.02);
box-shadow:
0 12px 32px rgba(145,71,255,0.35),
0 0 0 1px rgba(145,71,255,0.5);
position: relative;
z-index: 2;
}
`;
}
function removeStyle() {
const style = document.getElementById(STYLE_ID);
if (style) style.remove();
}
function updateToggleLabel() {
const btn = document.getElementById(TOGGLE_ID);
if (btn) btn.textContent = `Grid: ${getCols()} col`;
}
function createToggle() {
if (document.getElementById(TOGGLE_ID)) return;
const btn = document.createElement('button');
btn.id = TOGGLE_ID;
btn.style.cssText = `
position: fixed;
bottom: 20px;
right: 20px;
z-index: 999999;
padding: 8px 14px;
background: #9147ff;
color: #fff;
border: none;
border-radius: 9999px;
font-size: 13px;
font-weight: 700;
font-family: Arial, sans-serif;
cursor: pointer;
box-shadow: 0 4px 12px rgba(0,0,0,0.35);
`;
btn.onclick = () => setCols(getCols() === 3 ? 2 : 3);
document.body.appendChild(btn);
updateToggleLabel();
}
function removeToggle() {
const btn = document.getElementById(TOGGLE_ID);
if (btn) btn.remove();
}
function isFollowingDirectory() {
return location.pathname.replace(/\/+$/, '') === '/directory/following/live';
}
function tick() {
if (isFollowingDirectory()) {
applyStyle();
createToggle();
} else {
removeStyle();
removeToggle();
}
}
let tickScheduled = false;
function scheduleTick() {
if (tickScheduled) return;
tickScheduled = true;
requestAnimationFrame(() => {
tickScheduled = false;
tick();
});
}
const origPushState = history.pushState;
history.pushState = function (...args) {
origPushState.apply(this, args);
scheduleTick();
};
window.addEventListener('popstate', scheduleTick);
const observer = new MutationObserver(scheduleTick);
observer.observe(document.body, { childList: true, subtree: true });
tick();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment