Как загружать видео-ролики по клику без JavaScript
Веб-разработчики прекрасно знают, что любое встроенное видео, например, с RuTube или подобного видео-хостинга тормозит загрузку веб-страницы, потому что видеоплеер, который будет использоваться для воспроизведения этого ролика грузит лишние ресурсы, даже если видео в итоге не посмотрят.
Известные подходы решения данной проблемы, например, (откроется в новой вкладке)<lite-youtube> хорош, если видео размещено ниже первого экрана, т.е. за пределами видимой области. Если же оно в видимой зоне — возможен сдвиг макета (CLS), что потенциально грозит санкциями для такой страницы при поисковой выдаче.
В этой статье детально разберем метод, который на сегодняшний день является лучшим решением оптимизированной загрузки видео на страницу по клику без JavaScript, даже, если оно находится в видимой зоне, с использованием только HTML и CSS.
Демонстрация работы метода
Элемент details: идеальное решение проблемы
В статье об HTML-теге <details> мы подробно разбирали работу этого элемента.
<details>
<summary> <!-- Все что здесь по умолчанию видно всегда --> </summary>
<!-- Все что здесь показывается/скрывается при клике на summary -->
</details>
Здесь же коротко напомним самое главное: details и summary позволяют сделать аккордеон без JavaScript. При клике на summary атрибут open добавляется к details и его контент показывается. При повторном клике контент скрывается.
То есть, по умолчанию весь контент скрыт внутри details кроме summary. Это идеальный способ показывать что-то по клику пользователя, не задействуя JavaScript!
Для решения нашей проблемы: оптимизированной загрузки видео, мы можем поместить iframe с видео как контент в details, а картинку-превью (постер) для него в summary.
<details>
<summary> <!-- Сюда помещаем постер --> </summary>
<!-- а сюда iframe с видео -->
</details>
Оптимизированная загрузка видео
Мы знаем, что современный HTML поддерживает ленивую загрузку (атрибут loading="lazy") для изображений и тега iframe. Но важно помнить, что, если так загружать все без разбору, можно только ухудшить производительность.
В нашем же случае видео должно появляться только после клика на summary, то есть изначально оно скрыто — находится вне видимой области, а следовательно атрибут loading="lazy", который мы присвоили тегу iframe не позволяет загружаться его контенту!
Стилизация details и его содержимого
Поскольку в summary вместо традиционного текста находится картинка, заменяющяя видео до ей появления, то ему мы задаем пропорции видеоплеера.
.details-video__poster {
aspect-ratio: 16/9;
width: 100%;
display: block;
grid-column: 1;
grid-row: 1;
}
Поверх картинки, по центру размещаем кнопку, чтобы посетитель явно понимал что кликнув в этой области можно посмотреть видео. Кнопку создаем с помощью CSS-псевдоэлементов.
.details-video__poster-holder::before,
.details-video__poster-holder::after {
content: "";
position: relative;
z-index: 2;
aspect-ratio: 1;
grid-column: 1;
grid-row: 1;
pointer-events: none;
}
.details-video__poster-holder::before {
width: 150px;
background-color: red;
border-radius: 100vw;
}
.details-video__poster-holder::after {
translate: 10% 0;
width: 50px;
background-color: #fff;
clip-path: polygon(0 0, 100% 50%, 0 100%);
}
После закрывающего тега </summary> в отдельный div вставляем iframe, в который в дальнейшем будет загружаться видео.
<details class="details-video">
<summary class="details-video__poster-holder">
<!-- Здесь находится постер -->
</summary>
<div class="details-video__content">
<iframe width="720" height="405" src="https://rutube.ru/play/embed/7bcb415574146bdfc4adcd0845574e38?autoplay=true" allow="clipboard-write; autoplay" allowFullScreen loading="lazy"></iframe>
</div>
</details>
Как отмечалось выше, по умолчанию, summary виден всегда, независимо от того показывается контент или нет. Но, в нашем случае, его нужно скрыть, когда видео-контент показывается. Скрываем его следующим способом:
.details-video[open] .details-video__poster {
visibility: hidden;
}
При клике на постере браузер добавляет тегу details атрибут open. В результате summary скрывается, а iframe появляется и видео загружается.
Как видите, iframe с видео грузится не во время прокрутки страницы, как это стандартно происходит при ленивой загрузке, а только когда пользователь реально хочет смотреть видео, т.е. кликает на кнопке.
Добавьте ?autoplay=1 к ссылке с RuTube или YouTube чтобы видео запускалось сразу после загрузки (если автоплей не запрещён браузером).
Полный пример кода
Код примера рабочий на 100%, поэтому можете его копировать и использовать в своих проектах. Сделайте лишь необходимые корректировки в атрибутах src и alt у тегов img и iframe, а также у атрибута aria-label.
<details class="details-video">
<summary class="details-video__poster-holder" aria-label="Воспроизвести видео: Здесь название вашего видео">
<img class="details-video__poster" src="ваш_постер.webp" alt="Название для вашего постера">
</summary>
<div class="details-video__content">
<iframe loading="lazy" width="720" height="405" src="https://rutube.ru/play/embed/код_вашего_видео?autoplay=true" allow="clipboard-write; autoplay" allowFullScreen ></iframe>
</div>
</details>
.details-video {
position: relative;
}
.details-video[open] .details-video__poster {
visibility: hidden;
}
.details-video__poster-holder {
position: relative;
z-index: 1;
display: grid;
place-items: center;
cursor: pointer;
}
.details-video__poster-holder::before,
.details-video__poster-holder::after {
content: "";
position: relative;
z-index: 2;
aspect-ratio: 1;
grid-column: 1;
grid-row: 1;
pointer-events: none;
}
.details-video__poster-holder::before {
width: 150px;
background-color: red;
border-radius: 100vw;
}
.details-video__poster-holder::after {
translate: 10% 0;
width: 50px;
background-color: #fff;
clip-path: polygon(0 0, 100% 50%, 0 100%);
}
.details-video__poster {
list-style: none;
width: 100%;
grid-column: 1;
grid-row: 1;
aspect-ratio: 16 / 9;
}
.details-video__content {
position: absolute;
z-index: 2;
top: 0;
left: 0;
right: 0;
bottom: 0;
aspect-ratio: 16 / 9;
}
.details-video__content > iframe {
width: 100% !important;
height: 100% !important;
aspect-ratio: 16 / 9;
}
Подведем итог
Решение с <details>/<summary> грузит видео только по клику, а не заранее. Подходит для RuTube, YouTube, Vimeo, GIF, своих видео и любого другого встраиваемого контента.
Можно даже так: сначала показывать картинку, по клику — включать интерактив. Если загрузка не удалась — показывать ошибку. На сегодняшний день это одно из лучших решений подобной проблемы средствами браузера.
Собери свой код. Запусти сайт!
От наброска на салфетке до первого работающего лендинга. Наш онлайн-курс «Веб-верстка с нуля и до профессионала» — это интенсивный трек, где ты не будешь зубрить теорию, а с первого дня начнешь превращать идеи в чистый HTML и CSS.
Собери свой первый проект под руководством практикующих разработчиков.
Заключение
Освоив предложенный метод оптимизации видео, вы сделали важный шаг к созданию по-настоящему быстрых и профессиональных сайтов. Но современная вёрстка — это не только изолированные приёмы, а целая система знаний, где критически важна каждая деталь: от семантической структуры до идеальной производительности.
Если вы хотите систематизировать свои навыки и научиться создавать сайты, которые превосходят ожидания клиентов и требования поисковых систем, обратите внимание на наш онлайн-курс «Веб-вёрстка с нуля до профессионала». Мы собрали в нём десятки подобных оптимизационных техник, лучшие практики и реальные кейсы, чтобы вы могли уверенно решать любые задачи.
А если текущие проекты требуют немедленного результата или вы хотите доверить создание сайта профессионалам, — команда нашей веб-студии с радостью возьмёт эту работу на себя, воплотив все современные технологии в вашем проекте. Напишите или позвоните нам сегодня, чтобы обсудить детали!