Как смоделировать функции background-size:cover
в элементе html, например <video>
или <img>
?
Мне бы хотелось, чтобы он работал как
background-size: cover;
background-position: center center;
Как смоделировать функции background-size:cover
в элементе html, например <video>
или <img>
?
Мне бы хотелось, чтобы он работал как
background-size: cover;
background-position: center center;
Вот как я это сделал. Рабочим примером является этот 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>
Использование фонового покрытия отлично подходит для изображений, а значит, и ширина 100%. Они не являются оптимальными для <video>
, и эти ответы слишком сложны. Вам не нужно jQuery или JavaScript для создания полноформатного видео фона.
Имейте в виду, что мой код не будет полностью покрывать фон с видео, как на обложке, но вместо этого он сделает видео настолько большим, насколько это необходимо, чтобы поддерживать соотношение сторон и по-прежнему охватывать весь фон. Любое избыточное видео сбрасывается с края страницы, в зависимости от того, где вы привязываете видео.
Ответ довольно прост.
Просто используйте этот видеокод HTML5 или что-то в этом роде: (test in Full Page)
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>
Это то, что я вытащил из волос на некоторое время, но я столкнулся с отличным решением, которое не использует никаких script, и может добиться идеального моделирования покрытия на видео с 5 строками CSS (9 if вы считаете селекторы и скобки). У этого есть 0 ребер, в которых он не работает отлично, за исключением CSS3-совместимости.
Вы можете увидеть пример здесь
Проблема с решением Timothy заключается в том, что он неправильно обрабатывает масштабирование. Если окружающий элемент меньше видеофайла, он не уменьшается. Даже если вы дадите видеотеку крошечный начальный размер, например 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;
), то также будет и видео.
Если вы хотите, чтобы видеоцентрировалось также, вы можете использовать подход центрирования с уверенностью:
/* 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, поэтому, если вам нужна совместимость с гораздо более старыми браузерами, вам нужно будет использовать script.
Для некоторых браузеров вы можете использовать
object-fit: cover;
Другие ответы были хорошими, но они включают 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 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, вы захотите изменить нижний уровень заполнения. Помимо этого, он работает из коробки. Протестировано в IE9 +, Safari 9.0.1, Chrome 46 и Firefox 41.
Поскольку я отправил этот ответ, я написал небольшой CSS-модуль для имитации элементов background-size: cover
и background-size: contain
на <video>
: http://codepen.io/benface/pen/NNdBMj
Он поддерживает различные настройки для видео (аналогично background-position
). Также обратите внимание, что реализация contain
не идеальна. В отличие от background-size: contain
, он не будет масштабировать видео до его фактического размера, если ширина и высота контейнера больше, но я думаю, что он может быть полезен в некоторых случаях. Я также добавил специальные классы fill-width
и fill-height
, которые вы можете использовать вместе с contain
, чтобы получить специальное сочетание contain
и cover
... попробуйте, и не стесняйтесь его улучшать!
Основываясь на ответе и комментариях Даниэля де Вита, я искал немного больше. Спасибо ему за решение.
Решение состоит в том, чтобы использовать object-fit: cover;
который имеет большую поддержку (все современные браузеры поддерживают его). Если вы действительно хотите поддерживать IE, вы можете использовать polyfill как object-fit-images или object-fit.
Демоверсии:
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"/>
object-fit: cover
- лучший ответ с этим IE, Safari polyfill.
https://github.com/constancecchen/object-fit-polyfill
Он поддерживает элементы img
, video
и picture
.
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'
})
Сразу после нашей длинной секции комментариев, я думаю, что это то, что вы ищете, на основе 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/
Верхний ответ не уменьшает масштаб видео, если ширина браузера меньше ширины вашего видео. Попробуйте использовать этот CSS (С#bgvid, являющимся вашим идентификатором видео):
#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%);
}
Я тоже знаю, что это проблема, потому что у меня была эта проблема, но другие решения не работали для моей ситуации...
Я думаю, чтобы правильно имитировать свойство 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";
}
}
Этот подход использует только css и html. Вы можете легко складывать divs под видео. Это покрытие, но не центрированное при изменении размера.
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*/
}
У этого вопроса есть открытая награда, стоящая +100 репутации от Скрытых Гоббсов, заканчивающихся через 6 дней. Изобретательное использование единиц просмотра, чтобы получить гибкое решение только для CSS.
Вы открыли щедрость по этому вопросу для решения только для CSS, поэтому я дам ему попробовать. Мое решение такой проблемы заключается в использовании фиксированного соотношения для определения высоты и ширины видео. Обычно я использую Bootstrap, но я извлек из него необходимый CSS, чтобы он работал без него. Это код, который я использовал ранее, среди прочего, в центре встроенного видео с правильным соотношением. Он должен работать и для элементов <video>
и <img>
. Это верхний, который здесь имеет значение, но я дал вам и другие два, так как я уже их клал. Удачи!:)
.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>
Старый вопрос, но в случае, если кто-либо это увидит, лучшим ответом, на мой взгляд, является преобразование видео в анимированный GIF. Это дает вам гораздо больше контроля, и вы можете просто рассматривать его как образ. Это также единственный способ работать на мобильных устройствах, поскольку вы не можете автоматически запускать видео. Я знаю, что вопрос просит сделать это в теге <img>
, но я не вижу недостатков в использовании <div>
и делает background-size: cover
Чтобы ответить на комментарий weotch, ответ Тимоти Райан Карпентер не учитывает 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%);
}
Я бы сразу прокомментировал ответ Тимоти, но у меня недостаточно репутации, чтобы сделать это.
Ребята, у меня есть лучшее решение, и оно отлично работает для меня. Я использовал его для видео. И он отлично эмулирует опцию обложки в 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 должен быть "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
. Вот 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="#" onclick="location.href='https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css'; return false;" rel="stylesheet"/>
<div class="container">
<div class="center-cover d-flex align-items-center">
<img src="http://placehold.it/1000x700">
</div>
</div>