Question Maintenir le ratio d'aspect d'une div avec CSS


Je veux créer un div qui peut changer sa largeur / hauteur à mesure que la largeur de la fenêtre change.

Existe-t-il des règles CSS3 permettant de changer la hauteur en fonction de la largeur, tout en conservant ses proportions?

Je sais que je peux le faire via JavaScript, mais je préférerais utiliser uniquement CSS.

div keeping aspect ratio according to width of window


796
2017-09-29 23:11


origine


Réponses:


Il suffit de créer un wrapper <div> avec une valeur en pourcentage pour padding-bottom, comme ça:

div {
  width: 100%;
  padding-bottom: 75%;
  background: gold; /** <-- For the demo **/
}
<div></div>

Il en résultera un <div> avec une hauteur égale à 75% de la largeur de son contenant (rapport d'aspect 4: 3).

Cela repose sur le fait que pour le rembourrage:

Le pourcentage est calculé par rapport à la largeur du bloc contenant la boîte générée [...] (source: w3.org, emphase sur moi)

Valeurs de remplissage-fond pour d'autres proportions et largeur de 100%:

aspect ratio  | padding-bottom value
--------------|----------------------
    16:9      |       56.25%
    4:3       |       75%
    3:2       |       66.66%
    8:5       |       62.5%

Placer du contenu dans la div:

Afin de conserver le ratio d'aspect de la div et empêcher son contenu de l'étirer, vous devez ajouter un enfant positionné de façon absolue et l'étirer sur les bords de l'enveloppe avec:

div.stretchy-wrapper {
  position: relative;
}

div.stretchy-wrapper > div {
  position: absolute;
  top: 0; bottom: 0; left: 0; right: 0;
}

Voici un démo et un autre plus en profondeur démo


1077
2018-05-04 01:19



vw unités:

Vous pouvez utiliser vw unités pour les deux largeur et hauteur de l'élément. Cela permet de conserver le format de l'élément en fonction de la largeur de la fenêtre.

vw: 1 / 100ème de la largeur de la fenêtre. [MDN]

Alternativement, vous pouvez également utiliser vh pour la hauteur de la fenêtre, ou même vmin/vmax utiliser la plus petite / plus grande des dimensions de la fenêtre (discussion ici).

Exemple: ratio d'aspect 1: 1

div {
  width: 20vw;
  height: 20vw;
  background: gold;
}
<div></div>

Pour les autres proportions, vous pouvez utiliser le tableau suivant pour calculer la valeur de hauteur en fonction de la largeur de l'élément:

aspect ratio  |  multiply width by
-----------------------------------
     1:1      |         1
     1:3      |         3
     4:3      |        0.75
    16:9      |       0.5625

Exemple: grille 4x4 de divs carrés

body {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}
div {
  width: 23vw;
  height: 23vw;
  margin: 0.5vw auto;
  background: gold;
}
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>

Voici une Fiddle avec cette démo et voici une solution pour faire un grille sensible de carrés avec contenu verticalement et horizontalement centré.


Le support du navigateur pour les unités vh / vw est IE9 + voir canIuse pour plus d'informations


327
2018-05-15 08:48



J'ai trouvé un moyen de le faire en utilisant CSS, mais vous devez être prudent car cela peut changer en fonction du flux de votre propre site web. Je l'ai fait afin d'intégrer la vidéo avec un rapport d'aspect constant dans une partie de la largeur du fluide de mon site Web.

Supposons que vous avez une vidéo intégrée comme celle-ci:

<object>
     <param ... /><param ... />...
     <embed src="..." ...</embed>
</object>

Vous pouvez ensuite placer tout cela dans une div avec une classe "vidéo". Cette classe vidéo sera probablement l'élément fluide de votre site web, de sorte que, par elle-même, il n'y a pas de contraintes de hauteur directes, mais lorsque vous redimensionnez le navigateur, sa largeur varie en fonction du flux du site web. Ce serait l'élément que vous essayez probablement d'obtenir votre vidéo intégrée tout en conservant un certain ratio d'aspect de la vidéo.

Pour ce faire, j'ai mis une image avant l'objet incorporé dans la classe "video" div.

!!! La partie importante est que l'image a le ratio d'aspect correct que vous souhaitez maintenir. Aussi, assurez-vous que la taille de l'image est au moins aussi grande que la plus petite que vous attendez de la vidéo (ou de tout ce que vous maintenez le A.R. de) pour obtenir en fonction de votre mise en page. Cela évitera tout problème potentiel dans la résolution de l'image lors d'un redimensionnement en pourcentage. Par exemple, si vous souhaitez conserver un rapport d'aspect de 3: 2, n'utilisez pas uniquement une image 3px par 2px. Cela peut fonctionner dans certaines circonstances, mais je ne l'ai pas testé, et ce serait probablement une bonne idée à éviter.

Vous devriez probablement déjà avoir une largeur minimale comme celle-ci définie pour les éléments fluides de votre site Web. Si ce n'est pas le cas, c'est une bonne idée de le faire afin d'éviter de couper des éléments ou de se chevaucher lorsque la fenêtre du navigateur devient trop petite. Il est préférable d'avoir une barre de défilement à un moment donné. La plus petite largeur qu'une page Web devrait obtenir est quelque part autour de ~ 600px (y compris les colonnes de largeur fixe) parce que les résolutions d'écran ne sont pas plus petites, sauf si vous avez affaire à des sites favorables au téléphone. !!!

J'utilise un png complètement transparent mais je ne pense pas vraiment que cela finisse par être important si vous le faites correctement. Comme ça:

<div class="video">
     <img class="maintainaspectratio" src="maintainaspectratio.png" />
     <object>
          <param ... /><param ... />...
          <embed src="..." ...</embed>
     </object>
</div>

Vous devriez maintenant être en mesure d'ajouter CSS de la manière suivante:

div.video { ...; position: relative; }
div.video img.maintainaspectratio { width: 100%; }
div.video object { position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; }
div.video embed {width: 100%; height: 100%; }

Veillez également à supprimer toute déclaration de hauteur ou de largeur explicite dans l'objet et les balises d'intégration généralement accompagnées du code d'intégration copier / coller.

La façon dont cela fonctionne dépend des propriétés de position de l'élément de classe vidéo et l'élément que vous souhaitez conserver un certain ratio d'aspect. Il profite de la façon dont une image conservera son bon format lorsqu'elle est redimensionnée dans un élément. Il indique tout ce qui est dans l'élément de classe vidéo pour tirer pleinement parti de l'image fournie par l'image dynamique en forçant sa largeur / hauteur à 100% de l'élément de classe vidéo ajusté par l'image.

Assez cool, hein?

Vous devrez peut-être jouer avec un peu pour le faire fonctionner avec votre propre design, mais cela fonctionne étonnamment bien pour moi. Le concept général est là.


25
2017-12-22 02:08



Pour ajouter à la réponse de Web_Designer, le <div> aura une hauteur (entièrement composée de rembourrage inférieur) de 75% de la largeur de son élément contenant. Voici un bon résumé: http://mattsnider.com/css-using-percent-for-margin-and-padding/. Je ne sais pas pourquoi cela devrait être ainsi, mais c'est comme ça.

Si vous voulez que votre div soit d'une largeur autre que 100%, vous avez besoin d'un autre div sur lequel vous pouvez définir la largeur:

div.ar-outer{
    width: 60%; /* container; whatever width you want */
    margin: 0 auto; /* centered if you like */
}
div.ar {
    width:100%; /* 100% of width of container */
    padding-bottom: 75%; /* 75% of width of container */
    position:relative;
}
div.ar-inner {
    position: absolute;
    top: 0; bottom: 0; left: 0; right: 0;
}

J'ai utilisé quelque chose de similaire à l'astuce de l'image d'Elliot récemment pour me permettre d'utiliser des requêtes de médias CSS pour servir un fichier de logo différent en fonction de la résolution de l'appareil, mais toujours proportionnellement comme un <img> ferait naturellement (je place le logo comme image de fond à un .png transparent avec le rapport d'aspect correct). Mais la solution de Web_Designer me permettrait d'économiser une requête http.


13
2018-05-06 17:35



Elliot m'a inspiré à cette solution - merci:

aspectratio.png est un fichier PNG complètement transparent avec la taille de votre rapport d'aspect préféré, dans mon cas 30x10 pixels.

HTML

<div class="eyecatcher">
  <img src="/img/aspectratio.png"/>
</div>

CSS3

.eyecatcher img {
  width: 100%;
  background-repeat: no-repeat;
  background-size: 100% 100%;
  background-image: url(../img/autoresized-picture.jpg);
}

Notez s'il vous plaît:  background-size est une fonctionnalité css3 qui peut ne pas fonctionner avec vos navigateurs cibles. Vous pouvez vérifier l'interopérabilité (f.e. caniuse.com).


13
2017-07-07 14:25



Comme indiqué dans ici sur w3schools.com et un peu réitéré dans ce réponse acceptée, remplissage des valeurs en pourcentages (emphase mienne):

Spécifie le remplissage en pourcentage de la largeur du élément contenant

Ergo, un exemple correct d'un DIV réactif qui conserve un rapport d'aspect 16: 9 est la suivante:

CSS

.parent {
    position: relative;
    width: 100%;
}
.child {
    position: relative;
    padding-bottom: calc(100% * 9 / 16);
}
.child > div {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
}

HTML

<div class="parent">
    <div class="child">
        <div>Aspect is kept when resizing</div>
    </div>
</div>

Démo sur JSFiddle


9
2018-03-22 12:18



En me basant sur vos solutions, j'ai fait quelques trucs:

Quand vous l'utiliserez, votre HTML sera seulement

<div data-keep-ratio="75%">
    <div>Main content</div>
</div>

Pour l'utiliser de cette façon, faites: CSS:

*[data-keep-ratio] {
    display: block;
    width: 100%;
    position: relative;
}
*[data-keep-ratio] > * {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
}

et js (jQuery)

$('*[data-keep-ratio]').each(function(){ 
    var ratio = $(this).data('keep-ratio');
    $(this).css('padding-bottom', ratio);
});

Et ayant cela, vous venez de définir attr data-keep-ratio à hauteur / largeur et c'est tout.


9
2017-12-05 21:13



Vous pouvez utiliser un svg. Faire la position du conteneur / wrapper relative, placer le svg d'abord comme positionné statiquement puis placer le contenu absolument positionné (haut: 0, gauche: 0, droite: 0, bas: 0;)

Exemple avec des proportions 16: 9:

image.svg: (peut être inline dans src)

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 9" width="16" height="9"/>

CSS:

.container {
  position: relative;
}
.content {
  position: absolute;
  top:0; left:0; right:0; bottom:0;
}

HTML:

<div class="container">
  <img style="width: 100%" src="image.svg" />
  <div class="content"></div>
</div>

Notez que svg inline ne semble pas fonctionner, mais vous pouvez urlencode le svg et l'incorporer dans l'attribut img src comme ceci:

<img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2016%209%22%20width%3D%2216%22%20height%3D%229%22%2F%3E" style="width: 100%;" />

6
2017-10-05 05:26



Comme @ web-tiki montre déjà un moyen d'utiliser vh/vw, J'ai aussi besoin d'un moyen de centrer dans l'écran, voici un code d'extrait pour 9h16 portrait.

.container {
  width: 100vw;
  height: calc(100vw * 16 / 9);
  transform: translateY(calc((100vw * 16 / 9 - 100vh) / -2));
}

translateY gardera ce centre dans l'écran. calc(100vw * 16 / 9) est prévu hauteur pour 9/16.(100vw * 16 / 9 - 100vh) est la hauteur de débordement, alors, tirez overflow height/2 le gardera au centre sur l'écran.

Pour le paysage, et gardez 16: 9, vous montrez l'utilisation

.container {
  width: 100vw;
  height: calc(100vw * 9 / 16);
  transform: translateY(calc((100vw * 9 / 16 - 100vh) / -2));
}

Le ratio 9/16 est la facilité de changement, pas besoin de prédéfinir 100:56.25 ou 100:75.Si vous voulez d'abord assurer la hauteur, vous devez changer la largeur et la hauteur, par ex. height:100vh;width: calc(100vh * 9 / 16) pour le portrait de 9h16.

Si vous voulez adapter pour la taille d'écran différente, vous pouvez également intéresser

  • taille de fond couvrir / contenir
    • Le style ci-dessus est similaire à contenir, dépend du rapport largeur: hauteur.
  • objet-fit
    • cover / contient pour img / video tag
  • @media (orientation: portrait)/@media (orientation: landscape)
    • Requête média pour portrait/landscape pour changer le rapport.

4
2017-11-01 02:40



SCSS est la meilleure solution dans mon cas; en utilisant un attribut de données:

[data-aspect-ratio] {
    display: block;
    max-width: 100%;
    position: relative;

    &:before {
        content: '';
        display: block;
    }

    > * {
        display: block;
        height: 100%;
        left: 0;
        position: absolute;
        top: 0;
        width: 100%;
    }
}
[data-aspect-ratio="3:1"]:before {
    padding-top: 33.33%;
}
[data-aspect-ratio="2:1"]:before {
    padding-top: 50%;
}
[data-aspect-ratio="16:9"]:before {
    padding-top: 56.25%;
}
[data-aspect-ratio="3:2"]:before {
    padding-top: 66.66%;
}
[data-aspect-ratio="4:3"]:before {
    padding-top: 75%;
}
[data-aspect-ratio="1:1"]:before {
    padding-top: 100%;
}
[data-aspect-ratio="3:4"]:before {
    padding-top: 133.33%;
}
[data-aspect-ratio="2:3"]:before {
    padding-top: 150%;
}
[data-aspect-ratio="9:16"]:before {
    padding-top: 177.77%;
}
[data-aspect-ratio="1:2"]:before {
    padding-top: 200%;
}
[data-aspect-ratio="1:3"]:before {
    padding-top: 300%;
}

Par exemple :

<div data-aspect-ratio="16:9"><iframe ...></iframe></div>

la source


3
2017-10-23 11:18