Имитировать фон-размер: обложка на <video> или <img> - программирование

Имитировать фон-размер: обложка на <video> или <img>

Как смоделировать функции background-size:cover в элементе html, например <video> или <img>?

Мне бы хотелось, чтобы он работал как

background-size: cover;
background-position: center center;
4b9b3361

Ответ 1

Вот как я это сделал. Рабочим примером является этот jsFiddle.

var min_w = 300; // minimum video width allowed
var vid_w_orig;  // original video dimensions
var vid_h_orig;

jQuery(function() { // runs after DOM has loaded

  vid_w_orig = parseInt(jQuery('video').attr('width'));
  vid_h_orig = parseInt(jQuery('video').attr('height'));
  $('#debug').append("<p>DOM loaded</p>");

  jQuery(window).resize(function () { resizeToCover(); });
  jQuery(window).trigger('resize');
});

function resizeToCover() {
  // set the video viewport to the window size
  jQuery('#video-viewport').width(jQuery(window).width());
  jQuery('#video-viewport').height(jQuery(window).height());

  // use largest scale factor of horizontal/vertical
  var scale_h = jQuery(window).width() / vid_w_orig;
  var scale_v = jQuery(window).height() / vid_h_orig;
  var scale = scale_h > scale_v ? scale_h : scale_v;

  // don't allow scaled width < minimum video width
  if (scale * vid_w_orig < min_w) {scale = min_w / vid_w_orig;};

  // now scale the video
  jQuery('video').width(scale * vid_w_orig);
  jQuery('video').height(scale * vid_h_orig);
  // and center it by scrolling the video viewport
  jQuery('#video-viewport').scrollLeft((jQuery('video').width() - jQuery(window).width()) / 2);
  jQuery('#video-viewport').scrollTop((jQuery('video').height() - jQuery(window).height()) / 2);

  // debug output
  jQuery('#debug').html("<p>win_w: " + jQuery(window).width() + "</p>");
  jQuery('#debug').append("<p>win_h: " + jQuery(window).height() + "</p>");
  jQuery('#debug').append("<p>viewport_w: " + jQuery('#video-viewport').width() + "</p>");
  jQuery('#debug').append("<p>viewport_h: " + jQuery('#video-viewport').height() + "</p>");
  jQuery('#debug').append("<p>video_w: " + jQuery('video').width() + "</p>");
  jQuery('#debug').append("<p>video_h: " + jQuery('video').height() + "</p>");
  jQuery('#debug').append("<p>vid_w_orig: " + vid_w_orig + "</p>");
  jQuery('#debug').append("<p>vid_h_orig: " + vid_h_orig + "</p>");
  jQuery('#debug').append("<p>scale: " + scale + "</p>");
};
#video-viewport {
  position: absolute;
  top: 0;
  overflow: hidden;
  z-index: -1; /* for accessing the video by click */
}

#debug {
  position: absolute;
  top: 0;
  z-index: 100;
  color: #fff;
  font-size: 12pt;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="video-viewport">
  <video autoplay controls preload width="640" height="360">
    <source src="http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4"type="video/mp4" />
    <source src="http://www.quirksmode.org/html5/videos/big_buck_bunny.webm"type="video/webm" />
    <source src="http://www.quirksmode.org/html5/videos/big_buck_bunny.ogv"type="video/webm" />
  </video>
</div>

<div id="debug"></div>

Ответ 2

jsFiddle

Использование фонового покрытия отлично подходит для изображений, а значит, и ширина 100%. Они не являются оптимальными для <video>, и эти ответы слишком сложны. Вам не нужно jQuery или JavaScript для создания полноформатного видео фона.

Имейте в виду, что мой код не будет полностью покрывать фон с видео, как на обложке, но вместо этого он сделает видео настолько большим, насколько это необходимо, чтобы поддерживать соотношение сторон и по-прежнему охватывать весь фон. Любое избыточное видео сбрасывается с края страницы, в зависимости от того, где вы привязываете видео.

Ответ довольно прост.

Просто используйте этот видеокод HTML5 или что-то в этом роде: (test in Full Page)

html, body {
  width: 100%; 
  height:100%; 
  overflow:hidden;
}

#vid{
  position: absolute;
  top: 50%; 
  left: 50%;
  -webkit-transform: translateX(-50%) translateY(-50%);
  transform: translateX(-50%) translateY(-50%);
  min-width: 100%; 
  min-height: 100%; 
  width: auto; 
  height: auto;
  z-index: -1000; 
  overflow: hidden;
}
<video id="vid" video autobuffer autoplay>
  <source id="mp4" src="http://grochtdreis.de/fuer-jsfiddle/video/sintel_trailer-480.mp4" type="video/mp4">
</video>

Ответ 3

Это то, что я вытащил из волос на некоторое время, но я столкнулся с отличным решением, которое не использует никаких script, и может добиться идеального моделирования покрытия на видео с 5 строками CSS (9 if вы считаете селекторы и скобки). У этого есть 0 ребер, в которых он не работает отлично, за исключением CSS3-совместимости.

Вы можете увидеть пример здесь

Проблема с решением Timothy заключается в том, что он неправильно обрабатывает масштабирование. Если окружающий элемент меньше видеофайла, он не уменьшается. Даже если вы дадите видеотеку крошечный начальный размер, например 16px на 9px, auto завершает работу с минимальным размером своего собственного файла. С текущим голосованием на этой странице было невозможно, чтобы видеофайлы уменьшались, что приводило к резкому эффекту масштабирования.

Если соотношение сторон вашего видео известно, например, 16: 9, вы можете сделать следующее:

.parent-element-to-video {
    overflow: hidden;
}
video {
    height: 100%;
    width: 177.77777778vh; /* 100 * 16 / 9 */
    min-width: 100%;
    min-height: 56.25vw; /* 100 * 9 / 16 */
}

Если родительский элемент видео установлен для обложки всей страницы (например, position: fixed; width: 100%; height: 100vh;), то также будет и видео.

Если вы хотите, чтобы видеоцентрировалось также, вы можете использовать подход центрирования с уверенностью:

/* merge with above css */
.parent-element-to-video {
    position: relative; /* or absolute or fixed */
}
video {
    position: absolute;
    left: 50%; /* % of surrounding element */
    top: 50%;
    transform: translate(-50%, -50%); /* % of current element */
}

Конечно, vw, vh и transform являются CSS3, поэтому, если вам нужна совместимость с гораздо более старыми браузерами, вам нужно будет использовать script.

Ответ 4

Для некоторых браузеров вы можете использовать

object-fit: cover;

http://caniuse.com/object-fit

Ответ 5

Другие ответы были хорошими, но они включают javascript или они не центрируют видео по горизонтали и по вертикали.

Вы можете использовать это полное решение для CSS, чтобы иметь видео, имитирующее свойство background-size: cover:

  video {
    position: fixed;           // Make it full screen (fixed)
    right: 0;
    bottom: 0;
    z-index: -1;               // Put on background

    min-width: 100%;           // Expand video
    min-height: 100%;
    width: auto;               // Keep aspect ratio
    height: auto;

    top: 50%;                  // Vertical center offset
    left: 50%;                 // Horizontal center offset

    -webkit-transform: translate(-50%,-50%);
    -moz-transform: translate(-50%,-50%);
    -ms-transform: translate(-50%,-50%);
    transform: translate(-50%,-50%);         // Cover effect: compensate the offset

    background: url(bkg.jpg) no-repeat;      // Background placeholder, not always needed
    background-size: cover;
  }

Ответ 6

Решение M-Pixel отлично подходит для решения проблемы масштабирования Timothy answer (видео будет увеличиваться, но не вниз, поэтому, если ваше видео действительно велико, есть хорошие шансы, что вы увидите только небольшую увеличенную часть). Однако это решение основано на ложных предположениях, связанных с размером видеоконтейнера, а именно, что это обязательно составляет 100% от ширины и высоты окна просмотра. Я нашел несколько случаев, когда это не сработало для меня, поэтому я решил сам решить проблему, и я считаю, что придумал окончательное решение.

HTML

<div class="parent-container">
    <div class="video-container">
        <video width="1920" height="1080" preload="auto" autoplay loop>
            <source src="video.mp4" type="video/mp4">
        </video>
    </div>
</div>

CSS

.parent-container {
  /* any width or height */
  position: relative;
  overflow: hidden;
}
.video-container {
  width: 100%;
  min-height: 100%;
  position: absolute;
  left: 0px;
  /* center vertically */
  top: 50%;
  -moz-transform: translate(0%, -50%);
  -ms-transform: translate(0%, -50%);
  -webkit-transform: translate(0%, -50%);
  transform: translate(0%, -50%);
}
.video-container::before {
  content: "";
  display: block;
  height: 0px;
  padding-bottom: 56.25%; /* 100% * 9 / 16 */
}
.video-container video {
  width: auto;
  height: 100%;
  position: absolute;
  top: 0px;
  /* center horizontally */
  left: 50%;
  -moz-transform: translate(-50%, 0%);
  -ms-transform: translate(-50%, 0%);
  -webkit-transform: translate(-50%, 0%);
  transform: translate(-50%, 0%);
}

Он также основан на соотношении видео, поэтому, если ваше видео имеет отношение, отличное от 16/9, вы захотите изменить нижний уровень заполнения. Помимо этого, он работает из коробки. Протестировано в IE9 +, Safari 9.0.1, Chrome 46 и Firefox 41.

EDIT (17 марта 2016 года)

Поскольку я отправил этот ответ, я написал небольшой CSS-модуль для имитации элементов background-size: cover и background-size: contain на <video>: http://codepen.io/benface/pen/NNdBMj

Он поддерживает различные настройки для видео (аналогично background-position). Также обратите внимание, что реализация contain не идеальна. В отличие от background-size: contain, он не будет масштабировать видео до его фактического размера, если ширина и высота контейнера больше, но я думаю, что он может быть полезен в некоторых случаях. Я также добавил специальные классы fill-width и fill-height, которые вы можете использовать вместе с contain, чтобы получить специальное сочетание contain и cover... попробуйте, и не стесняйтесь его улучшать!

Ответ 7

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

Решение состоит в том, чтобы использовать object-fit: cover; который имеет большую поддержку (все современные браузеры поддерживают его). Если вы действительно хотите поддерживать IE, вы можете использовать polyfill как object-fit-images или object-fit.

Демоверсии:

img {
  float: left;
  width: 100px;
  height: 80px;
  border: 1px solid black;
  margin-right: 1em;
}
.fill {
  object-fit: fill;
}
.contain {
  object-fit: contain;
}
.cover {
  object-fit: cover;
}
.none {
  object-fit: none;
}
.scale-down {
  object-fit: scale-down;
}
<img class="fill" src="http://www.peppercarrot.com/data/wiki/medias/img/chara_carrot.jpg"/>
<img class="contain" src="http://www.peppercarrot.com/data/wiki/medias/img/chara_carrot.jpg"/>
<img class="cover" src="http://www.peppercarrot.com/data/wiki/medias/img/chara_carrot.jpg"/>
<img class="none" src="http://www.peppercarrot.com/data/wiki/medias/img/chara_carrot.jpg"/>
<img class="scale-down" src="http://www.peppercarrot.com/data/wiki/medias/img/chara_carrot.jpg"/>

Ответ 9

CSS и маленькие js могут сделать видеоизображение фоном и горизонтально центрированным.

CSS

video#bgvid {
    position: absolute;
    bottom: 0px; 
    left: 50%; 
    min-width: 100%; 
    min-height: 100%; 
    width: auto; 
    height: auto; 
    z-index: -1; 
    overflow: hidden;
}

JS: (свяжите это с изменением размера окна и вызовите один раз отдельно)

$('#bgvid').css({
    marginLeft : '-' + ($('#bgvid').width()/2) + 'px'
})

Ответ 10

Сразу после нашей длинной секции комментариев, я думаю, что это то, что вы ищете, на основе jQuery:

HTML:

<img width="100%" id="img" src="http://uploads8.wikipaintings.org/images/william-adolphe-bouguereau/self-portrait-presented-to-m-sage-1886.jpg">

JS:

<script type="text/javascript">
window.onload = function(){
       var img = document.getElementById('img')
       if(img.clientHeight<$(window).height()){
            img.style.height=$(window).height()+"px";
       }
       if(img.clientWidth<$(window).width()){
            img.style.width=$(window).width()+"px";
       } 
}
​</script>​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​

CSS

body{
    overflow: hidden;
}

В приведенном выше коде используется ширина и высота браузеров, если вы делаете это в div, вам придется изменить его на следующее:

Для Div:

HTML:

<div style="width:100px; max-height: 100px;" id="div">
     <img width="100%" id="img" src="http://uploads8.wikipaintings.org/images/william-adolphe-bouguereau/self-portrait-presented-to-m-sage-1886.jpg">
</div>

JS:

<script type="text/javascript">
window.onload = function(){
       var img = document.getElementById('img')
       if(img.clientHeight<$('#div').height()){
            img.style.height=$('#div').height()+"px";
       }
       if(img.clientWidth<$('#div').width()){
            img.style.width=$('#div').width()+"px";
       } 
}
​</script>​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​

CSS

div{
   overflow: hidden;
}

Я также должен указать, что я только тестировал это Google Chrome... вот jsfiddle: http://jsfiddle.net/ADCKk/

Ответ 11

Верхний ответ не уменьшает масштаб видео, если ширина браузера меньше ширины вашего видео. Попробуйте использовать этот CSS (С#bgvid, являющимся вашим идентификатором видео):

#bgvid {
     position: fixed;
     top: 50%;
     left: 50%;
     min-width: 100%;
     min-height: 100%;
     width: auto;
     height: auto;
     transform: translateX(-50%) translateY(-50%);
     -webkit-transform: translateX(-50%) translateY(-50%);
}

Ответ 12

Я тоже знаю, что это проблема, потому что у меня была эта проблема, но другие решения не работали для моей ситуации...

Я думаю, чтобы правильно имитировать свойство background-size:cover; css для элемента вместо свойства background-image элементов, вам придется сравнить соотношение сторон изображения с текущим соотношением сторон окна, поэтому независимо от того, какой размер (и также в случае, если изображение выше, чем шире), окно - это элемент, который заполняет окно (а также центрирует его, хотя я не знаю, было ли это требование)....

используя изображение, просто для простоты, я уверен, что элемент видео тоже будет работать отлично.

сначала получите соотношение сторон элементов (после его загрузки), затем прикрепите обработчик изменения размера окна, три раза запустите его для первоначального выбора:

var img = document.getElementById( "background-picture" ),
    imgAspectRatio;

img.onload = function() {
    // get images aspect ratio
    imgAspectRatio = this.height / this.width;
    // attach resize event and fire it once
    window.onresize = resizeBackground;
    window.onresize();
}

то в вашем обработчике изменения размеров вы должны сначала определить, нужно ли заполнять ширину или высоту заполнения, сравнивая соотношение сторон окна с исходным форматом изображения.

function resizeBackground( evt ) {

// get window size and aspect ratio
var windowWidth = window.innerWidth,
    windowHeight = window.innerHeight;
    windowAspectRatio = windowHeight / windowWidth;

//compare window ratio to image ratio so you know which way the image should fill
if ( windowAspectRatio < imgAspectRatio ) {
    // we are fill width
    img.style.width = windowWidth + "px";
    // and applying the correct aspect to the height now
    img.style.height = (windowWidth * imgAspectRatio) + "px";
    // this can be margin if your element is not positioned relatively, absolutely or fixed
    // make sure image is always centered
    img.style.left = "0px";
    img.style.top = (windowHeight - (windowWidth * imgAspectRatio)) / 2 + "px";
} else { // same thing as above but filling height instead
    img.style.height = windowHeight + "px";
    img.style.width = (windowHeight / imgAspectRatio) + "px";
    img.style.left = (windowWidth - (windowHeight / imgAspectRatio)) / 2 + "px";
    img.style.top = "0px";
}

}

Ответ 13

Этот подход использует только css и html. Вы можете легко складывать divs под видео. Это покрытие, но не центрированное при изменении размера.

HTML:

<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css"> 
</script>
</head>
<body>
<div id = "contain">
<div id="vid">
    <video autoplay>
        <source src="http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4" type="video/mp4" />
    </video>
</div>
</div>
</body>
</html>

CCS:

/*
filename:style.css
*/
body {
    margin:0;
}

#vid video{
position: absolute; 
right: 0; 
top: 0;
min-width: 100%; 
min-height: 100%;
width: auto; 
height: auto; 
}

#contain {
width:100%;
height:100%;
zoom:1%;/*Without this the video will be stretched and skewed*/ 
}

Ответ 14

@Hidden Hobbes

У этого вопроса есть открытая награда, стоящая +100 репутации от Скрытых Гоббсов, заканчивающихся через 6 дней. Изобретательное использование единиц просмотра, чтобы получить гибкое решение только для CSS.

Вы открыли щедрость по этому вопросу для решения только для CSS, поэтому я дам ему попробовать. Мое решение такой проблемы заключается в использовании фиксированного соотношения для определения высоты и ширины видео. Обычно я использую Bootstrap, но я извлек из него необходимый CSS, чтобы он работал без него. Это код, который я использовал ранее, среди прочего, в центре встроенного видео с правильным соотношением. Он должен работать и для элементов <video> и <img>. Это верхний, который здесь имеет значение, но я дал вам и другие два, так как я уже их клал. Удачи!:)

jsfiddle полноэкранный пример

.embeddedContent.centeredContent {
    margin: 0px auto;
}
.embeddedContent.rightAlignedContent {
    margin: auto 0px auto auto;
}
.embeddedContent > .embeddedInnerWrapper {
    position:relative;
    display: block;
    padding: 0;
    padding-top: 42.8571%; /* 21:9 ratio */
}
.embeddedContent > .embeddedInnerWrapper > iframe {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    height: 100%;
    width: 100%;
    border: 0;
}
.embeddedContent {
    max-width: 300px;
}
.box1text {
    background-color: red;
}
/* snippet from Bootstrap */
.container {
    margin-right: auto;
    margin-left: auto;
}
.col-md-12 {
    width: 100%;
}
<div class="container">
    <div class="row">
        <div class="col-md-12">
            Testing ratio AND left/right/center align:<br />
            <div class="box1text">
                <div class="embeddedContent centeredContent">
                    <div class="embeddedInnerWrapper">
                        <iframe allowfullscreen="true" allowscriptaccess="always" frameborder="0" height="349" scrolling="no" src="//www.youtube.com/embed/u6XAPnuFjJc?wmode=transparent&amp;jqoemcache=eE9xf" width="425"></iframe>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<div class="container">
    <div class="row">
        <div class="col-md-12">
            Testing ratio AND left/right/center align:<br />
            <div class="box1text">
                <div class="embeddedContent rightAlignedContent">
                    <div class="embeddedInnerWrapper">
                        <iframe allowfullscreen="true" allowscriptaccess="always" frameborder="0" height="349" scrolling="no" src="//www.youtube.com/embed/u6XAPnuFjJc?wmode=transparent&amp;jqoemcache=eE9xf" width="425"></iframe>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<div class="container">
    <div class="row">
        <div class="col-md-12">
            Testing ratio AND left/right/center align:<br />
            <div class="box1text">
                <div class="embeddedContent">
                    <div class="embeddedInnerWrapper">
                        <iframe allowfullscreen="true" allowscriptaccess="always" frameborder="0" height="349" scrolling="no" src="//www.youtube.com/embed/u6XAPnuFjJc?wmode=transparent&amp;jqoemcache=eE9xf" width="425"></iframe>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

Ответ 15

Старый вопрос, но в случае, если кто-либо это увидит, лучшим ответом, на мой взгляд, является преобразование видео в анимированный GIF. Это дает вам гораздо больше контроля, и вы можете просто рассматривать его как образ. Это также единственный способ работать на мобильных устройствах, поскольку вы не можете автоматически запускать видео. Я знаю, что вопрос просит сделать это в теге <img>, но я не вижу недостатков в использовании <div> и делает background-size: cover

Ответ 16

Чтобы ответить на комментарий weotch, ответ Тимоти Райан Карпентер не учитывает cover центрирование фона, я предлагаю это быстрое исправление CSS:

CSS

margin-left: 50%;
transform: translateX(-50%);

Добавление этих двух линий будет центрировать любой элемент. Еще лучше, что все браузеры, которые могут обрабатывать видео HTML5, также поддерживают преобразования CSS3, поэтому это всегда будет работать.

Полный CSS выглядит так.

#video-background { 
    position: absolute;
    bottom: 0px; 
    right: 0px; 
    min-width: 100%; 
    min-height: 100%; 
    width: auto; 
    height: auto; 
    z-index: -1000; 
    overflow: hidden;
    margin-left: 50%;
    transform: translateX(-50%);
}

Я бы сразу прокомментировал ответ Тимоти, но у меня недостаточно репутации, чтобы сделать это.

Ответ 17

Ребята, у меня есть лучшее решение, и оно отлично работает для меня. Я использовал его для видео. И он отлично эмулирует опцию обложки в css.

Javascript

    $(window).resize(function(){
            //use the aspect ration of your video or image instead 16/9
            if($(window).width()/$(window).height()>16/9){
                $("video").css("width","100%");
                $("video").css("height","auto");
            }
            else{
                $("video").css("width","auto");
                $("video").css("height","100%");
            }
    });

Если вы перевернете if, иначе вы получите его.

И вот css. (Вам не нужно использовать его, если вы не хотите централизованного позиционирования, родительский div должен быть "position: relative" )

CSS

video {
position: absolute;
-webkit-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
top: 50%;
left: 50%;}

Ответ 18

Я просто решил это и хотел поделиться. Это работает с Bootstrap 4. Он работает с img, но я не тестировал его с помощью video. Вот HAML и SCSS

HAML
.container
  .detail-img.d-flex.align-items-center
    %img{src: 'http://placehold.it/1000x700'}
SCSS
.detail-img { // simulate background: center/cover
  max-height: 400px;
  overflow: hidden;

  img {
    width: 100%;
  }
}

/* simulate background: center/cover */
.center-cover { 
  max-height: 400px;
  overflow: hidden;
  
}

.center-cover img {
    width: 100%;
}
<link href="#" onclick="location.href='https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css'; return false;" rel="stylesheet"/>
<div class="container">
  <div class="center-cover d-flex align-items-center">
    <img src="http://placehold.it/1000x700">
  </div>
</div>