Как я отвоевал свой интерфейс у YouTube: битва за сетку видео на чистом CSS
Современный веб всё чаще решает за пользователя, как должен выглядеть интерфейс. Алгоритмы и скрипты динамически пересчитывают макеты, подгоняя их под усредненные метрики. Но когда инструменты становятся частью твоей повседневной жизни, хочется полного контроля. Моя битва с YouTube началась с двух, казалось бы, простых желаний: я хотел видеть ровно 5 видео в ряду на главной странице и удобную сетку 3x3 в рекомендациях после окончания ролика. Спойлер: скрипты Google сопротивлялись до последнего. Для внедрения своих CSS-правил я использую отличное расширение Enhancer for YouTube — в его настройках есть удобный блок «Пользовательская тема», куда можно внедрить любой код.
Акт первый: Синдром «уползающей» сетки
Настроить 5 колонок на главной странице с помощью пользовательского CSS несложно — достаточно задать контейнеру grid-template-columns: repeat(5, 1fr).
Но при прокрутке страницы вниз начиналась магия: сетка плавно превращалась в 4,5 видео, а затем в 4. Правый край просто обрезался. Проблема крылась в скрытом конфликте: JS-движок YouTube (Polymer) динамически вешал на карточки роликов жесткий min-width. Когда грид пытался сжать элементы, чтобы уместить пятерку, min-width упирался.
Решение: Пришлось не только жестко сбросить min-width: 0 !important для самих карточек, но и «хакнуть» CSS-переменные самого YouTube (--ytd-rich-grid-items-per-row: 5), чтобы JS-логика смирилась с новой реальностью. Для верности строки были развернуты через display: contents, объединяя всё в единый монолитный грид.
Акт второй: Анархия конечных заставок
Вторая проблема ждала в конце видео. По умолчанию YouTube предлагает скудную полоску из 3 рекомендованных видео (или накладывает авторские элементы). Мне нужна была полноценная видеостена 3x3.
Здесь YouTube использует тяжелую артиллерию: скрипты высчитывают absolute координаты (top, left) для каждой плитки в зависимости от размера плеера. Лишние плитки просто скрываются.
Решение:
К черту абсолютное позиционирование! Контейнер
.videowall-endscreenбыл переведен во Flexbox. У каждой плитки я принудительно отключил координаты (top: auto !important, left: auto !important) и задал им ширину в 32% и высоту в 28%. Движок продолжал пытаться расставлять элементы по координатам, но Flexbox игнорировал их, аккуратно складывая плитки в идеальную матрицу из 9 элементов.
Акт третий: Бой с тенью (и темным экраном)
Сетка 3x3 технически заработала, но YouTube нанес ответный удар.
Во-первых, по окончании просмотра видео вместо ожидаемой сетки вылезал Pause Overlay — узкая раздражающая полоска всего с тремя роликами по центру экрана. Меня это очень сильно напрягало, так как я привык к классической и информативной сетке 3х3. Пришлось выжечь классы этой полоски через display: none !important, чтобы она не перекрывала мою видеостену.
Во-вторых, авторские элементы (End Cards) ложились поверх моей сетки, превращая экран в кашу. Их тоже пришлось скрыть.
И наконец, финальный босс: пытаясь сделать сетку более читаемой, я задал ей темный фон background: rgba(0, 0, 0, 0.8). Но контейнер оказался «липким». При переключении на следующее видео этот полупрозрачный слой не всегда исчезал, накладывая на ролик эффект тонированного стекла. Пришлось отказаться от фона в пользу transparent и добавить text-shadow для текста, чтобы он читался на любом фоне.
Итог
Мы привыкли мириться с тем, что нам предлагают корпорации. Но пара строк правильного кода способна вернуть автономию и сделать цифровое пространство по-настоящему удобным. Ниже приведен полный CSS-код моей победы, который необходимо вставить в блок кастомных стилей расширения Enhancer for YouTube.
Полный код решения:
/* ==========================================================================
ЧАСТЬ 1: ГЛАВНАЯ СТРАНИЦА (Стабильная сетка из 5 видео)
========================================================================== */
ytd-rich-grid-renderer {
--ytd-rich-grid-items-per-row: 5 !important;
--ytd-rich-grid-posts-per-row: 5 !important;
--ytd-rich-grid-min-item-width: 0px !important;
}
ytd-rich-grid-row,
ytd-rich-grid-row > #contents {
display: contents !important;
}
ytd-rich-grid-renderer > #contents {
display: grid !important;
grid-template-columns: repeat(5, 1fr) !important;
gap: 16px !important;
width: 94% !important;
margin: 0 auto !important;
max-width: none !important;
}
/* Сброс min-width предотвращает "сползание" при скролле */
ytd-rich-item-renderer {
width: 100% !important;
margin: 0 !important;
min-width: 0 !important;
max-width: none !important;
}
/* Скрываем мусор на главной (Shorts, баннеры, рекламу) */
ytd-rich-section-renderer,
ytd-statement-banner-renderer,
ytd-primetime-promo-renderer,
ytd-rich-shelf-renderer,
#masthead-ad {
display: none !important;
}
#contents.ytd-rich-grid-renderer {
padding-top: 10px !important;
}
/* Спиннер загрузки на всю ширину, чтобы не ломал грид */
ytd-continuation-item-renderer {
grid-column: 1 / -1 !important;
}
/* ==========================================================================
ЧАСТЬ 2: КОНЕЦ ВИДЕО (Сетка рекомендаций 3x3)
========================================================================== */
/* Контейнер видеостены переводим во Flexbox */
.html5-endscreen.videowall-endscreen {
display: flex !important;
flex-wrap: wrap !important;
justify-content: center !important;
align-content: center !important;
padding: 2% !important;
opacity: 1 !important;
visibility: visible !important;
z-index: 100 !important;
background: transparent !important;
pointer-events: auto !important;
}
/* Отменяем абсолютное позиционирование JS и задаем размеры плиткам */
.html5-endscreen .ytp-videowall-still {
display: block !important;
visibility: visible !important;
opacity: 1 !important;
position: relative !important;
top: auto !important;
left: auto !important;
transform: none !important;
width: 32% !important;
height: 28% !important;
margin: 0.5% !important;
}
/* Подгонка картинок */
.html5-endscreen .ytp-videowall-still-image {
border-radius: 4px !important;
background-size: cover !important;
opacity: 1 !important;
display: block !important;
}
/* Скрываем аватарки авторов для экономии места */
.ytp-videowall-still-info-author {
display: none !important;
}
/* Форматирование заголовков с тенью для читаемости */
.ytp-videowall-still-info-title {
font-size: 110% !important;
line-height: 1.2 !important;
max-height: 2.4em !important;
overflow: hidden !important;
white-space: normal !important;
text-shadow: 1px 1px 2px black !important;
}
/* ==========================================================================
ЧАСТЬ 3: ОЧИСТКА ИНТЕРФЕЙСА (Удаление лишних оверлеев)
========================================================================== */
/* Убираем узкую полоску "Больше видео" по окончании ролика */
.ytp-pause-overlay,
.ytp-pause-overlay-container {
display: none !important;
}
/* Скрываем элементы, добавленные авторами (перекрывают сетку) */
.ytp-ce-element,
.ytp-ce-covering-overlay {
display: none !important;
}
/* Скрываем окно автовоспроизведения "Следующее видео" */
.ytp-upnext {
display: none !important;
}
/* Скрываем кнопки навигации в эндскрине */
.ytp-endscreen-previous,
.ytp-endscreen-next {
display: none !important;
}