CSS: rendre la largeur de div proportionnelle à la hauteur

c'est un peu difficile à expliquer, mais: je veux un div responsive-height (height: 100%) qui va mettre à l'échelle le largeur proportionnel à la hauteur (pas l'inverse).

je sais cette méthode utiliser un padding-top hack pour prendre de la hauteur proportionnelle à la largeur, mais j'en ai besoin pour travailler dans l'autre sens. Cela étant dit, Je ne suis pas très favorable à l'exigence supplémentaire d'éléments absolument positionnés pour le contenu dans ce méthode, donc je me rends compte que je demande peut-être la Lune sur un bâton ici.

pour aider à visualiser, voici une image:

Visual representation of desired effect

...et voici un jsFiddle<!--12, ce qui illustre à peu près la même chose.

Il est intéressant de noter que je suis déjà à l'aide de la :before et :after pseudo-éléments pour aligner verticalement le contenu de la boîte que je veux dimensionner proportionnellement.

j'aimerais vraiment, vraiment ne pas aimer devoir revenir à jQuery, juste parce qu'il va y avoir une exigence inhérente pour redimensionner les gestionnaires et généralement plus de débogage tout autour... mais si c'est mon seul choix, puis fiat.

28
demandé sur indextwo 2014-03-27 01:04:14

6 réponses

je me pose la question d'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 la démo complète et l'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
}
12
répondu Patrick Kunka 2014-08-23 22:55:12
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 rembourrage vertical dans CSS est lié à la largeur de l'élément, pas à la hauteur.

12
répondu feeela 2014-03-26 21:12:00

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

L'astuce que j'utilise est d'avoir une image utilisée comme une 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 la plus jolie avec deux divs supplémentaires et une image inutile. Mais ça pourrait être pire. L'élément image doit avoir la largeur et la hauteur avec les dimensions désirées. La largeur et la hauteur doivent être aussi grands que la taille maximale autorisée (une fonctionnalité!).

Le css:

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

cet élément est pour limiter la hauteur, mais pour s'étendre horizontalement (width: auto) mais jamais au-delà du parent (max-width). Le débordement doit être caché parce que certains enfants feront saillie à l'extérieur de la div.

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

cette image est invisible et graduée proportionnellement à la hauteur, alors que la largeur est ajustée et force la largeur du parent à aussi être ajusté.

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

Cet élément est nécessaire pour remplir l'espace avec un positionnement absolu conteneur.

.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 du bas 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 y a un piratage qui peut être appliqué pour résoudre cela, comme indiqué dans ma démonstration.

6
répondu Johan Rönnblom 2016-03-06 18:55:58

basé sur la réponse de @kunkalabs (ce qui est vraiment intelligent) j'ai trouvé une solution qui vous permet de préserver la taille de police héritée.

HTML:

<div id='rect'>
    <div id='content'>Text</div>
</div>

CSS:

#rect {
    font-size: 1000%;
    height: 1em;
    width: 1em;
    position: relative;
}

#content {
    font-size: 10%;
}

Donc en gros, la taille de police #content (100 / $rectFontSize) * 100% du rectangle. Si vous avez besoin d'une taille de pixel définie pour le rectangle, vous pouvez définir le #rectfait la taille de police du parent...sinon ajustez la taille de police jusqu'à ce que ce soit à peu près où vous voulez qu'elle soit. (et enrager votre concepteur dans le processus).

1
répondu hobberwickey 2015-07-24 02:33:10

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

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

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

0
répondu Erwan 2018-10-01 15:03:52

faites que le DIV parent se comporte comme une cellule de table et alignez l'élément enfant verticalement. Pas besoin de faire des trucs de rembourrage.

HTML

<div class="parent">
<img src="foo.jpg" />
</div>

CSS

.parent { width:300px; height:300px; display:table-cell; vertical-align:middle; }
-2
répondu Eric Windmeier 2015-05-22 10:55:20