147 votes

Aligner verticalement une image à l'intérieur d'un div avec une hauteur réactive

J'ai le code suivant qui configure un conteneur dont la hauteur change avec la largeur lorsque le navigateur est redimensionné (pour maintenir un rapport d'aspect carré).

HTML

<div class="responsive-container">
    <div class="dummy"></div>
    <div class="img-container">
        <IMG HERE>
    </div>
</div>

CSS

.responsive-container {
    position: relative;
    width: 100%;
    border: 1px solid black;
}

.dummy {
    padding-top: 100%; /* forces 1:1 aspect ratio */
}

.img-container {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
}

Comment aligner verticalement l'IMG à l'intérieur du conteneur ? Toutes mes images ont des hauteurs variables et le conteneur ne peut pas avoir une hauteur/une hauteur de ligne fixe parce qu'il est réactif... Aidez-moi !

394voto

Hashem Qolami Points 22990

Voici une technique permettant d'aligner les éléments en ligne à l'intérieur d'un fichier de type parent horizontalement et verticalement en même temps :

Alignement vertical

1) Dans cette approche, nous créons un inline-block en tant que premier (ou dernier) enfant du (pseudo-)élément parent et définir son height à la propriété 100% pour prendre toute la hauteur de son parent .

2) En outre, l'ajout de vertical-align: middle maintient les éléments inline(-block) au milieu de l'interligne. Nous ajoutons donc cette déclaration CSS à l'élément premier enfant y notre élément (le image ) les deux.

3) Enfin, afin de supprimer le caractère d'espace blanc entre en ligne(-block) nous pourrions définir la taille de la police de l'élément parent à zéro par font-size: 0; .

Note : J'ai utilisé le livre de Nicolas Gallagher technique de remplacement d'image dans ce qui suit.

Quels sont les avantages ?

  • Le conteneur ( parent ) peuvent avoir des dimensions dynamiques.

  • Il n'est pas nécessaire de spécifier explicitement les dimensions de l'élément image.

  • Nous pouvons facilement utiliser cette approche pour aligner un <div> élément verticalement qui peuvent avoir un contenu dynamique (hauteur et/ou largeur). Mais notez que vous devez redéfinir l'attribut font-size de l div pour afficher le texte intérieur. Démonstration en ligne .

    <div class="container"> <div id="element"> ... </div> </div>

    .container { height: 300px; text-align: center; / align the inline(-block) elements horizontally / font: 0/0 a; / remove the gap between inline(-block) elements / }

    .container:before { / create a full-height inline block pseudo=element / content: ' '; display: inline-block; vertical-align: middle; / vertical alignment of the inline element / height: 100%; }

    element {

    display: inline-block;
    vertical-align: middle;  /* vertical alignment of the inline element */
    font: 16px/1 Arial sans-serif;        /* <-- reset the font property */

    }

Le résultat

Vertically align an element in its container

Conteneur réactif

Cette section ne va pas répondre à la question car le PO sait déjà comment créer un conteneur réactif. Cependant, je vais expliquer comment cela fonctionne.

Afin de rendre le hauteur d'un élément conteneur change avec son largeur (en respectant le rapport d'aspect), nous pourrions utiliser une valeur en pourcentage pour le haut/bas padding propriété.

A valeur du pourcentage sur le rembourrage ou les marges en haut/bas est relatif à la largeur du bloc contenant.

Par exemple :

.responsive-container {
  width: 60%;

  padding-top: 60%;    /* 1:1 Height is the same as the width */
  padding-top: 100%;   /* width:height = 60:100 or 3:5        */
  padding-top: 45%;    /* = 60% * 3/4 , width:height =  4:3   */
  padding-top: 33.75%; /* = 60% * 9/16, width:height = 16:9   */
}

Voici le Démonstration en ligne . Commentez les lignes du bas et redimensionnez le panneau pour voir l'effet.

De même, nous pourrions appliquer le padding à une propriété factice l'enfant ou :before / :after pour obtenir le même résultat. Mais note que dans ce cas, la valeur du pourcentage sur padding est relative à la largeur de la .responsive-container lui-même.

<div class="responsive-container">
  <div class="dummy"></div>
</div>

.responsive-container { width: 60%; }

.responsive-container .dummy {
  padding-top: 100%;    /*  1:1 square */
  padding-top: 75%;     /*  w:h =  4:3 */
  padding-top: 56.25%;  /*  w:h = 16:9 */
}

Démo n°1 .
Démo n°2 (En utilisant :after pseudo-élément)

Ajout du contenu

Utilisation de padding-top propriété provoque un espace énorme en haut ou en bas du contenu, à l'intérieur de l'élément conteneur .

Pour résoudre ce problème, nous devons envelopper le contenu par un élément d'enveloppement, supprimer cet élément du flux normal du document en utilisant la commande positionnement absolu et, enfin, développer le wrapper (en utilisant top , right , bottom y left ) pour remplir tout l'espace de son parent, le conteneur .

C'est parti :

.responsive-container {
  width: 60%;
  position: relative;
}

.responsive-container .wrapper {
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
}

Voici le Démonstration en ligne .


Se retrouver tous ensemble

<div class="responsive-container">
  <div class="dummy"></div>

  <div class="img-container">
    <img src="http://placehold.it/150x150" alt="">
  </div>
</div>

.img-container {
  text-align:center; /* Align center inline elements */
  font: 0/0 a;       /* Hide the characters like spaces */
}

.img-container:before {
  content: ' ';
  display: inline-block;
  vertical-align: middle;
  height: 100%;
}

.img-container img {
  vertical-align: middle;
  display: inline-block;
}

Voici le DÉMO DE TRAVAIL .

Évidemment, vous pourriez éviter d'utiliser ::before pseudo-élément pour compatibilité des navigateurs et créez un élément comme premier enfant de l'élément .img-container :

<div class="img-container">
    <div class="centerer"></div>
    <img src="http://placehold.it/150x150" alt="">
</div>

.img-container .centerer {
  display: inline-block;
  vertical-align: middle;
  height: 100%;
}

DEMO MISE À JOUR .

Utilisation de max-* propriétés

Afin de conserver l'image à l'intérieur de la boîte dans une largeur plus faible, vous pouvez définir les paramètres suivants max-height y max-width sur l'image :

.img-container img {
    vertical-align: middle;
    display: inline-block;
    max-height: 100%;  /* <-- Set maximum height to 100% of its parent */
    max-width: 100%;   /* <-- Set maximum width to 100% of its parent */
}

Voici le DEMO MISE À JOUR .

50voto

Danield Points 17720

Avec flexbox, c'est facile :

FIDDLE

Il suffit d'ajouter les éléments suivants au conteneur d'images :

.img-container {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    display: flex; /* add */
    justify-content: center; /* add to align horizontal */
    align-items: center; /* add to align vertical */
}

16voto

Tibos Points 12774

Utilisez cette css, car vous avez déjà le balisage pour elle :

.img-container {
    position: absolute;
    top: 50%;
    left: 50%;
}

.img-container > img {
  margin-top:-50%;
  margin-left:-50%;  
}

Voici un JsBin fonctionnel : http://jsbin.com/ihilUnI/1/edit

Cette solution ne fonctionne que pour les images carrées (parce qu'un pourcentage de la valeur margin-top dépend de la largeur du conteneur, et non de sa hauteur). Pour les images de taille aléatoire, vous pouvez procéder comme suit :

.img-container {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%); /* add browser-prefixes */
}

Solution JsBin fonctionnelle : http://jsbin.com/ihilUnI/2/edit

12voto

Salman A Points 60620

Dans les navigateurs modernes, vous pouvez utiliser margin: auto avec une position absolue. Vous pouvez vous débarrasser de la div supplémentaire :

<div class="responsive-container">
    <div class="dummy"></div>
    <img src="http://placehold.it/350x150" width="350" height="150" />
</div>

.responsive-container {
    position: relative;
}
.dummy {
    padding-top: 100%;
}
.responsive-container img {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
}

Code , Démo

4voto

Essayez celui-ci

  .responsive-container{
          display:table;
  }
  .img-container{
          display:table-cell;
          vertical-align: middle;
   }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X