web-dev-qa-db-fra.com

Maintenir le rapport d'aspect div en fonction de la hauteur

J'ai besoin de maintenir la largeur d'un élément en pourcentage de sa hauteur. Ainsi, à mesure que la hauteur change, la largeur est mise à jour.

L'inverse est réalisable en utilisant une valeur% pour padding-top, mais padding-left en pourcentage sera un pourcentage de la largeur d'un objet, pas sa hauteur.

Donc, avec un balisage comme celui-ci:

<div class="box">
  <div class="inner"></div>
</div>

Je voudrais utiliser quelque chose comme ça:

.box {
    position: absolute;
    margin-top: 50%;
    bottom: 0;
}
.inner {
    padding-left: 200%;
}

Pour garantir la boîte le rapport d'aspect est maintenu en fonction de sa hauteur. La hauteur est fluide à cause de son% de marge - à mesure que la hauteur de la fenêtre change, la hauteur de la boîte aussi.

Je sais comment y parvenir avec JavaScript, je me demande simplement s'il existe une solution propre à CSS uniquement?

28
Fijjit

Vous pouvez utiliser une image qui a les proportions souhaitées pour faciliter le dimensionnement proportionnel (les images peuvent être mises à l'échelle proportionnellement en définissant une dimension sur une certaine valeur et l'autre sur auto). L'image n'a pas besoin d'être visible, mais elle doit occuper de l'espace.

.box {
  position: absolute;
  bottom: 0;
  left: 0;
  height: 50%;
}
.size-helper {
  display: block;
  width: auto;
  height: 100%;
}
.inner {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background: rgba(255, 255, 153, .8);
}
<div class="box">
  <img class="size-helper" src="//dummyimage.com/200x100/999/000" width="200" height="100">
  <div class="inner">
    1. box has fluid height<br>
    2. img has 2:1 aspect ratio, 100% height, auto width, static position<br>
    2.1 it thus maintains width = 200% of height<br>
    2.2 it defines the dimensions of the box<br>
    3. inner expands as much as box
  </div>
</div>

Dans l'exemple ci-dessus, box, inner et helper sont tous de même taille.

24
Salman A

Vous pouvez utiliser des unités vh pour la hauteur et la largeur de votre élément afin qu'elles changent en fonction de la hauteur de la fenêtre d'affichage .

vh 1/100e de la hauteur de la fenêtre. ( MDN )

DÉMO

.box {
    position: absolute;
    height:50vh;
    width:100vh;
    bottom: 0;
    background:teal;
}
<div class="box"></div>
15
web-tiki

L'astuce CSS que vous avez écrite fonctionne assez bien pour garder le ratio width/height sur un élément. Il est basé sur la propriété padding qui, lorsque sa valeur est en pourcentage, est proportionnelle à la largeur du parent, même pour padding-top et padding-bottom.

Aucune propriété CSS ne peut définir un dimensionnement horizontal proportionnellement à la hauteur du parent. Je pense donc qu'il n'y a pas de solution CSS propre.

5
tzi

Il existe un autre moyen plus efficace d'obtenir un rapport hauteur/largeur constant en fonction de la hauteur.

Vous pouvez placer un svg vide afin de ne pas avoir à charger une image externe.

Code HTML:

    <svg xmlns="http://www.w3.org/2000/svg"
      height="100"
      width="200"
      class='placeholder-svg'
    />

Code CSS:

.placeholder-svg {
  width: auto;
  height: 100%;
}

Modifiez la largeur/hauteur pour obtenir le rapport hauteur/largeur souhaité.

Gardez à l'esprit que le svg peut déborder.

http://www.w3.org/2000/svg n'est qu'un espace de noms. Il ne charge rien.

Si vous changez placeholder-svg classe à:

.placeholder-svg {
  width: 100%;
  height: auto;
}

puis la hauteur est ajustée en fonction de la largeur.

Démo 1 La largeur est ajustée en fonction de la hauteur et du format 2: 1.

Démo 2 idem que ci-dessus, mais vous pouvez redimensionner facilement (utilise React)

1
Daniel

Je ne trouve pas de solution CSS pure. Voici une solution utilisant CSS Element Queries bibliothèque JavaScript.

var aspectRatio = 16/9;
var element = document.querySelector('.center');
function update() {
  element.style.width = (element.clientHeight * aspectRatio) + 'px';
}

new ResizeSensor(element, update);
update();

Démo CodePen!

0
Neal Ehardt