Javascript 在 <video> 或 <img> 上模拟 background-size:cover
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10797632/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
simulate background-size:cover on <video> or <img>
提问by seron
How can I simulate the functionality of background-size:cover
on an html element like <video>
or <img>
?
如何模拟background-size:cover
html 元素上的功能,例如<video>
或<img>
?
I'd like it to work like
我希望它像
background-size: cover;
background-position: center center;
采纳答案by seron
Here's how I did this. A working example is in this jsFiddle.
这是我如何做到的。一个工作示例在这个 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>
回答by M-Pixel
This is something I pulled my hair out over for a while, but I came across a great solution that doesn't use any script, and can achieve a perfect cover simulation on video with 5 lines of CSS (9 if you count selectors and brackets). This has 0 edge-cases in which it doesn't work perfectly, short of CSS3-compatibility.
这是我拉扯了一段时间的东西,但我遇到了一个很好的解决方案,它不使用任何脚本,并且可以使用 5 行 CSS(如果算上选择器和括号,则为 9 行)在视频上实现完美的封面模拟)。这有 0 个边缘情况,它不能完美地工作,缺少 CSS3-compatibility。
You can see an example here
你可以在这里看到一个例子
The problem with Timothy's solution, is that it doesn't handle scaling correctly. If the surrounding element is smaller than the video file, it isn't scaled down. Even if you give the video tag a tiny initial size, like 16px by 9px, auto
ends up forcing it to a minimum of its native file-size. With the current top-voted solution on this page, it was impossible for me to have the video file scale down resulting in a drastic zoom effect.
Timothy 的解决方案的问题在于它不能正确处理缩放。如果周围的元素小于视频文件,则不会按比例缩小。即使你给视频标签一个很小的初始大小,比如 16 像素 x 9 像素,auto
最终会强制它最小化其原生文件大小。使用此页面上当前最高投票的解决方案,我不可能缩小视频文件的比例,从而产生剧烈的缩放效果。
If the aspect ratio of your video is known, however, such as 16:9, you can do the following:
但是,如果您的视频的纵横比已知,例如 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 */
}
If the video's parent element is set to cover the entire page (such as position: fixed; width: 100%; height: 100vh;
), then the video will, too.
如果视频的父元素设置为覆盖整个页面(例如position: fixed; width: 100%; height: 100vh;
),则视频也将覆盖整个页面。
If you want the video centered as well, you can use the surefire centering approach:
如果您还希望视频居中,则可以使用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 */
}
Of course, vw
, vh
, and transform
are CSS3, so if you need compatibility with much older browsers, you'll need to use script.
当然,vw
、vh
和transform
是CSS3,所以如果您需要与更旧的浏览器兼容,您将需要使用脚本。
回答by Timothy Ryan Carpenter
jsFiddle
js小提琴
Using background cover is fine for images, and so is width 100%. These are not optimal for <video>
, and these answers are overly complicated. You do not need jQuery or JavaScript to accomplish a full width video background.
使用背景覆盖对图像来说很好,宽度 100% 也是如此。这些不是最佳的<video>
,而且这些答案过于复杂。您不需要 jQuery 或 JavaScript 来完成全宽视频背景。
Keep in mind that my code will not cover a background completely with a video like cover will, but instead it will make the video as big as it needs to be to maintain aspect ratio and still cover the whole background. Any excess video will bleed off the page edge, which sides depend on where you anchor the video.
请记住,我的代码不会像封面那样用视频完全覆盖背景,而是会使视频尽可能大,以保持纵横比并仍然覆盖整个背景。任何多余的视频都会从页面边缘溢出,这取决于您锚定视频的位置。
The answer is quite simple.
答案很简单。
Just use this HTML5 video code, or something along these lines: (test in Full Page)
只需使用此 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>
The min-height and min-width will allow the video to maintain the aspect ratio of the video, which is usually the aspect ratio of any normal browser at a normal resolution. Any excess video bleeds off the side of the page.
min-height 和 min-width 将允许视频保持视频的纵横比,这通常是任何普通浏览器在正常分辨率下的纵横比。任何多余的视频都会从页面的一侧流出。
回答by Dani?l de Wit
For some browsers you can use
对于某些浏览器,您可以使用
object-fit: cover;
回答by aloisdg moving to codidact.com
Based on Daniel de Wit's answerand comments, I searched a bit more. Thanks to him for the solution.
根据Daniel de Wit 的回答和评论,我进行了更多搜索。感谢他的解决方案。
The solution is to use object-fit: cover;
which has a great support(every modern browser support it). If you really want to support IE, you can use a polyfill like object-fit-imagesor object-fit.
解决方案是使用object-fit: cover;
它有很大的支持(每个现代浏览器都支持它)。如果你真的想支持 IE,你可以使用像object-fit-images或object-fit这样的 polyfill 。
Demos :
演示:
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"/>
and with a parent:
并与父母:
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>
回答by micred
The other answers were good but they involve javascript or they doesn't center the video horizontally AND vertically.
其他答案很好,但它们涉及 javascript 或者它们没有水平和垂直居中视频。
You can use this full CSS solution to have a video that simulate the background-size: cover property:
您可以使用这个完整的 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;
}
回答by benface
M-Pixel's solutionis great in that it solves the scaling problem of Timothy's answer(the video will scale up but not down, so if your video is really large there are good chances you will only see a small zoomed in part of it). However, that solution is based on false assumptions related to the size of the video container, namely that it is necessarily 100% of the viewport's width and height. I have found a few cases where it didn't work for me, so I decided to tackle the problem myself, and I believe I came up with the ultimate solution.
M-Pixel 的解决方案很棒,因为它解决了Timothy 答案的缩放问题(视频会放大但不会缩小,因此如果您的视频非常大,很有可能您只会看到其中的一小部分放大)。但是,该解决方案基于与视频容器大小相关的错误假设,即它必须是视口宽度和高度的 100%。我发现了一些对我不起作用的情况,所以我决定自己解决这个问题,我相信我想出了最终的解决方案。
HTML
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
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%);
}
It is also based on the ratio of the video, so if your video has a ratio other than 16 / 9 you will want to change the padding-bottom %. Other than that, it works out of the box. Tested in IE9+, Safari 9.0.1, Chrome 46, and Firefox 41.
它也基于视频的比例,因此如果您的视频的比例不是 16 / 9,您将需要更改 padding-bottom %。除此之外,它开箱即用。在 IE9+、Safari 9.0.1、Chrome 46 和 Firefox 41 中测试。
EDIT (March 17, 2016)
编辑(2016 年 3 月 17 日)
Since I posted this answer I've written a small CSS module to simulate both background-size: cover
and background-size: contain
on <video>
elements: http://codepen.io/benface/pen/NNdBMj
由于我张贴了这个答案我写了一个小的CSS模块来模拟background-size: cover
和background-size: contain
对<video>
元素:http://codepen.io/benface/pen/NNdBMj
It supports different alignments for the video (similar to background-position
). Also note that the contain
implementation is not perfect. Unlike background-size: contain
, it won't scale the video past its actual size if the container's width and height are bigger, but I think it can still be useful in some cases. I've also added special fill-width
and fill-height
classes that you can use together with contain
to get a special mix of contain
and cover
... try it out, and feel free to improve it!
它支持视频的不同对齐方式(类似于background-position
)。还要注意,contain
实现并不完美。与 不同background-size: contain
,如果容器的宽度和高度更大,它不会将视频缩放到超过其实际大小,但我认为它在某些情况下仍然有用。我还添加了特殊fill-width
和fill-height
类,您可以将它们与contain
它们一起使用以获得特殊的contain
和cover
……尝试一下,并随时改进它!
回答by fozuse
object-fit: cover
is the best answer with this IE, Safari polyfill.
object-fit: cover
是这个 IE,Safari polyfill 的最佳答案。
https://github.com/constancecchen/object-fit-polyfill
https://github.com/constancecchen/object-fit-polyfill
It is supporting img
, video
and picture
elements.
它支持img
,video
和picture
元素。
回答by Salim Hariz
CSS and little js can make the video cover the background and horizontally centered.
CSS 和小 js 可以让视频覆盖背景并水平居中。
CSS:
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: (bind this with window resize and call once seperately)
JS:(将其与窗口调整大小绑定并单独调用一次)
$('#bgvid').css({
marginLeft : '-' + ($('#bgvid').width()/2) + 'px'
})
回答by Lennart
Right after our long comment section, I think this is what you're looking for, it's jQuery based:
在我们的长评论部分之后,我认为这就是您要寻找的,它基于 jQuery:
HTML:
HTML:
<img width="100%" id="img" src="http://uploads8.wikipaintings.org/images/william-adolphe-bouguereau/self-portrait-presented-to-m-sage-1886.jpg">
JS:
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:
CSS:
body{
overflow: hidden;
}
?The code above is using the browsers width and height if you where doing this within a div, you would have to change it to something like this:
?上面的代码使用浏览器的宽度和高度,如果你在一个 div 中这样做,你必须把它改成这样:
For Div:
对于 Div:
HTML:
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:
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:
CSS:
div{
overflow: hidden;
}
I should also state that I've only tested this is Google Chrome... here is a jsfiddle: http://jsfiddle.net/ADCKk/
我还应该声明我只测试过这是谷歌浏览器......这是一个jsfiddle:http: //jsfiddle.net/ADCKk/