模拟背景大小:覆盖<视频>或<IMG>

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

我希望它能像这样工作

background-size: cover;
background-position: center center;
210428 次浏览

在我们长长的评论部分之后,我想这就是你要找的,它是基于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;
}

我还应该声明,我只测试了这是谷歌浏览器。下面是一个JSFiddle: http://jsfiddle.net/ADCKk/

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

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

我认为要正确模拟元素上的background-size:cover; CSS属性而不是元素背景图像属性,您必须将图像的纵横比与当前窗口的纵横比进行比较,因此无论窗口的大小如何(以及在图像较高而不是较宽的情况下),元素都会填充窗口(并将其居中,尽管我不知道这是否是一项要求)。

使用图像,只是为了简单起见,我相信视频元素也可以很好地工作。

首先获取元素的纵横比(加载后),然后附加窗口大小调整处理程序,触发一次以进行初始调整:

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

}

Jsfiddle

对于图像,使用背景覆盖很好,宽度100%也是如此。这些对于<video>来说不是最优的,并且这些答案过于复杂。您不需要jQuery或JavaScript来完成全宽视频背景。

请记住,我的代码不会像Cover Will那样用视频完全覆盖背景,相反,它会使视频尽可能大,以保持纵横比,并仍然覆盖整个背景。任何多余的视频都会从页面边缘溢出,这取决于您锚定视频的位置。

答案很简单。

只需使用这个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>

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

这种方法只使用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*/
}

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

object-fit: cover;

http://caniuse.com/object-fit.

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

为了回答韦奇的评论,即蒂莫西·瑞安·卡彭特的答案没有考虑到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%);
}

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

其他答案很好,但它们涉及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;
}

这是我把我的头发拉出来了一段时间,但我遇到了一个伟大的解决方案,不使用任何脚本,并可以实现一个完美的封面模拟视频5行CSS(9如果你计算选择器和括号)。这有0个边缘情况,它不能完美地工作,缺乏CSS3兼容性

您可以查看在这里(已存档)的示例

蒂莫西的解决方案的问题是它不能正确处理缩放。如果周围的元素小于视频文件,则不会按比例缩小。即使您给video标签一个很小的初始大小,比如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;),则视频也将覆盖整个页面。

如果您还希望视频居中,则可以使用SureFire居中方法:

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

当然,vwvhtransform都是CSS3,因此如果您需要与较旧浏览器的兼容性,则需要使用脚本。

@隐藏的霍布斯

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

你在这个问题上打开了一个只有CSS解决方案的赏金,所以我会试一试。对于这样的问题,我的解决方案是使用固定的比例来决定视频的高度和宽度。我通常使用引导程序,但我从那里提取了必要的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>

M-Pixel的解决方案非常好,因为它解决了蒂莫西的回答的缩放问题(视频将放大,但不会缩小,因此如果您的视频非常大,您很可能只会看到一小部分放大的视频)。然而,该解决方案基于与视频容器的大小相关的错误假设,即它必须是视口的宽度和高度的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中进行了测试。

编辑(2016年3月17日)

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

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

伙计们,我有一个更好的解决方案,它很短,对我来说很完美。我用它来录像。它完美地模仿了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,否则你会得到CONTAIN.

这是CSS.(如果不想居中,则不需要使用它,父DIV必须是“位置:相对 ”)

CSS

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

基于丹尼尔·德威特的回答和评论,我搜索了更多。感谢他的解决方案。

解决方案是使用object-fit: cover;,它具有强大的支持(每个现代浏览器都支持它)。如果确实要支持IE,可以使用多边形填充,如对象匹配图像对象拟合

演示:

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>

当你的浏览器宽度小于你的视频宽度时,最上面的答案不会缩小视频。尝试使用这个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%);
}

object-fit: cover是这个IE的最佳答案,Safari多边形填充。

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

它支持imgvideopicture元素。

我刚刚解决了这个问题,想分享一下。这适用于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="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>

老问题,但如果有人看到这个,在我看来,最好的答案是将视频转换成动画GIF.这给了你更多的控制,你可以把它当作一个图像。这也是它在移动设备上工作的唯一方式,因为你不能自动播放视频。我知道问题是要求在<img>标记中执行此操作,但我并不认为使用<div>和执行background-size: cover有什么坏处。

我也有这个问题,我解决了以下CSS:

#video-container {
overflow: hidden;
}


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

你可以试试这个CSS代码。

video {
object-fit: cover;
width: 100vw;
height: 100vh;
position: fixed;
top: 0;
left: 0;
}