如何在像<video>或<img>这样的HTML元素上模拟background-size:cover
的功能?
我希望它能像这样工作
background-size: cover;
background-position: center center;
如何在像<video>或<img>这样的HTML元素上模拟background-size:cover
的功能?
我希望它能像这样工作
background-size: cover;
background-position: center center;
这是一件让我苦恼了一段时间的事情,但我找到了一个绝佳的解决方案,它不使用任何脚本,并且可以用5行CSS(如果计算选择器和括号,则为9行)实现视频的完美覆盖模拟。 除了CSS3兼容性之外,它没有任何不能完美工作的边缘情况。
你可以在这里看到一个示例(已存档)
而Timothy的解决方案存在问题,就是它无法正确处理缩放。如果周围元素比视频文件小,它不会缩小。即使您给视频标记一个微小的初始大小,如16像素乘以9像素,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的一部分,因此如果你需要与旧浏览器兼容,你将需要使用脚本。
height: 100%; width: 100%;
。谢谢这个现代的回答。 - Jossef Harush Kadouri使用背景覆盖对于图像来说很好,宽度为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>
最小高度和最小宽度将使视频保持视频的纵横比,通常为普通分辨率下任何正常浏览器的纵横比。任何多余的视频都会溢出页面的一侧。
min-width
或 min-height
即可解决问题。 - Ryan Burneyposition: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
- Sjeiti以下是我是如何做到的。一个可用的示例在这个 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>
video {min-width: 100%; min-height:100%;}
,它就像魔术般地工作。 - Alexandre DuBreuil根据Daniel de Wit的答案及其评论,我进行了更多搜索。感谢他提供的解决方案。
解决方案是使用object-fit: cover;
,它具有很好的支持(每个现代浏览器都支持它)。如果你确实想支持IE,可以使用类似object-fit-images或object-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>
object-fit: cover
,并将 width
和 height
设置为 100%,您可以轻松获得一个比例缩放的 img
或 video
,并且居中放大而无需任何麻烦。 - phip其他答案都不错,但它们涉及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;
}
M-Pixel的解决方案非常出色,它解决了Timothy答案中的缩放问题(视频将会被放大但不会被缩小,所以如果你的视频非常大,你只能看到一个小的放大部分)。然而,该解决方案是基于对视频容器大小的错误假设,即其必须是视口宽度和高度的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中进行测试。
自从我发布了这个答案后,我编写了一个小型CSS模块,在<video>
元素上模拟了background-size: cover
和background-size: contain
:http://codepen.io/benface/pen/NNdBMj
它支持不同的视频对齐方式(类似于background-position
)。同时请注意,contain
实现并不完美。与background-size: contain
不同,如果容器的宽度和高度更大,它不会将视频缩放到其实际大小,但我认为在某些情况下仍然有用。我还添加了特殊的fill-width
和fill-height
类,您可以将它们与contain
一起使用,以获得contain
和cover
的特殊组合...尝试一下,随时可以改进它!
object-fit: cover
,而你使用Modernizr来解决IE的问题。 - MrThunderobject-fit: cover
是在 IE 和 Safari 中使用的最佳解决方案之一,可以通过这个多功能插件实现。
https://github.com/constancecchen/object-fit-polyfill
它支持 img
、video
和 picture
元素。
video#bgvid {
position: absolute;
bottom: 0px;
left: 50%;
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
z-index: -1;
overflow: hidden;
}
JS:(将this与窗口大小调整绑定并分别调用一次)
$('#bgvid').css({
marginLeft : '-' + ($('#bgvid').width()/2) + 'px'
})
<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>
div{
overflow: hidden;
}
我还要声明一下,我只在Google Chrome中测试过这个... 这里是一个jsfiddle: http://jsfiddle.net/ADCKk/
cover
有一些微妙之处。请参阅链接上的“背景大小 101”。 - ivvi