Гибкое видео или Responsive Video

21 марта 2016

Случается, что необходимо вставить видео на сайт, но при вставке кода он имеет заданные ширину и высоту, это не есть хорошо, особенно в век гибкого содержимого. Видео может быть обёрнуто в такие теги:

<video width="400" height="300" ...
​​​​​​​<iframe width="400" height="300" ... 
<object width="400" height="300" ...
<embed width="400" height="300" ...

При этом если сайт имеет, например, определённую ширину то видео будет залазить за края

Обычно мы делаем так:

<video width="100%" ...

Если имеем дело с html5 видео, то приводим все в порядок через CSS

video {
  width: 100% !important;
  height: auto !important;
}

И все бы ничего, но мы разобрались только с html5 видео, а как же быть с iframe?

После добавления CSS для iframe

iframe {
  width: 100% !important;
  height: auto !important;
}

Мы получим:

Как предложил еще в далеком 2009 году Thierry Koblentz свое решение данного вопроса и сделал он это так:

Оборачиваем наш iframe в div и назначим ему класс, например, .videoWrapper. Добавляем стили для класса и iframe

<div class="videoWrapper">
    <!-- Copy & Pasted from YouTube -->
    <iframe width="560" height="349" src="http://www.youtube.com/embed/n_dZNLr2cME?rel=0&hd=1" frameborder="0" allowfullscreen></iframe>
</div>
.videoWrapper {
    position: relative;
    padding-bottom: 56.25%; /* 16:9 */
    padding-top: 25px;
    height: 0;
}
.videoWrapper iframe {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

Уаля, так-то лучше, получаем видео 16:9 и с нормальным height.

Но… как обычно&nbsp; такого способа есть якобы «недостатки», такие как:

  • Видео должно оборачиваться в div
  • Проблемы с форматом 16:9 или 4:3

И как всегда все проблемы решаются с помощью могучего jquery

Например, наше видео обернуто в <p> добавляем следующий скрипт:

$(function() {
    var $allVideos = $("iframe[src*='//player.vimeo.com'], iframe[src*='//www.youtube.com'], object, embed"),
    $fluidEl = $("p");

    $allVideos.each(function() {
        $(this)
        // jQuery .data does not work on object/embed elements
        .attr('data-aspectRatio', this.height / this.width)
        .removeAttr('height')
        .removeAttr('width');
    });

    $(window).resize(function() {
        var newWidth = $fluidEl.width();
        $allVideos.each(function() {
        var $el = $(this);
        $el
            .width(newWidth)
            .height(newWidth * $el.attr('data-aspectRatio'));

        });
    }).resize();
});

И получаем респонсив видео для любых тегов

количество этих тегов соответственно редактируется здесь

var $allVideos = $("iframe[src*='//player.vimeo.com'], iframe[src*='//www.youtube.com'], object, embed"),

Ну вот и все!