模拟背景大小:覆盖<video>或<img/> </video>

时间:2012-05-29 10:48:57

标签: javascript jquery css

如何在background-size:cover<video>等html元素上模拟<img>的功能?

我希望它像

一样工作
background-size: cover;
background-position: center center;

18 个答案:

答案 0 :(得分:116)

jsFiddle

使用背景封面适用于图像,因此宽度为100%。这些对于<video>来说不是最佳的,这些答案过于复杂。您不需要jQuery或JavaScript来完成全宽视频背景。

请记住,我的代码不会完全覆盖带有视频的视频背景,而是会使视频尽可能大,以保持宽高比并仍覆盖整个背景。任何多余的视频都会从页面边缘流失,哪些方面取决于您锚定视频的位置。

答案很简单。

只需使用此HTML5视频代码或以下内容:(在整页测试)

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>

最小高度和最小宽度将允许视频保持视频的宽高比,这通常是正常分辨率下任何普通浏览器的宽高比。任何多余的视频都会从页面侧面流出。

答案 1 :(得分:84)

对于某些浏览器,您可以使用

object-fit: cover;

http://caniuse.com/object-fit

答案 2 :(得分:43)

我是这样做的。一个工作示例位于this 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>

答案 3 :(得分:14)

其他答案很好,但它们涉及javascript,或者它们没有水平和垂直居中视频。

您可以使用此完整的CSS解决方案来制作模拟背景大小的视频:封面属性:

  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;
  }

答案 4 :(得分:13)

M-Pixel's solution非常棒,因为它解决了Timothy's 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,则需要更改padding-bottom%。除此之外,它开箱即用。在IE9 +,Safari 9.0.1,Chrome 46和Firefox 41中进行了测试。

编辑(2016年3月17日)

自从我发布此答案后,我编写了一个小型CSS模块来模拟background-size: cover元素上的background-size: contain<video>http://codepen.io/benface/pen/NNdBMj

它支持视频的不同对齐方式(类似于background-position)。另请注意,contain实施并不完美。与background-size: contain不同,如果容器的宽度和高度较大,它不会将视频缩放超过其实际大小,但我认为在某些情况下它仍然有用。我还添加了可与fill-width一起使用的特殊fill-heightcontain类,以获得containcover的特殊组合。尝试一下,随时改进它!

答案 5 :(得分:5)

object-fit: cover是这个IE,Safari polyfill的最佳答案。

https://github.com/constancecchen/object-fit-polyfill

它支持imgvideopicture元素。

答案 6 :(得分:4)

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'
})

答案 7 :(得分:4)

基于Daniel de Wit's answer和评论,我搜索了一下。感谢他的解决方案。

解决方案是使用object-fit: cover;,它有一个很棒的support(IE和Edge之外的所有人,但它目前在consideration中)。如果您想支持IE和Edge,可以使用object-fit-imagesobject-fit之类的polyfill。

演示:

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"/>

并与父母:

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

答案 8 :(得分:3)

在我们的长篇评论部分之后,我认为这是你正在寻找的,它是基于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/

答案 9 :(得分:2)

当您的浏览器宽度小于视频宽度时,最佳答案不会缩小视频比例。尝试使用此CSS(#bgvid是您的视频ID):

#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%);
}

答案 10 :(得分:1)

@Hidden Hobbes

  

这个问题有一个公开的赏金价值+隐藏霍布斯在6天结束时的声望+100。   创造性地使用视口单元来获得灵活的仅CSS解决方案。

你在这个问题上打开了一个只有CSS解决方案的赏金,所以我会尝试一下。我对这类问题的解决方案是使用固定比率来决定视频的高度和宽度。我通常使用Bootstrap,但是我从那里提取了必要的CSS以使其无需工作。这是我之前使用的代码,其中包含具有正确比率的嵌入视频。它应该适用于<video><img>元素这是最重要的元素,但是我已经给了你另外两个,因为我已经让它们存在了。祝你好运! :)

jsfiddle fullscreen example

.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>

答案 11 :(得分:1)

老问题,但万一有人看到这个,我认为最好的答案是将视频转换为动画GIF。这为您提供了更多控制权,您可以像对待图像一样对待它。这也是它在移动设备上工作的唯一方式,因为您无法自动播放视频。我知道问题是要求在<img>标记中执行此操作,但我并未真正看到使用<div>并执行background-size: cover

的缺点

答案 12 :(得分:1)

这种方法只使用css和html。实际上,您可以轻松地在视频下方堆叠div。当你调整大小时,它是封面但不是居中。

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*/ 
}

答案 13 :(得分:1)

我也发布了这个解决方案,因为我有这个问题,但其他解决方案对我的情况不起作用......

我认为要正确模拟元素上的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";
}

}

答案 14 :(得分:0)

伙计我有一个更好的解决方案,简短而且对我来说很完美。我用它来录像。它完美地模仿了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必须是&#34; position:relative &#34;)

<强> CSS

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

答案 15 :(得分:0)

要回复weotch的评论Timothy Ryan Carpenter的答案不能说明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%);
}

我直接评论了蒂莫西的答案,但我没有足够的声誉这样做。

答案 16 :(得分:0)

我刚刚解决了这个问题并希望分享。这适用于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%;
  }
}

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

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

答案 17 :(得分:0)

我也遇到了这个问题,我使用以下 css 解决了这个问题:

#video-container {
    overflow: hidden;
}

#video{
    width: 100%;
    position:absolute; 
    top: 0; 
    right: 0; 
    z-index: -1; 
}