À l'aide du modèle de boîte flexible CSS, comment puis-je forcer une image à conserver ses proportions?
JS Fiddle: http://jsfiddle.net/xLc2Le0k/2/
Notez que les images s’étirent ou se rétrécissent afin de remplir la largeur du conteneur. C'est bien, mais peut-on également réduire ou réduire la hauteur pour conserver les proportions de l'image?
HTML
<div class="slider">
<img src="http://www.placebacon.net/400/300" alt="Bacn">
<img src="http://www.placebacon.net/400/300" alt="Bacn">
<img src="http://www.placebacon.net/400/300" alt="Bacn">
<img src="http://www.placebacon.net/400/300" alt="Bacn">
</div>
CSS
.slider {
display: flex;
}
.slider img {
margin: 0 5px;
}
Pour les balises img, si vous définissez un côté, l'autre côté est redimensionné pour conserver les proportions et, par défaut, les images se développent à leur taille d'origine.
En utilisant ce fait, si vous enveloppez chaque balise img dans une balise div et définissez sa largeur à 100% de la div parent, la hauteur correspondra au rapport hauteur/largeur que vous souhaitez.
* {
margin: 0;
padding: 0;
}
.slider {
display: flex;
}
.slider .slide img {
width: 100%;
}
Pour empêcher les images de s’étirer dans l’un ou l’autre axe à l’intérieur d’un parent flexible, j'ai trouvé plusieurs solutions.
Vous pouvez essayer d’utiliser objet-fit sur l’image qui, par exemple,.
object-fit: contain;
Ou vous pouvez ajouter des règles flex-specfic qui peuvent fonctionner mieux dans certains cas.
align-self: center;
flex: 0 0 auto;
Pas besoin d'ajouter un div contenant.
La valeur par défaut de la propriété css "align-items" est "stretch", ce qui a pour effet d'étirer vos images à leur hauteur d'origine. Définir la propriété css "align-items" sur "flex-start" corrige votre problème.
.slider {
display: flex;
align-items: flex-start; /* ADD THIS! */
}
La plupart des images avec des dimensions intrinsèques , c'est-à-dire une taille naturelle, comme une image
jpeg
. Si la taille spécifiée définit à la fois la largeur et la hauteur, la valeur manquante est déterminée à l'aide du rapport intrinsèque ... - voir MDN .
Mais cela ne fonctionne pas comme prévu si les images définies en tant qu’éléments de flex direct avec l’actuel module de disposition de boîte flexible de niveau 1 , autant que je sache.
Voir ces discussions et les rapports de bugs peuvent être liés:
Pour contourner le problème, vous pouvez envelopper chaque <img>
avec un <div>
ou un <span>
, ou presque.
.slider {
display: flex;
}
.slider>div {
min-width: 0; /* why? see below. */
}
.slider>div>img {
max-width: 100%;
height: auto;
}
<div class="slider">
<div><img src="https://picsum.photos/400/300?image=0" /></div>
<div><img src="https://picsum.photos/400/300?image=1" /></div>
<div><img src="https://picsum.photos/400/300?image=2" /></div>
<div><img src="https://picsum.photos/400/300?image=3" /></div>
</div>
4.5 Taille minimale implicite des éléments Flex
Pour fournir une taille minimale par défaut plus raisonnable pour éléments flexibles , cette spécification introduit une nouvelle valeur auto en tant que valeur initiale de min-width et min-height propriétés définies dans CSS 2.1.
Alternativement, vous pouvez utiliser CSS table
layout à la place. Vous obtiendrez des résultats similaires à flexbox
, cela fonctionnera avec davantage de navigateurs, même pour IE8.
.slider {
display: table;
width: 100%;
table-layout: fixed;
border-collapse: collapse;
}
.slider>div {
display: table-cell;
vertical-align: top;
}
.slider>div>img {
max-width: 100%;
height: auto;
}
<div class="slider">
<div><img src="https://picsum.photos/400/300?image=0" /></div>
<div><img src="https://picsum.photos/400/300?image=1" /></div>
<div><img src="https://picsum.photos/400/300?image=2" /></div>
<div><img src="https://picsum.photos/400/300?image=3" /></div>
</div>
Ces derniers temps, je jouais à flexbox et j’ai trouvé une solution à ce problème grâce à l’expérimentation et au raisonnement suivant. Cependant, en réalité, je ne sais pas si c'est exactement ce qui se passe.
Si la largeur réelle est affectée par le système flex. Ainsi, après que la largeur des éléments ait atteint la largeur maximale du parent, la largeur supplémentaire définie dans css est ignorée. Ensuite, il est prudent de régler la largeur à 100%.
Étant donné que la hauteur de la balise img est dérivée de l'image elle-même, définir la hauteur sur 0% peut faire quelque chose. (c'est là que je ne sais pas trop quoi ... mais cela me semblait logique de le réparer)
(rappelez-vous vu ici d'abord!)
.slider {
display: flex;
}
.slider img {
height: 0%;
width: 100%;
margin: 0 5px;
}
Fonctionne uniquement dans chrome pour le moment
Ce comportement est attendu. Le conteneur flex étendra tous les enfants par défaut. Les images ne font pas exception. (Par exemple, le parent aura la propriété align-items: stretch
)
Pour conserver les proportions, nous avons deux solutions:
align-items: stretch
par align-items: flex-start
ou align-self: center
etc, http://jsfiddle.net/e394Lqnt/3/ou
align-self: center
ou align-self: flex-start
etc. http://jsfiddle.net/e394Lqnt/2/