simuler la taille du fond: couverture sur <video> ou <img>

154

Comment puis-je simuler la fonctionnalité d' background-size:coverun élément html comme <video>ou <img>?

J'aimerais que ça marche comme

background-size: cover;
background-position: center center;
seron
la source
1
d'accord, je n'ai jamais utilisé background-size: cover; mais je l'ai regardé en ligne, alors ce que vous voulez est un moyen d'avoir une image / vidéo plein écran qui se redimensionne lorsque la fenêtre se redimensionne?
Lennart
Oui, mais il y a des subtilités avec cover. Voir la taille de fond 101 sur le lien .
seron
d'accord donc pour simplifier à 100% la largeur d'une image / vidéo et s'il y a un débordement il est coupé? Si vous voulez cela, je peux voir si je peux coder cela, mais pour la vidéo, vous devez garder à l'esprit que vous auriez besoin d'un lecteur personnalisé car dans la plupart des navigateurs, les commandes sont au bas du lecteur et elles seraient coupées s'il y avait is an overflow ...
Lennart
Oui, débordement également des côtés opposés. Je suis conscient du problème des commandes vidéo.
seron
1
Si la fenêtre est plus haute que l'image, elle laissera un espace vide quelque part le long de l'axe vertical, je pense. Dans un tel cas, l'image doit au contraire déborder sur les côtés et sa hauteur doit être la même que la fenêtre. Et l'inverse devrait se produire lorsque la fenêtre est plus large que l'image.
seron

Réponses:

142

C'est quelque chose sur lequel je me suis tiré les cheveux pendant un moment, mais je suis tombé sur une excellente solution qui n'utilise aucun script, et peut réaliser une simulation de couverture parfaite sur vidéo avec 5 lignes de CSS (9 si vous comptez les sélecteurs et les crochets ). Cela a 0 cas extrêmes dans lesquels cela ne fonctionne pas parfaitement, à moins de compatibilité CSS3 .

Vous pouvez voir un exemple ici

Le problème avec la solution de Timothy , c'est qu'elle ne gère pas correctement la mise à l'échelle. Si l'élément environnant est plus petit que le fichier vidéo, il n'est pas réduit. Même si vous donnez à la balise vidéo une taille initiale minuscule, comme 16px par 9px, autofinit par la forcer à un minimum de sa taille de fichier native. Avec la solution actuelle la plus votée sur cette page, il était impossible pour moi de réduire l'échelle du fichier vidéo, ce qui entraînerait un effet de zoom drastique.

Si le rapport hauteur / largeur de votre vidéo est connu, par exemple 16: 9, vous pouvez effectuer les opérations suivantes:

.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 */
}

Si l'élément parent de la vidéo est défini pour couvrir toute la page (par exemple position: fixed; width: 100%; height: 100vh;), la vidéo le sera également.

Si vous souhaitez également centrer la vidéo, vous pouvez utiliser l'approche de centrage infaillible:

/* 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 */
}

Bien sûr, vw, vhet transformsont CSS3, donc si vous avez besoin d'une compatibilité avec les navigateurs beaucoup plus anciens , vous devez utilisez un script.

M-Pixel
la source
3
C'est la meilleure réponse. Pas de javascript, pur CSS, mise à l'échelle correctement et centrée.
mark.monteiro
6
Ah ouais mec. Voici LA réponse pour 2016. Ignorez toutes les autres.
Josh Burson
voudriez-vous expliquer pourquoi cela fonctionne? Je ne peux pas m'enrouler la tête autour de ça. qu'est-ce que vhet vwa à voir avec quoi que ce soit?
commonpike
1
@insidesin: Publier un violon?
M-Pixel
2
En 2020, la meilleure solution est l'adaptation à l'objet: couverture, comme décrit dans la réponse de Daniël de Wit
Brett Donald
128

jsFiddle

L'utilisation de la couverture d'arrière-plan convient aux images, tout comme la largeur de 100%. Celles-ci ne sont pas optimales pour <video>, et ces réponses sont trop compliquées. Vous n'avez pas besoin de jQuery ou de JavaScript pour créer un arrière-plan vidéo pleine largeur.

Gardez à l'esprit que mon code ne couvrira pas complètement un arrière-plan avec une vidéo comme la couverture le fera, mais au lieu de cela, il rendra la vidéo aussi grande que nécessaire pour maintenir les proportions et couvrir tout l'arrière-plan. Tout excès de vidéo saignera du bord de la page, dont les côtés dépendent de l'endroit où vous ancrez la vidéo.

La réponse est assez simple.

Utilisez simplement ce code vidéo HTML5, ou quelque chose du genre: (test en pleine 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>

La hauteur min et la largeur min permettront à la vidéo de conserver le rapport hauteur / largeur de la vidéo, qui est généralement le rapport hauteur / largeur de tout navigateur normal à une résolution normale. Tout excès de vidéo saigne sur le côté de la page.

Timothy Ryan Carpenter
la source
2
C'est beaucoup plus simple que les autres réponses et cela fonctionne très bien pour moi. Il suffit de régler min-widthou de min-heightfaire l'affaire.
Ryan Burney
31
Cette solution ne centre pas la vidéo comme le fait la couverture.
weotch
1
juste un commentaire pour empêcher les débutants de s'arracher les cheveux: #video_background {devrait être #videobackground {.
carrabino

21
Cela ne réduit pas du tout une vidéo (je n'ai pas essayé d'en augmenter une), ce qui pose de nombreux problèmes si la fenêtre du navigateur est petite et la vidéo est grande. Donc, fondamentalement, il ne s'occupe que de la partie de fond perdu de la taille de l'arrière-plan: la couverture, pas la partie de mise à l'échelle.
Kevin Newman

4
Avec les technologies actuelles, cela devrait être la réponse acceptée: une solution CSS est préférable à une solution Javascript. Même si cela vous oblige à définir correctement votre parentNode. Pour centrer la vidéo, utilisez: position: absolute; left: 50%; top: 50%; transform: translateX(-50%) translateY(-50%);.
Sjeiti

101

Pour certains navigateurs, vous pouvez utiliser

object-fit: cover;

http://caniuse.com/object-fit


15
Il s'agit d'une déclaration très puissante qui, si les navigateurs l'adoptaient, mettrait fin à de nombreux problèmes liés à la mise à l'échelle des sites Web.
Mike Kormendy

1
Ceci est exactement ce que je cherchais!
Peter_Fretter

3
Il existe un polyfill pour les navigateurs qui ne le supportent pas (encore): github.com/anselmh/object-fit
creimers

7
devait également postuler height: 100%; width: 100%;. merci pour cette réponse moderne
Jossef Harush

J'ai fait une réponse basée sur celle-ci avec des exemples et des informations . Merci d'avoir signalé cette fonctionnalité!
aloisdg passe à codidact.com

43

Voici comment j'ai fait ça. Un exemple de travail est dans ce 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>


Pourquoi cette solution a-t-elle été rejetée? À toutes fins utiles, il semble résoudre le problème.
Jan

2
C'est la meilleure solution que j'ai trouvée pour ce problème. Merci!
Chaser324

1
Cela fonctionne très bien si la vidéo est grande et la fenêtre petite, mais ne fonctionnera pas pour moi si la fenêtre est plus grande que la vidéo et que la vidéo doit être mise à l'échelle. J'ai ajouté l'astuce min de @ Timothy-Ryan-Carpenter ( réponse ici ) à la balise vidéo comme: video { min-width: 100%; min-height: 100%; }et cela fonctionne comme un charme.
Alexandre DuBreuil

J'ai trouvé cette approche également utile et je l'ai emballée comme un simple plugin jQuery pour tous les intéressés: github.com/aMoniker/jquery.videocover
Jim Greenleaf

Malgré ce que dit @AlexandreDuBreuil, cela met à l'échelle les vidéos très bien (voyez par vous-même: fiddle.jshell.net/GCtMm/show ). C'est certainement la meilleure solution ici. Dommage que le JS soit si lourd par rapport à l'autre réponse ici, mais c'est ce dont vous avez besoin si vous voulez background-size: coverde la vidéo.
Chuck Le Butt

14

Les autres réponses étaient bonnes mais elles impliquent du javascript ou elles ne centrent pas la vidéo horizontalement ET verticalement.

Vous pouvez utiliser cette solution CSS complète pour avoir une vidéo qui simule la propriété 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;
  }

Cela n'a pas fonctionné pour moi. La vidéo n'a pas été mise à l'échelle en plein écran. Puis-je voir votre html pour cet exemple? Est-ce juste une balise vidéo dans le corps?
mat

Solution vraiment sympa. Cela n'a pas fonctionné pour moi au début, mais c'était probablement quelque chose que j'ai manqué parce que quand j'ai copié et collé votre css, cela a fonctionné! Merci;)
rafaelbiten

2
a très bien fonctionné pour moi. Je viens de changer de position: fixé à absolu
Assaf Katz

14

Sur la base de la réponse et des commentaires de Daniel de Wit , j'ai cherché un peu plus. Merci à lui pour la solution.

La solution est d'utiliser object-fit: cover;ce qui a un excellent support (tous les navigateurs modernes le supportent). Si vous voulez vraiment prendre en charge IE, vous pouvez utiliser un polyfill comme object-fit-images ou object-fit .

Démos:

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"/>

et avec un 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>


1
Meilleure réponse moderne.
Routhinator

1
C'est la réponse pour quiconque cible les navigateurs modernes. En utilisant object-fit: coveret widthet heightréglé sur 100%, vous obtenez une mise à l'échelle proportionnelle imgou un videozoom au centre sans aucun problème.
phip le

13

La solution de M-Pixel est excellente en ce sens qu'elle résout le problème de mise à l'échelle de la réponse de Timothy (la vidéo augmentera mais pas vers le bas, donc si votre vidéo est vraiment grande, il y a de bonnes chances que vous ne voyiez qu'une petite partie agrandie). Cependant, cette solution repose sur de fausses hypothèses liées à la taille du conteneur vidéo, à savoir qu'il correspond nécessairement à 100% de la largeur et de la hauteur de la fenêtre. J'ai trouvé quelques cas où cela n'a pas fonctionné pour moi, alors j'ai décidé de m'attaquer moi-même au problème et je pense avoir trouvé la solution ultime .

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%);
}

Il est également basé sur le rapport de la vidéo, donc si votre vidéo a un rapport autre que 16/9, vous voudrez changer le% de remplissage en bas. À part cela, cela fonctionne hors de la boîte. Testé dans IE9 +, Safari 9.0.1, Chrome 46 et Firefox 41.

EDIT (17 mars 2016)

Depuis que j'ai publié cette réponse, j'ai écrit un petit module CSS pour simuler à la fois background-size: coveret background-size: containsur les <video>éléments: http://codepen.io/benface/pen/NNdBMj

Il prend en charge différents alignements pour la vidéo (similaire à background-position). A noter également que la containmise en œuvre n'est pas parfaite. Contrairement à background-size: containcela, la vidéo ne sera pas mise à l'échelle au-delà de sa taille réelle si la largeur et la hauteur du conteneur sont plus grandes, mais je pense que cela peut toujours être utile dans certains cas. J'ai également ajouté des classes spéciales fill-widthet fill-heightque vous pouvez utiliser avec containpour obtenir un mélange spécial de containet cover... essayez-le, et n'hésitez pas à l'améliorer!


Cela ne met pas la vidéo à l'échelle au-dessus de la résolution normale pour l'adapter à 100% largeur / hauteur, quoi qu'il arrive. Ainsi, il ne reproduit pas la fonctionnalité de «couverture».
jetlej

@jetlej C'est le cas ici. Sur quel navigateur testez-vous? Avez-vous regardé mon codepen?
benface

1
Cela a bien fonctionné comme solution de secours sur Edge pour moi. Cheers
MrThunder

@MrThunder qu'est-ce que vous utilisez comme solution principale si vous l'utilisez comme solution de secours?
benface

1
@ benoitr007 J'ai utilisé object-fit: coverpour FF et chrome et votre solution avec Modernizr pour IE
MrThunder


4

CSS et little js peuvent faire en sorte que la vidéo couvre l'arrière-plan et soit centrée horizontalement.

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: (liez ceci avec le redimensionnement de la fenêtre et appelez une fois séparément)

$('#bgvid').css({
    marginLeft : '-' + ($('#bgvid').width()/2) + 'px'
})

3

Juste après notre longue section de commentaires, je pense que c'est ce que vous recherchez, c'est basé sur 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;
}

Le code ci-dessus utilise la largeur et la hauteur du navigateur si vous le faites dans un div, vous devriez le changer en quelque chose comme ceci:

Pour 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;
}

Je dois également préciser que je n'ai testé que Google Chrome ... voici un jsfiddle: http://jsfiddle.net/ADCKk/


Le jsfiddle ne semble rien faire lorsque je change la taille du cadre Résultat ou la taille du navigateur. J'ai essayé cela dans Chrome.
seron

Je l'ai mis à jour, mais j'ai toujours un léger problème: si vous réduisez trop la largeur, il saute soudainement ... jsfiddle.net/ADCKk/1
Lennart

d'accord, désolé mais je n'ai aucune idée, j'ai essayé tellement de choses que je pense m'être confus, je ne sais pas si c'est possible ... Le script ci-dessus ne fonctionne que lorsque vous actualisez la page, pour le faire fonctionner lorsque vous redimensionnez une fenêtre, vous devrez utiliser l'événement window.resize dans js, mais je ne peux pas le faire fonctionner, peut-être que vous pouvez avec cette information :) bonne chance quand même
Lennart

3

La réponse principale ne réduit pas la vidéo lorsque la largeur du navigateur est inférieure à la largeur de votre vidéo. Essayez d'utiliser ce CSS (avec #bgvid étant l'identifiant de votre vidéo):

#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%);
}

Pourquoi le négatif est-il z-indexnécessaire?
aleclarson

Ce n'est pas seulement utile lors de la conception avec plusieurs éléments en couches. Je l'ai supprimé.
Ramzi Dreessen

1

Je suis gunna poster cette solution aussi, car j'ai eu ce problème mais les autres solutions n'ont pas fonctionné pour ma situation ...

Je pense que pour simuler correctement la background-size:cover;propriété css sur un élément au lieu d'une propriété background-image éléments, il vous faudrait comparer le rapport d'aspect des images à la fenêtre courante rapport d'aspect, donc peu importe la taille (et aussi au cas où l'image est plus haut que large) la fenêtre est l'élément qui remplit la fenêtre (et la centre également, même si je ne sais pas si c'était une exigence) ....

en utilisant une image, juste pour des raisons de simplicité, je suis sûr qu'un élément vidéo fonctionnerait bien aussi.

obtenez d'abord le rapport hauteur / largeur des éléments (une fois qu'il est chargé), puis attachez le gestionnaire de redimensionnement de la fenêtre, déclenchez-le une fois pour le dimensionnement initial:

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();
}

Ensuite, dans votre gestionnaire de redimensionnement, vous devez d'abord déterminer s'il faut remplir la largeur ou la hauteur de remplissage en comparant le rapport hauteur / largeur actuel de la fenêtre au rapport hauteur / largeur d'origine de l'image.

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";
}

}

bawwb
1
Merci pour la réponse @turbopipp même si j'ai bien peur que vous ayez mal compris la raison de ma prime. Je l'ai soulevé afin de pouvoir l'attribuer à une réponse existante, cela ne me permettra pas de le faire tant que la prime n'aura pas été active pendant 24 heures. Néanmoins, +1 pour vos efforts, l'astuce du pourcentage de remplissage est un moyen utile de garantir qu'un élément conserve le bon rapport hauteur / largeur.
Hidden Hobbes du
Aha, eh bien, ce n'était vraiment pas un problème, et vraiment gentil de votre part de donner générosité aux réponses déjà existantes. Je suppose que je devrais lire sur le système de primes. :) Merci
turbopipp
C'est une bonne idée et dans certains cas vaut la peine d'essayer. Le seul inconvénient est que le * .gif est (dans mon cas) plus grand en taille de fichier. J'ai converti un 2,5 Mo * .mpeg en un 16 Mo * .gif.
Henning Fischer
Je suis d'accord, et souvent, la .giftaille est beaucoup plus grande, tout en étant plus floue. Mon point de vue a changé depuis que j'ai écrit cette réponse. C'est dommage que vous ne puissiez pas combiner le meilleur des deux.
D-Marc
J'ai fini avec un (raccourci) * .gif pour mobile et un * .mp4 pour le bureau.
Henning Fischer
1

Cette approche utilise simplement css et html. Vous pouvez en fait empiler facilement un div sous la vidéo. Il est couvert mais pas centré lors du redimensionnement.

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*/ 
}
tue le sarcasme
la source
1

@ Hobbes cachés

Cette question a une prime ouverte d'une valeur de +100 points de réputation de Hidden Hobbes se terminant dans 6 jours. Utilisation inventive des unités de fenêtre pour obtenir une solution flexible CSS uniquement.

Vous avez ouvert une prime sur cette question pour une solution CSS uniquement, je vais donc essayer. Ma solution à un problème comme celui-ci est d'utiliser un rapport fixe pour décider de la hauteur et de la largeur de la vidéo. J'utilise généralement Bootstrap, mais j'en ai extrait le CSS nécessaire pour le faire fonctionner sans. C'est un code que j'ai utilisé plus tôt pour, entre autres, centrer une vidéo intégrée avec le bon rapport. Il devrait fonctionner <video>et des <img>éléments Il est trop haut qui est pertinent, mais je vous ai donné les deux autres aussi bien que je les avais déjà autour de la pose. Bonne chance! :)

Exemple de plein écran 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&amp;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&amp;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&amp;jqoemcache=eE9xf" width="425"></iframe>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

turbopipp
la source
1
Merci pour la réponse @turbopipp même si j'ai bien peur que vous ayez mal compris la raison de ma prime. Je l'ai soulevé afin de pouvoir l'attribuer à une réponse existante, cela ne me permettra pas de le faire tant que la prime n'aura pas été active pendant 24 heures. Néanmoins, +1 pour vos efforts, l'astuce du pourcentage de remplissage est un moyen utile de garantir qu'un élément conserve le bon rapport hauteur / largeur.
Hidden Hobbes du
Aha, eh bien, ce n'était vraiment pas un problème, et vraiment gentil de votre part de donner générosité aux réponses déjà existantes. Je suppose que je devrais lire sur le système de primes. :) Merci
turbopipp
0

Pour répondre au commentaire de weotch selon lequel la réponse de Timothy Ryan Carpenter ne tient pas compte du covercentrage de l'arrière-plan, je propose cette solution CSS rapide:

CSS:

margin-left: 50%;
transform: translateX(-50%);

L'ajout de ces deux lignes centrera n'importe quel élément. Mieux encore, tous les navigateurs capables de gérer la vidéo HTML5 prennent également en charge les transformations CSS3, donc cela fonctionnera toujours.

Le CSS complet ressemble à ceci.

#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%);
}

J'aurais commenté directement la réponse de Timothy, mais je n'ai pas assez de réputation pour le faire.

Jake Z
la source
0

Les gars, j'ai une meilleure solution, c'est court et fonctionne parfaitement pour moi. Je l'ai utilisé pour la vidéo. Et il émule parfaitement l'option de couverture en 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%");
            }
    });

Si vous inversez le if, sinon vous obtiendrez contenir.

Et voici le css. (Vous n'avez pas besoin de l'utiliser si vous ne voulez pas de positionnement central, le div parent doit être " position: relative ")

CSS

video {
position: absolute;
-webkit-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
top: 50%;
left: 50%;}
user2925729
la source
0

Je viens de résoudre ce problème et je voulais partager. Cela fonctionne avec Bootstrap 4. Cela fonctionne avec imgmais je ne l'ai pas testé avec video. Voici le HAML et le 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>

Chloe
la source
0

Ancienne question, mais au cas où quelqu'un verrait cela, la meilleure réponse à mon avis est de convertir la vidéo en un GIF animé. Cela vous donne beaucoup plus de contrôle et vous pouvez simplement le traiter comme une image. C'est également le seul moyen de fonctionner sur mobile, car vous ne pouvez pas lire automatiquement les vidéos. Je sais que la question est de le faire dans une <img>balise, mais je ne vois pas vraiment l'inconvénient d'utiliser <div>et de fairebackground-size: cover

D-Marc
la source
C'est une bonne idée et dans certains cas vaut la peine d'essayer. Le seul inconvénient est que le * .gif est (dans mon cas) plus grand en taille de fichier. J'ai converti un 2,5 Mo * .mpeg en un 16 Mo * .gif.
Henning Fischer
Je suis d'accord, et souvent, la .giftaille est beaucoup plus grande, tout en étant plus floue. Mon point de vue a changé depuis que j'ai écrit cette réponse. C'est dommage que vous ne puissiez pas combiner le meilleur des deux.
D-Marc
J'ai fini avec un (raccourci) * .gif pour mobile et un * .mp4 pour le bureau.
Henning Fischer