模拟背景大小:覆盖<video>或<img>
如何模拟background-size:cover
的functionbackground-size:cover
像<video>
或<img>
类的html元素?
我喜欢它的工作
background-size: cover; background-position: center center;
的jsfiddle
使用背景封面对于图像来说很好,宽度也是100%。 这些对于<video>
并不是最佳的,这些答案过于复杂。 您不需要使用jQuery或JavaScript来完成全宽video背景。
请记住,我的代码不会像封面一样完全覆盖背景,而是会使video尽可能地大,以保持纵横比,并且仍然覆盖整个背景。 任何多余的video都会从页面边缘stream失,哪一边取决于您在何处定位video。
答案很简单。
只要使用这个HTML5的video代码,或者沿着这些线:(在全页面testing)
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>
这是我把头发拉出来的一段时间,但我遇到了一个不使用任何脚本的优秀解决scheme,并且可以用5行CSS实现对video的完美覆盖模拟(如果您计算select器和括号)。 这有0边缘情况下,它不能完美的工作,缺乏CSS3兼容性 。
你可以在这里看到一个例子
蒂莫西的解决scheme的问题是,它不能正确处理缩放。 如果周围的元素比video文件小,则不会缩小。 即使你给video标签一个微小的初始大小,比如16px乘9px, auto
也会最终将它强制为最小的原始文件大小。 使用本页顶级投票解决scheme,我不可能让video文件缩小,从而导致极大的缩放效果。
如果您的video宽高比是已知的,但是,例如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 */ }
如果video的父元素设置为覆盖整个页面(如position: fixed; width: 100%; height: 100vh;
),那么video也会覆盖整个页面。
如果你还想让video居中,你可以使用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 */ }
当然, vw
, vh
和transform
都是CSS3,所以如果你需要和更老的浏览器兼容的话 ,你需要使用脚本。
这是我做的。 一个工作的例子是在这个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>
其他答案是好的,但他们涉及JavaScript或他们没有水平和垂直中心的video。
您可以使用这个完整的CSS解决scheme来制作一个模拟背景大小的video: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; }
M-Pixel的解决scheme非常好,因为它解决了Timothy答案的缩放问题(video会放大而不是缩小,所以如果你的video真的很大,很可能你只能看到一小部分放大)。 但是,该解决scheme基于与video容器大小有关的错误假设,即它必然是视口宽度和高度的100%。 我发现了一些不适合我的情况,所以我决定自己解决这个问题,我相信我提出了最终的解决scheme 。
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%); }
它也是基于video的比例,所以如果你的video比例不是16/9,你会想改变填充底部%。 除此之外,它是开箱即用的。 testingIE9 +,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
它支持video的不同路线(类似于background-position
)。 还要注意, contain
实现并不完美。 与background-size: contain
,如果容器的宽度和高度都比较大的话,它不会缩小video的实际大小,但是我认为它在某些情况下仍然有用。 我还添加了特殊的fill-width
和fill-height
类,您可以使用它们一起使用以获得特定的contain
和cover
组合…尝试一下,并随时改进它!
CSS和小js可以使video覆盖背景和水平居中。
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:(绑定这个窗口resize,并单独调用一次)
$('#bgvid').css({ marginLeft : '-' + ($('#bgvid').width()/2) + 'px' })
根据Daniel de Wit的回答和评论,我search了一下。 感谢他的解决scheme。
解决scheme是使用object-fit: cover;
这有很大的支持 (IE和Edge之外的所有人,但目前正在考虑之中 )。 如果你想支持IE和Edge,你可以使用像对象适合图像或对象适合的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"/>
在我们长篇评论部分之后,我想这就是你要找的,这是基于jQuery的:
HTML:
<img width="100%" id="img" src="http://uploads8.wikipaintings.orghttp://img.dovov.comwilliam-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.orghttp://img.dovov.comwilliam-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; }
我还应该说,我只testing过这是谷歌Chrome …这是一个jsfiddle: http : //jsfiddle.net/ADCKk/
我是甘那发布这个解决scheme以及,因为我有这个问题,但其他解决scheme不适用于我的情况…
我认为正确地模拟background-size:cover;
css属性而不是元素的背景图像属性,您必须将图像宽高比与当前的窗口宽高比进行比较,所以无论大小(以及图像高于宽度)窗口是元素填充窗口(也居中,虽然我不知道这是否是一个要求)….
使用图像,只是为了简单起见,我敢肯定,video元素也能正常工作。
首先获取元素纵横比(一旦它被加载),然后附加窗口resize处理程序,触发一次初始大小:
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(); }
那么在resize处理程序中,首先应通过比较窗口的当前宽高比与图像的原始宽高比来确定是填充宽度还是填充高度。
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"; }
}
这种方法只是使用CSS和HTML。 您实际上可以轻松地在video下面叠加一个div。 当你resize时,它是封面但不居中。
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*/ }
@隐藏的霍布斯
这个问题有一个公开的赏金值得隐藏的霍布斯+6声望在6天结束。 本发明使用视口单元来获得灵活的仅CSS解决scheme。
你在这个问题上打开了一个悬赏的解决scheme,所以我会试一试。 我对这样的问题的解决scheme是使用固定的比例来决定video的高度和宽度。 我通常使用Bootstrap,但是我从那里提取了必要的CSS以使其不工作。 这是我以前使用的代码,以正确的比例集中embedded的video。 它应该也适用于<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&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&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&jqoemcache=eE9xf" width="425"></iframe> </div> </div> </div> </div> </div> </div>
当浏览器宽度小于video宽度时,最佳答案不会缩小video。 尝试使用这个CSS(#bgvid是你的video的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
它支持img
, video
和picture
elemetns。
为了回答weotch的评论, Timothy Ryan Carpenter的回答没有考虑到cover
的背景,我提供了这个快速的CSS修正:
CSS:
margin-left: 50%; transform: translateX(-50%);
添加这两行将中心任何元素。 更好的是,所有可以处理HTML5video的浏览器也支持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%); }
我会直接评论蒂莫西的答案,但是我没有足够的声望来这样做。
伙计们,我有一个更好的解决scheme它的短,完美的作品给我。 我用它来video。 它完美地模拟了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%"); } });
如果你翻转如果,否则你会得到包含。
这是CSS。 (如果你不需要中心定位,你不需要使用它,父div必须是“ position:relative ”)
CSS
video { position: absolute; -webkit-transform: translateX(-50%) translateY(-50%); transform: translateX(-50%) translateY(-50%); top: 50%; left: 50%;}
我刚刚解决这个问题,想分享。 这与Bootstrap 4一起工作。它适用于img
但我没有用video
testing。 这里是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="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>
老问题,但万一有人看到这个,我认为最好的答案是将video转换成animationGIF。 这给你更多的控制,你可以把它像一个图像。 这也是使用移动设备的唯一方式,因为您无法自动播放video。 我知道这个问题是要求在<img>
标签中做,但是我真的不明白使用<div>
和做background-size: cover
的缺点background-size: cover