具有max-height
样式的Flexbox中的图片看起来会有不同的呈现方式,具体取决于它是否设置了height
和width
属性。
具有属性的,设置为图像的真实宽度/高度,保留其宽高比,但没有属性的那些尊重max-height
并显示为压扁
.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>
&#13;
这就是Chrome 58中的显示方式(在Firefox 54中也是如此)。
https://en.wikipedia.org/wiki/File:Red_eyed_tree_frog_edit2.jpg
为什么它们的渲染方式不同?管理这种行为的规则是什么?
我(显然不正确)的理解是高度和宽度属性会覆盖图像加载时找到的固有高度和宽度,如果高度和宽度属性等于图像的尺寸,渲染应该没有区别图像加载后。
上下文正在制作一个包含响应式图像的页面,其中每个图像都是
vh
)青蛙图像来自{{3}}
答案 0 :(得分:33)
弹性容器的初始设置为align-items: stretch
。
这意味着flex项目将扩展到容器的cross axis。
在行方向容器中,与问题一样,横轴是垂直的。
这意味着物品(图像,在这种情况下)将覆盖容器的整个高度。
但是,当弹性项目具有已定义的交叉大小时,它会覆盖stretch
默认值。
来自规范:
8.3. Cross-axis Alignment: the
align-items
andalign-self
propertiesFlex项目可以在当前行的交叉轴上对齐 flex容器,类似于
justify-content
但在垂直方向 方向。<强>
stretch
强>如果flex项的cross size属性计算为
auto
,则 两个横轴边距都不是auto
,flex项是 拉伸。
这是关键语言:
如果flex项的cross size属性计算为
auto
这就是规范定义“交叉尺寸属性”的方式:
弹性项目的宽度或高度,以十字中的任何一个为准 维度,是项目的交叉大小。 交叉尺寸属性是 交叉维度中的
width
或height
中的任何一个。
因此,您的代码似乎按规范中的定义播放。
这就是你所拥有的:
.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>
第一张图片在CSS或HTML中没有定义的宽度(主要尺寸)或高度(横向尺寸)。因此,它的交叉大小计算为auto
。
本声明:
如果flex项的cross size属性计算为
auto
...是真的,align-items: stretch
生效。
图像在容器的高度上扩展,为10px。
然而,第二张图片具有明确的尺寸。交叉大小在HTML(height="240"
)中定义。
现在声明:
如果flex项的cross size属性计算为
auto
...为false,并且align-items: stretch
被覆盖。 HTML height
属性占优势。
关于第二张图片的两个注释:
max-height
限制,因为CSS中的初始设置为overflow: visible
。width
和height
属性映射到各自的CSS属性。因此,height="240"
会覆盖height: auto
默认值。请参阅下面的规格参考。* 在Flex容器中渲染图像时,还有两个需要考虑的问题。
弹性项目的默认最小大小。此设置可防止弹性项目缩小到其内容大小以下。阅读这篇文章了解详情:
主要浏览器之间的行为不同。 Firefox,Chrome,Safari,Edge和IE11并不总是以相同的方式将图像渲染为弹性项目。阅读这篇文章了解更多详情:
考虑到上述所有因素,这是我建议的解决方案:
.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>
* HTML width
和height
属性映射到各自的CSS属性。因此,在指定时,它们会覆盖CSS默认值。来自HTML5规范:
10.4.3 Attributes for embedded content and images
width
,height
,applet
上的embed
和iframe
属性,object
或video
个元素,input
元素type
图像按钮状态中的属性,或者表示一个 图像或用户期望的图像最终将代表图像, 分别映射到元素上的维度属性width
和height
。10.2 The CSS user agent style sheet and presentational hints
当下面的文字说明元素上的属性映射到 维度属性(或属性),这意味着如果元素具有 一个属性集,并使用rules for parsing dimension values解析该属性的值不会产生错误,那么用户代理应该使用 解析维度作为presentational hint的值 属性,如果维度,则给定值作为像素长度 是一个整数,如果是,则以百分比给出的值 维度是一个百分比。
答案 1 :(得分:3)
尝试阅读w3c flexbox规范并偶然发现this。它说
对于每个维度,如果是Flex容器的内容的维度 盒子是一定的尺寸,使用那个;如果是flex的那个维度 容器的大小在最小或最大内容约束下, 该维度中的可用空间是该约束。
否则,从该维度中Flex容器的可用空间中减去Flex容器的边距,边框和填充,并使用可能导致无限值的值。
希望这有帮助。
答案 2 :(得分:2)
这里你写了max-height:10vh,vh不支持任何浏览器,除了最新的iOS 6.这适用于所有与视口相关的长度单位。 使用其他值而不是Vh这将正常工作。 请阅读此博客https://css-tricks.com/the-lengths-of-css/。
.flex-parent {
display: flex;
max-height: max-content;
}
&#13;
<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>
&#13;
答案 3 :(得分:0)
问题在于您设置max-height。默认情况下不会继承css属性max-height。您的css声明会创建一个占视口高度10%的div。没有尺寸设置的图像根据其父级尺寸缩小。您设置隐式尺寸的图像始终是那些尺寸。根据div的大小,它可能会溢出。如果将max-height属性放在第一个图像上,则应调整大小以保持纵横比相同。