Как я могу имитировать функциональность 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;
Ответы:
Это то, что я вырвал на некоторое время, но я наткнулся на отличное решение, которое не использует сценарий и может обеспечить идеальное моделирование обложки на видео с 5 строками CSS (9, если вы считаете селекторы и скобки) ). Это имеет 0 крайних случаев, в которых он не работает идеально, за исключением CSS3-совместимости .
Вы можете увидеть пример здесь
Проблема с решением Тимофея в том , что он неправильно обрабатывает масштабирование. Если окружающий элемент меньше видеофайла, он не уменьшается. Даже если вы дадите видео тегу крошечный начальный размер, например 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, поэтому если вам нужна совместимость с более старыми браузерами , вам нужно использовать сценарий.
vhи vwчто общего?
Использование фонового покрытия подходит для изображений, как и ширина 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делает трюк.
position: absolute; left: 50%; top: 50%; transform: translateX(-50%) translateY(-50%);.
height: 100%; width: 100%;. спасибо за этот современный ответ
Вот как я это сделал. Рабочий пример находится в этом 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%; }и он работает как шарм.
background-size: 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;
}
Основываясь на ответе и комментариях Даниэля де Вит , я искал немного больше. Спасибо ему за решение.
Решением является использование, 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"/>
и с родителем:
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увеличенный по центру без суеты.
Решение 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.
Так как я опубликовал этот ответ я написал небольшой модуль 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для FF и Chrome, а ваше решение с Modernizr для IE
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%);
}
z-indexнужен?
я тоже хочу опубликовать это решение, так как у меня была эта проблема, но другие решения не работали для моей ситуации ...
я думаю, чтобы правильно моделировать background-size:cover; свойство css для элемента вместо свойства background-image elements, вам нужно сравнить соотношение сторон изображения с текущим соотношением сторон окна, поэтому независимо от того, какой размер (а также в случае, если изображение выше, чем шире) окно - элемент, заполняющий окно (и также центрирующий его, хотя я не знаю, было ли это требованием) ....
используя изображение, просто для простоты, я уверен, что элемент видео тоже будет работать нормально.
сначала получите соотношение сторон элементов (как только оно будет загружено), затем присоедините обработчик изменения размера окна, активируйте его один раз для первоначального определения размера:
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. Вы можете легко сложить 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*/
}
Этот вопрос имеет открытую награду +100 репутации от Hidden Hobbes и заканчивается через 6 дней. Изобретательное использование единиц просмотра для получения гибкого решения только для CSS.
Вы открыли награду за этот вопрос только для решения CSS, поэтому я попробую. Мое решение такой проблемы - использовать фиксированное соотношение для определения высоты и ширины видео. Я обычно использую Bootstrap, но я извлек из него необходимый 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&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>
Чтобы ответить на комментарий 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: родственник »)
CSS
video {
position: absolute;
-webkit-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
top: 50%;
left: 50%;}
Я просто решил это и хотел поделиться. Это работает с Bootstrap 4. Это работает с, imgно я не проверял это с video. Вот ХАМЛ и СКС
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
.gifэто намного больше по размеру, но при этом более размыто. Мое мнение изменилось с тех пор, как я написал этот ответ. Жаль, что вы не можете объединить лучшее из обоих.