Restores scrollable fullscreen mode. Aggressively neutralizes all grid-state classes to prevent control bar freezing and hiding.
// ==UserScript==
// @name YouTube Restore Scrollable Fullscreen
// @namespace burak-tools
// @version 1.97
// @description Restores scrollable fullscreen mode. Aggressively neutralizes all grid-state classes to prevent control bar freezing and hiding.
// @author Waldoocs (https://x.com/Waldoocs) https://github.com/Waldoocs
// @match https://www.youtube.com/*
// @run-at document-idle
// @grant GM_addStyle
// @grant GM.addStyle
// @license MIT
// @compatible firefox
// @compatible chrome
// ==/UserScript==
(function() {
'use strict';
const addStyle = (css) => {
if (typeof GM_addStyle !== 'undefined') {
GM_addStyle(css);
} else if (typeof GM !== 'undefined' && GM.addStyle) {
GM.addStyle(css);
} else {
const style = document.createElement('style');
style.type = 'text/css';
style.textContent = css;
document.head.appendChild(style);
}
};
addStyle(`
/* Base layout restorations for scrolling */
ytd-app[fullscreen] {
overflow: auto !important;
}
ytd-app[scrolling] {
position: absolute !important;
top: 0 !important;
left: 0 !important;
right: calc((var(--ytd-app-fullerscreen-scrollbar-width) + 1px)*-1) !important;
bottom: 0 !important;
overflow-x: auto !important;
}
ytd-watch-flexy[fullscreen] #single-column-container.ytd-watch-flexy,
ytd-watch-flexy[fullscreen] #columns.ytd-watch-flexy {
display: flex !important;
}
/* Completely hide the grid and its invisible click-stealing overlays */
.ytp-fullscreen-grid,
.ytp-fullscreen-grid-stills-container,
.ytp-fullscreen-grid-buttons-container,
.ytp-fullscreen-grid-hover-overlay {
display: none !important;
visibility: hidden !important;
opacity: 0 !important;
pointer-events: none !important;
}
/* Force grid CSS math variables to zero */
.html5-video-player {
--ytp-grid-scroll-percentage: 0 !important;
--ytp-grid-peek-height: 0px !important;
}
`);
// Master blacklist of all classes YouTube uses to trigger grid states
const GRID_CLASSES = [
'ytp-grid-scrollable',
'ytp-fullscreen-grid-peeking',
'ytp-fullscreen-grid-active',
'ytp-grid-scrolling'
];
// Synchronous function to strip grid classes instantly
function stripGridClasses() {
const player = document.querySelector('.html5-video-player');
if (!player) return;
// Loop through the blacklist and remove any offending classes
GRID_CLASSES.forEach(cls => {
if (player.classList.contains(cls)) {
player.classList.remove(cls);
}
});
}
function init() {
stripGridClasses();
// Observer fires instantly to prevent UI lockups before the screen paints
const playerObserver = new MutationObserver(stripGridClasses);
// Wait for player to exist before attaching
const checkPlayer = setInterval(() => {
const player = document.querySelector('.html5-video-player');
if (player) {
clearInterval(checkPlayer);
playerObserver.observe(player, {
attributes: true,
attributeFilter: ['class']
});
}
}, 500);
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();