web-dev-qa-db-fra.com

CSS: rendre la largeur div proportionnelle à la hauteur

C'est un peu difficile à expliquer, mais: je veux un div responsive-height (height: 100%) qui mettra à l'échelle la largeur proportionnelle à la hauteur (pas vice versa).

Je connais cette méthode utilisant un padding-top pirater pour rendre la hauteur proportionnelle à la largeur, mais j'en ai besoin pour travailler dans l'autre sens. Cela dit, je ne suis pas très intéressé par l'exigence supplémentaire d'éléments absolument positionnés pour le contenu de cette méthode, alors je me rends compte que je peux très bien demander la lune sur un bâton ici.

Pour aider à visualiser, voici une image:

Visual representation of desired effect

... et voici un jsFiddle , illustrant à peu près la même chose.

Il convient de noter que j'utilise déjà le :before et :after pseudo-éléments pour aligner verticalement le contenu de la boîte que je souhaite mettre à l'échelle proportionnellement.

J'aimerais vraiment, vraiment ne pas avoir à revenir à jQuery, juste parce qu'il y aura une exigence inhérente pour les gestionnaires de redimensionnement et généralement plus de débogage tout au long ... mais si c'est mon seul choix, alors fiat.

30
indextwo

Je me pose des questions sur une solution pure-css à ce problème depuis un certain temps. J'ai finalement trouvé une solution utilisant ems, qui peut être progressivement améliorée en utilisant vws:

Voir le lien codepen pour une démonstration complète et une explication:

http://codepen.io/patrickkunka/pen/yxugb

Version simplifiée:

.parent {
  font-size: 250px; // height of container
  height: 1em;
}

.child {
  height: 100%;
  width: 1em; // 100% of height
}
13
Patrick Kunka

Oh, vous pourriez probablement utiliser cette astuce "padding-top".

width: 50%;
height: 0;
padding-bottom: 50%;

http://absolide.tumblr.com/post/7317210512/full-css-fluid-squares

Ou:

.square-box{
    position: relative;
    width: 50%;
    overflow: hidden;
    background: #4679BD;
}
.square-box:before{
    content: "";
    display: block;
    padding-top: 100%;
}

http://codeitdown.com/css-square-rectangle/

Le remplissage vertical en CSS est lié à la largeur de l'élément, pas à la hauteur.

13
feeela

La solution de police nécessite que la hauteur soit connue. J'ai trouvé une solution pour rendre un élément proportionnel à l'intérieur d'un div parent avec des largeurs et des hauteurs inconnues. Voici une démo .

L'astuce que j'utilise est d'avoir une image utilisée comme entretoise. Le code explique:

<div class="heightLimit">
 <img width="2048" height="2048" class="spacer"
  src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAA
       P///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">
 <div class="filler">
  <div class="proportional">
  </div>
 </div>
</div>

Ce n'est donc pas le plus joli avec deux div supplémentaires et une image inutile. Mais cela pourrait être pire. L'élément d'image doit avoir une largeur et une hauteur aux dimensions souhaitées. La largeur et la hauteur doivent être aussi grandes que la taille maximale autorisée (une caractéristique!).

Le css:

.heightLimit {
 position: absolute;
 top: 0;
 left: 0;
 height: 100%;
 width: auto;
 max-width: 100%;
 overflow: hidden;
}

Cet élément consiste à limiter la hauteur, mais à l'agrandir horizontalement (width: auto) mais jamais au-delà du parent (max-width). Le débordement doit être caché car certains enfants dépassent du div.

.spacer {
 width: auto;
 max-height: 100%;
 visibility: hidden;
}

Cette image est invisible et mise à l'échelle proportionnellement à la hauteur, tandis que la largeur est ajustée et force la largeur du parent à être également ajustée.

.filler {
 position: absolute;
 top: 0;
 left: 0;
 bottom: 0;
 right: 0;
}

Cet élément est nécessaire pour remplir l'espace avec un conteneur absolument positionné.

.proportional {
 position: relative;
 width: 100%;
 height: 0;
 padding-bottom: 100%;
}

Et ici, notre élément proportionnel obtient une hauteur proportionnelle à la largeur avec l'astuce familière de rembourrage.

Malheureusement, il y a un bug dans Chrome et IE donc si vous modifiez l'élément parent en utilisant Javascript, comme dans ma démo, les dimensions ne seront pas mises à jour) Il existe un hack qui peut être appliqué pour résoudre ce problème, comme indiqué dans ma démo.

6
Johan Rönnblom

Vous pouvez utiliser la hauteur de vue (vh) comme unité pour la largeur .

Voici un exemple avec la marge 20px que vous avez demandée.

 .parent {
   margin : 20px;
}
.child {
   width: calc(100vh - 40px);
   height : calc(100vh - 40px);
   margin:0 auto;
   background: red;
   box-sizing:border-box;
   padding:10px;
}

Voir le violon: https://jsfiddle.net/svobczp4/

1
Erwan