Слайдер в стиле Netflix — 3 варианта (CSS / JS)
Основной поиск: “слайдер в стиле Netflix”. Варианты запросов: “Netflix slider CSS”, “горизонтальный карусель CSS JS”, “hover preview slider”, “carousel accessibility”.
Что в этом материале
- Три готовых варианта реализации: навигационные кнопки (CSS), горизонтальная полоса прокрутки (CSS) и кнопки + JS.
- Полные примеры кода (HTML, CSS, JS) — копируйте и подставляйте свои изображения.
- Рекомендации по доступности, производительности и адаптивности.
Важно: все приведённые блоки можно адаптировать под ваш фреймворк (React/Vue) — в статье есть советы по интеграции и тестам.

1. Netflix-стиль: с навигационными кнопками (чистый CSS)
Ниже — минимальный HTML + CSS, где каждая секция — независимый «слайд», а кнопки реализованы как якоря для плавного скролла.
На наведении элемент масштабируется и отодвигает соседей:
HTML
CSS
html {
scroll-behavior: smooth;
}
body {
margin: 0;
background-color: #000;
}
h1 {
font-family: Arial;
color: red;
text-align: center;
}
.wrapper {
display: grid;
grid-template-columns: repeat(3, 100%);
overflow: hidden;
scroll-behavior: smooth;
}
.wrapper section {
width: 100%;
position: relative;
display: grid;
grid-template-columns: repeat(5, auto);
margin: 20px 0;
}
.wrapper section .item {
padding: 0 2px;
transition: 250ms all;
}
.wrapper section .item:hover {
margin: 0 40px;
transform: scale(1.2);
}
.wrapper section a {
position: absolute;
color: #fff;
text-decoration: none;
font-size: 6em;
background: black;
width: 80px;
padding: 20px;
text-align: center;
z-index: 1;
}
.wrapper section a:nth-of-type(1) {
top: 0;
bottom: 0;
left: 0;
background: linear-gradient(-90deg, rgba(0, 0, 0, 0) 0%, black 100%);
}
.wrapper section a:nth-of-type(2) {
top: 0;
bottom: 0;
right: 0;
background: linear-gradient(90deg, rgba(0, 0, 0, 0) 0%, black 100%);
}
@media only screen and (max-width: 600px) {
a.arrow__btn {
display: none;
}
}2. Netflix-стиль: горизонтальная полоса прокрутки (чистый CSS)
Проще вёрстка: блок с white-space и inline-block элементами. Полоса прокрутки даёт привычный UX на десктопе и мобильных браузерах.
На наведении карточка увеличивается, а остальные становятся полупрозрачными.
HTML
Netflix Carousel
Pure CSS Netflix Video Carousel
Top Gear
CSS
body,
html {
padding: 0 10px;
margin: 0;
background: #0e0f11;
color: #ecf0f1;
font-family: 'Open Sans', sans-serif;
min-height: 100vh;
display: flex;
flex-direction: row;
align-items: center;
width: 100%;
}
* {
box-sizing: border-box;
}
h1 {
text-align: center;
}
.contain {
width: 100%;
}
.row {
overflow: scroll;
overflow-y: hidden;
width: 100%;
}
.row__inner {
transition: 450ms transform;
font-size: 0;
white-space: nowrap;
margin: 70.3125px 0;
padding-bottom: 10px;
}
.tile {
position: relative;
display: inline-block;
width: 250px;
height: 140.625px;
margin-right: 10px;
font-size: 20px;
cursor: pointer;
transition: 450ms all;
transform-origin: center left;
}
.tile__img {
width: 250px;
height: 140.625px;
-o-object-fit: cover;
object-fit: cover;
}
.tile__details {
position: absolute;
bottom: 0;
left: 0;
right: 0;
top: 0;
font-size: 10px;
opacity: 0;
background: linear-gradient(to top, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0) 100%);
transition: 450ms opacity;
}
.tile:hover .tile__details {
opacity: 1;
}
.row__inner:hover {
transform: translate3d(-62.5px, 0, 0);
}
.row__inner:hover .tile {
opacity: 0.3;
}
.row__inner:hover .tile:hover {
transform: scale(1.5);
opacity: 1;
}
.tile:hover~.tile {
transform: translate3d(125px, 0, 0);
}3. Netflix-стиль: навигация с JavaScript (CSS + JS)
Этот вариант добавляет явные кнопки влево/вправо и контролирует видимость кнопок в зависимости от положения прокрутки.
На наведении карточки увеличиваются, описание и иконка воспроизведения плавно появляются.
HTML
Netflix Carousel
Going In Style
Lorem ipsum dolor sit amet, lorem ipsum dolor sit amet.
CSS
body {
background-color: #343434;
margin: 0;
padding: 0;
margin: auto;
}
div.items {
white-space: nowrap;
flex-flow: row nowrap;
justify-content: space-between;
overflow: hidden;
display: flex;
align-self: center;
}
div.items:hover .item {
opacity: 0.3;
}
div.items:hover .item:hover {
opacity: 1;
}
div.control-container {
height: 300px;
position: absolute;
width: 100%;
overflow: hidden;
box-sizing: border-box;
}
div.container {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
min-height: 300px;
position: relative;
width: 100%;
box-sizing: border-box;
overflow: hidden;
display: flex;
flex-flow: row nowrap;
justify-content: center;
}
/* ... остальной CSS как в примере ... */JavaScript
function MouseWheelHandler(e, element) {
var delta = 0;
if (typeof e === 'number') {
delta = e;
} else {
if (e.deltaX !== 0) {
delta = e.deltaX;
} else {
delta = e.deltaY;
}
e.preventDefault();
}
element.scrollLeft -= (delta);
}
window.onload = function() {
var carousel = {};
carousel.e = document.getElementById('carousel');
carousel.items = document.getElementById('carousel-items');
carousel.leftScroll = document.getElementById('left-scroll-button');
carousel.rightScroll = document.getElementById('right-scroll-button');
carousel.items.addEventListener("mousewheel", handleMouse, false);
carousel.items.addEventListener("scroll", scrollEvent);
carousel.leftScroll.addEventListener("click", leftScrollClick);
carousel.rightScroll.addEventListener("click", rightScrollClick);
setLeftScrollOpacity();
setRightScrollOpacity();
function handleMouse(e) {
MouseWheelHandler(e, carousel.items);
}
function leftScrollClick() {
MouseWheelHandler(100, carousel.items);
}
function rightScrollClick() {
MouseWheelHandler(-100, carousel.items);
}
function scrollEvent(e) {
setLeftScrollOpacity();
setRightScrollOpacity();
}
function setLeftScrollOpacity() {
if (isScrolledAllLeft()) {
carousel.leftScroll.style.opacity = 0;
} else {
carousel.leftScroll.style.opacity = 1;
}
}
function isScrolledAllLeft() {
if (carousel.items.scrollLeft === 0) {
return true;
} else {
return false;
}
}
function isScrolledAllRight() {
if (carousel.items.scrollWidth > carousel.items.offsetWidth) {
if (carousel.items.scrollLeft + carousel.items.offsetWidth === carousel.items.scrollWidth) {
return true;
}
} else {
return true;
}
return false;
}
function setRightScrollOpacity() {
if (isScrolledAllRight()) {
carousel.rightScroll.style.opacity = 0;
} else {
carousel.rightScroll.style.opacity = 1;
}
}
}Примечание: код в статье распространяется под лицензией MIT.
Практические советы и расширенная помощь
Когда этот подход не подойдёт
- Если требуется сложная интерактивность (динамическая подгрузка контента, drag-and-drop внутри карусели) — лучше использовать компонентный подход (React/Vue) с виртуализацией.
- Если нужно 100% кроссбраузерное поведение старых IE — некоторые CSS-фичи и event ‘mousewheel’ могут не работать.
Альтернативные подходы
- Использовать библиотеку (Splide, Swiper, Flickity) — берёт на себя навигацию, инерцию, слайды и accessibility.
- Реализовать виртуализированную карусель для тысяч элементов (подгружать только видимые карточки).
Мини-методология внедрения (быстрая дорожная карта)
- Выбрать вариант (CSS-only / JS-controls / библиотека).
- Подготовить структуру данных и изображения (установить одинаковый aspect ratio).
- Вставить HTML и стили, заменить src на ваши миниатюры.
- Проверить на тач-устройствах, клавиатуре и скринридерах.
- Добавить lazy-loading и оптимизацию изображений.
- Протестировать производительность и UX на медиаванах.
Критерии приёмки
- Работает прокрутка мышью и свайп на мобильных.
- При наведении элемент масштабируется плавно, без мерцаний.
- Навигационные кнопки видимы/скрыты корректно в начале/конце.
- ARIA-метки и keyboard navigation (Tab/Enter/Arrow) протестированы.
Чеклист для разработчика
- Фиксированные размеры миниатюр или контейнера для стабильности лейаута.
- object-fit: cover для изображений.
- lazy-loading изображений (loading=”lazy”).
- aria-label на кнопках навигации.
- Поддержка тача (touch events) если нужно.
- Тесты на FF/Chrome/Safari/iOS/Android.
Доступность и SEO
- Добавьте aria-roledescription и aria-live при динамическом изменении контента.
- Кнопки должны иметь aria-label=”Сдвинуть влево”/“Сдвинуть вправо”.
- Для SEO — убедитесь, что важные данные (названия) доступны в DOM, даже если скрыты стилями.
Оптимизация производительности
- Используйте оптимизированные WebP или адаптивные srcset.
- Делайте lazy-loading для изображений вне вьюпорта.
- Снижайте repaint: используйте transform/opacity вместо margin/width там, где возможно.
Совместимость и миграция
- Для React — перенести HTML в JSX, управлять прокруткой через ref и использовать onWheel.
- Для серверного рендеринга — рендерить контейнер и заставку, анимации подключать на клиенте.
Итог
- Три простых варианта слайдера покрывают большинство задач: от простого CSS до управляемого JS.
- Выберите подходящую стратегию в зависимости от объёма контента и требований к доступности.
Короткое объявление: если нужен адаптированный компонент под ваш проект (React/Vue, lazy-loading, ARIA), я могу помочь составить конкретный план и пример кода.
Похожие материалы
Почему Apple замедляет старые iPhone — что делать
Как создать запоминающийся логотип
Виджет ChatGPT на Android — как установить и использовать
Отключить Bixby на Samsung Galaxy S20
Как смотреть UFC 286 онлайн — США, подписки и VPN