Come posso simulare la funzionalità di background-size:cover
su un elemento html come <video>
o <img>
?
Mi piacerebbe che funzionasse come
background-size: cover;
background-position: center center;
Come posso simulare la funzionalità di background-size:cover
su un elemento html come <video>
o <img>
?
Mi piacerebbe che funzionasse come
background-size: cover;
background-position: center center;
Risposte:
Questo è qualcosa su cui mi sono strappato i capelli per un po ', ma ho trovato un'ottima soluzione che non usa alcun copione e che posso ottenere una perfetta simulazione di copertina su video con 5 linee di CSS (9 se conti selettori e parentesi ). Questo ha 0 casi limite in cui non funziona perfettamente, a parte la compatibilità CSS3 .
Puoi vedere un esempio qui
Il problema con la soluzione di Timothy è che non gestisce correttamente il ridimensionamento. Se l'elemento circostante è più piccolo del file video, non viene ridimensionato. Anche se dai al tag video una dimensione iniziale minuscola, come 16px per 9px, auto
finisce per forzarlo al minimo della dimensione del file nativo. Con l'attuale soluzione più votata in questa pagina, è stato impossibile per me ridimensionare il file video con un effetto zoom drastico.
Se si conoscono le proporzioni del video, ad esempio 16: 9, è possibile effettuare le seguenti operazioni:
.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 */
}
Se l'elemento padre del video è impostato per coprire l'intera pagina (come position: fixed; width: 100%; height: 100vh;
), anche il video lo farà.
Se vuoi che anche il video sia centrato, puoi utilizzare l'approccio di centratura infallibile:
/* 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 */
}
Naturalmente, vw
, vh
, e transform
sono CSS3, quindi se avete bisogno di compatibilità con i browser molto più vecchi , avrete bisogno di script di uso.
vh
e vw
c'entra qualcosa?
L'uso della copertina di sfondo va bene per le immagini, così come la larghezza del 100%. Questi non sono ottimali per <video>
, e queste risposte sono eccessivamente complicate. Non è necessario jQuery o JavaScript per realizzare uno sfondo video a larghezza intera.
Tieni presente che il mio codice non coprirà completamente uno sfondo con un video come la copertina, ma renderà il video grande quanto deve essere per mantenere le proporzioni e coprire comunque l'intero sfondo. Qualsiasi video in eccesso verrà rimosso dal bordo della pagina, i cui lati dipendono da dove ancorare il video.
La risposta è abbastanza semplice
Usa questo codice video HTML5 o qualcosa del genere: (prova in Pagina Completa)
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>
L'altezza minima e la larghezza minima consentiranno al video di mantenere le proporzioni del video, che di solito è le proporzioni di qualsiasi browser normale a una risoluzione normale. Qualsiasi video in eccesso fuoriesce dal lato della pagina.
min-width
o min-height
fare il trucco.
position: absolute; left: 50%; top: 50%; transform: translateX(-50%) translateY(-50%);
.
height: 100%; width: 100%;
. grazie per questa risposta moderna
Ecco come l'ho fatto. Un esempio funzionante è in questo 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%; }
e funziona come un incantesimo.
background-size: cover
un video.
Le altre risposte sono state buone ma coinvolgono javascript o non centrano il video in senso orizzontale e verticale.
Puoi utilizzare questa soluzione CSS completa per avere un video che simuli la dimensione dello sfondo: proprietà copertina:
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;
}
Sulla base della risposta e dei commenti di Daniel de Wit , ho cercato un po 'di più. Grazie a lui per la soluzione.
La soluzione è utilizzare object-fit: cover;
che ha un ottimo supporto (ogni browser moderno lo supporta). Se vuoi davvero supportare IE, puoi usare un polyfill come object-fit-images o object-fit .
Demo:
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"/>
e con un genitore:
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
e width
ed height
impostato al 100%, si ottiene un proporzionalmente in scala img
o video
ingrandito sul centro senza tante storie.
La soluzione di M-Pixel è eccezionale in quanto risolve il problema di ridimensionamento della risposta di Timothy (il video si ingrandirà ma non diminuirà, quindi se il tuo video è davvero grande ci sono buone possibilità che vedrai solo un piccolo zoom in parte di esso). Tuttavia, tale soluzione si basa su presupposti falsi relativi alla dimensione del contenitore video, ovvero che è necessariamente pari al 100% della larghezza e dell'altezza del viewport. Ho trovato alcuni casi in cui non ha funzionato per me, quindi ho deciso di affrontare il problema da solo e credo di aver trovato la soluzione definitiva .
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%);
}
Si basa anche sul rapporto del video, quindi se il tuo video ha un rapporto diverso da 16/9 ti consigliamo di modificare la percentuale di riempimento inferiore. A parte questo, funziona fuori dagli schemi. Testato su IE9 +, Safari 9.0.1, Chrome 46 e Firefox 41.
Da quando ho pubblicato questa risposta ho scritto un piccolo modulo CSS per simulare entrambi background-size: cover
e background-size: contain
su <video>
elementi: http://codepen.io/benface/pen/NNdBMj
Supporta diversi allineamenti per il video (simile a background-position
). Si noti inoltre che l' contain
implementazione non è perfetta. Diversamente background-size: contain
, non ridimensionerà il video oltre la sua dimensione effettiva se la larghezza e l'altezza del contenitore sono maggiori, ma penso che in alcuni casi possa essere ancora utile. Ho anche aggiunto speciali fill-width
e fill-height
classi che puoi usare insieme contain
per ottenere un mix speciale di contain
e cover
... provalo e sentiti libero di migliorarlo!
object-fit: cover
per FF e Chrome e la tua soluzione con Modernizr per IE
object-fit: cover
è la risposta migliore con questo IE, Safari Polyfill.
https://github.com/constancecchen/object-fit-polyfill
Esso sostiene img
, video
e picture
gli elementi.
CSS e js piccoli possono far sì che il video copra lo sfondo e sia centrato orizzontalmente.
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: (associa questo con il ridimensionamento della finestra e chiama una volta separatamente)
$('#bgvid').css({
marginLeft : '-' + ($('#bgvid').width()/2) + 'px'
})
Subito dopo la nostra lunga sezione di commenti, penso che questo sia quello che stai cercando, è basato su 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;
}
Il codice sopra sta usando la larghezza e l'altezza del browser se lo facevi all'interno di un div, dovresti cambiarlo in qualcosa del genere:
Per 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;
}
Dovrei anche affermare che ho solo testato questo è Google Chrome ... ecco un jsfiddle: http://jsfiddle.net/ADCKk/
La risposta migliore non riduce il video quando la larghezza del browser è inferiore a quella del video. Prova a utilizzare questo CSS (con #bgvid come ID del tuo video):
#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
necessario il negativo ?
Sto anche postando questa soluzione, dato che ho avuto questo problema ma le altre soluzioni non hanno funzionato per la mia situazione ...
penso di simulare correttamente la background-size:cover;
proprietà css su un elemento anziché una proprietà background-image degli elementi, dovresti confrontare le proporzioni delle immagini con le attuali proporzioni di Windows, quindi indipendentemente dalle dimensioni (e anche nel caso in cui l'immagine sia più alta che più larga) la finestra è l'elemento che sta riempiendo la finestra (e anche centrandola, anche se non so se fosse un requisito) ...
usando un'immagine, solo per semplicità, sono sicuro che anche un elemento video funzionerebbe bene.
prima ottieni le proporzioni degli elementi (una volta caricato), quindi collega il gestore di ridimensionamento della finestra, attivalo una volta per il dimensionamento iniziale:
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();
}
quindi nel gestore di ridimensionamento dovresti prima determinare se riempire la larghezza o l'altezza di riempimento confrontando le proporzioni correnti della finestra con le proporzioni originali dell'immagine.
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";
}
}
Questo approccio utilizza solo CSS e HTML. Puoi effettivamente impilare facilmente un div sotto il video. È coperto ma non centrato durante il ridimensionamento.
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*/
}
Questa domanda ha una generosità aperta del valore di +100 reputazione da Hobby nascosti che termina in 6 giorni. Uso inventivo delle unità viewport per ottenere una soluzione flessibile solo CSS.
Hai aperto una taglia su questa domanda per una soluzione solo CSS, quindi ci proverò. La mia soluzione a un problema come questo è utilizzare un rapporto fisso per decidere l'altezza e la larghezza del video. Di solito uso Bootstrap, ma da lì ho estratto il CSS necessario per farlo funzionare senza. Questo è un codice che ho usato prima tra l'altro per centrare un video incorporato con il rapporto corretto. Dovrebbe funzionare per <video>
e<img>
gli elementi troppo E 'la parte superiore quella che qui interessa, ma vi ha dato gli altri due pure poiché ho già avuto di loro, che in giro. Buona fortuna! :)
jsfiddle esempio a schermo intero
.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>
Per rispondere al commento di Weotch che la risposta di Timothy Ryan Carpenter non tiene contocover
del centramento dello sfondo, offro questa rapida correzione CSS:
CSS:
margin-left: 50%;
transform: translateX(-50%);
L'aggiunta di queste due linee centrerà qualsiasi elemento. Ancora meglio, tutti i browser in grado di gestire video HTML5 supportano anche trasformazioni CSS3, quindi funzionerà sempre.
Il CSS completo è simile al seguente.
#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%);
}
Avrei commentato direttamente la risposta di Timothy, ma non ho abbastanza reputazione per farlo.
Ragazzi, ho una soluzione migliore, breve e funziona perfettamente per me. L'ho usato per i video. Ed emula perfettamente l'opzione di copertina in 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%");
}
});
Se capovolgi il if, altrimenti otterrai.
Ed ecco il css. (Non è necessario utilizzarlo se non si desidera il posizionamento centrale, il div parent deve essere " position: relative ")
CSS
video {
position: absolute;
-webkit-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
top: 50%;
left: 50%;}
Ho appena risolto questo e volevo condividere. Funziona con Bootstrap 4. Funziona con img
ma non l'ho provato video
. Ecco HAML e 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="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>
Vecchia domanda, ma nel caso qualcuno lo veda, la migliore risposta secondo me è convertire il video in una GIF animata. Questo ti dà molto più controllo e puoi semplicemente trattarlo come un'immagine. È anche l'unico modo per farlo funzionare su dispositivi mobili, poiché non è possibile riprodurre automaticamente i video. So che la domanda è chiedere di farlo in un <img>
tag, ma non vedo davvero il rovescio della medaglia di usare a <div>
e farebackground-size: cover
.gif
è molto più grande, anche se più sfocata. La mia opinione è cambiata da quando ho scritto questa risposta. È un peccato non riuscire a combinare il meglio di entrambi.