Une image dans un flexbox qui a un max-height
le style semble s'afficher différemment selon que ses attributs height
et width
sont définis.
Celui avec les attributs, définis sur la largeur/hauteur réelle de l'image, est rendu avec son rapport d'aspect préservé, mais ceux sans les attributs respectent la max-height
et apparaissent écrasés.
.flex-parent {
display: flex;
max-height: 10vh;
}
<div class="flex-parent">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/be/Red_eyed_tree_frog_edit2.jpg/320px-Red_eyed_tree_frog_edit2.jpg">
<img width="320" height="240" src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/be/Red_eyed_tree_frog_edit2.jpg/320px-Red_eyed_tree_frog_edit2.jpg">
</div>
Voici comment cela apparaît dans Chrome 58 (et il apparaît de la même manière dans Firefox 54).
Pourquoi rendent-ils différemment? Quelles sont les règles qui régissent ce comportement?
Ma compréhension (manifestement incorrecte) est que les attributs de hauteur et de largeur remplacent la hauteur et la largeur intrinsèques trouvées lors du chargement de l'image, et si les attributs de hauteur et de largeur sont égaux aux dimensions de l'image, il ne devrait pas y avoir de différence de rendu une fois l'image a chargé.
Le contexte crée une page avec des images réactives, où chaque image
vh
dans le CSS)L'image de la grenouille provient de https://en.wikipedia.org/wiki/File:Red_eyed_tree_frog_edit2.jpg
Un paramètre initial d'un conteneur flexible est align-items: stretch
.
Cela signifie que les éléments flexibles se développeront à travers axe transversal du conteneur.
Dans un conteneur de direction de ligne, comme dans la question, l'axe transversal est vertical.
Cela signifie que les articles (images, dans ce cas) couvriront toute la hauteur du conteneur.
Cependant, lorsqu'un élément flexible a une taille croisée définie, cela remplace la valeur par défaut stretch
.
D'après les spécifications:
8.3. Alignement transversal: le
align-items
etalign-self
propriétésLes éléments flexibles peuvent être alignés dans l'axe transversal de la ligne actuelle du conteneur flexible, comme
justify-content
mais dans la direction perpendiculaire.
stretch
Si la propriété de taille croisée de l'élément flexible est calculée sur
auto
et qu'aucune des marges de l'axe transversal n'estauto
, l'élément flexible est étiré.
C'est le langage clé:
Si la propriété de taille croisée de l'élément flexible se calcule en
auto
Et voici comment la spécification définit la "propriété de taille croisée":
La largeur ou la hauteur d'un élément flexible, quelle que soit sa dimension croisée, correspond à la taille de la croix de l'élément. La propriété cross size est celle de
width
ouheight
qui est dans la dimension croisée.
Ainsi, votre code semble se jouer comme défini dans la spécification.
Voici ce que vous avez:
.flex-parent {
display: flex;
max-height: 10vh;
}
<div class="flex-parent">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/be/Red_eyed_tree_frog_edit2.jpg/320px-Red_eyed_tree_frog_edit2.jpg">
<img width="320" height="240" src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/be/Red_eyed_tree_frog_edit2.jpg/320px-Red_eyed_tree_frog_edit2.jpg">
</div>
La première image n'a pas de largeur définie (taille principale) ou de hauteur (taille croisée), ni en CSS ni en HTML. Par conséquent, sa taille croisée est calculée en auto
.
Cette déclaration:
Si la propriété de taille croisée de l'élément flexible se calcule en
auto
... est vrai, et align-items: stretch
entre en vigueur.
L'image s'étend sur toute la hauteur du conteneur, qui est de 10 pixels.
La deuxième image a cependant un dimensionnement explicite. La taille croisée est définie dans le code HTML (height="240"
).
Maintenant, cette déclaration:
Si la propriété de taille croisée de l'élément flexible se calcule en
auto
... est faux, et align-items: stretch
est remplacé. L'attribut HTML height
prévaut.
Deux notes sur la deuxième image:
max-height
limite sur le conteneur car un paramètre initial en CSS est overflow: visible
.width
et height
correspondent à leurs propriétés CSS respectives. Par conséquent, height="240"
remplace le height: auto
défaut. Voir ci-dessous pour les références de spécifications. *Il y a deux autres problèmes à prendre en compte lors du rendu d'images dans un conteneur flexible.
Taille minimale par défaut des éléments flexibles. Ce paramètre empêche les éléments flexibles de rétrécir en dessous de la taille de leur contenu. Lisez cet article pour plus de détails:
Comportement variable parmi les principaux navigateurs. Firefox, Chrome, Safari, Edge et IE11 ne rendent pas toujours les images en tant qu'éléments flex de la même manière. Lisez cet article pour plus de détails:
Compte tenu de tous les facteurs ci-dessus, voici ma solution suggérée:
.flex-parent {
display: flex;
max-height: 50vh; /* adjusted for demo */
}
.flex-parent {
min-width: 0;
}
img {
width: 100%;
height: auto;
}
<div class="flex-parent">
<div>
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/be/Red_eyed_tree_frog_edit2.jpg/320px-Red_eyed_tree_frog_edit2.jpg">
</div>
<div>
<img width="320" height="240" src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/be/Red_eyed_tree_frog_edit2.jpg/320px-Red_eyed_tree_frog_edit2.jpg">
</div>
</div>
* Les attributs HTML width
et height
correspondent à leurs propriétés CSS respectives. Par conséquent, lorsqu'ils sont spécifiés, ils remplacent les valeurs par défaut CSS. De la spécification HTML5:
10.4.3 Attributs pour le contenu et les images intégrés
Les attributs
width
etheight
surapplet
,embed
,iframe
,object
ouvideo
éléments, etinput
éléments avec un attributtype
dans l'état du bouton Image et qui soit représente une image, soit que l'utilisateur attend éventuellement représentera une image, mapper aux propriétés de dimensionwidth
etheight
sur l'élément respectivement.10.2 La feuille de style de l'agent utilisateur CSS et les conseils de présentation
Lorsque le texte ci-dessous indique qu'un attribut sur un élément correspond à la propriété de dimension (ou aux propriétés), cela signifie que si l'élément a un ensemble d'attributs, et l'analyse de la valeur de cet attribut à l'aide de règles pour l'analyse des valeurs de dimension ne génère pas d'erreur, alors l'agent utilisateur devrait utiliser la dimension analysée comme valeur pour un indice de présentation = pour les propriétés, avec la valeur donnée en longueur de pixel si la dimension était un entier et avec la valeur donnée en pourcentage si la dimension était un pourcentage.
J'ai essayé de lire les spécifications w3c flexbox et je suis tombé sur this . Il dit que
Pour chaque dimension, si cette dimension de la zone de contenu du conteneur flexible est une taille définie, utilisez-la; si cette dimension du conteneur flexible est dimensionnée sous une contrainte de contenu min ou max, l'espace disponible dans cette dimension est cette contrainte.
Sinon, soustrayez la marge, la bordure et le rembourrage du conteneur flexible de l'espace disponible pour le conteneur flexible dans cette dimension et utilisez cette valeur qui pourrait donner une valeur infinie.
J'espère que cela t'aides.
Ici, vous avez écrit max-height: 10vh, vh ne prend en charge aucun navigateur, à l'exception du tout dernier iOS 6. Cela vaut pour toutes les unités de longueur liées à la fenêtre. utilisez d'autres valeurs au lieu de Vh, cela fonctionnera bien. Veuillez lire ce blog https://css-tricks.com/the-lengths-of-css/ .
.flex-parent {
display: flex;
max-height: max-content;
}
<div class="flex-parent">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/be/Red_eyed_tree_frog_edit2.jpg/320px-Red_eyed_tree_frog_edit2.jpg">
<img width="320" height="240" src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/be/Red_eyed_tree_frog_edit2.jpg/320px-Red_eyed_tree_frog_edit2.jpg">
</div>
Le problème est où vous définissez max-height. La propriété css max-height n'est pas héritée par défaut. Votre déclaration CSS crée une div qui correspond à 10% de la hauteur de la fenêtre. L'image sans aucune dimension définie a été réduite en fonction de ses dimensions parentes. L'image sur laquelle vous définissez les dimensions implicites sera toujours ces dimensions. Selon la taille du div, il peut déborder. Si vous mettez la propriété max-height sur la première image, elle devrait être redimensionnée en gardant le même rapport hauteur/largeur.