为什么弹性项的宽度和高度会影响弹性项的渲染方式?

Mic*_*mza 40 html css flexbox responsive-images

具有max-height样式的flexbox中的图像根据其是否具有其属性集height而显示为不同呈现width.

所述一个属性,设置为图像的真实宽度/高度,使得与保留了其纵横比,但没有属性的那些尊重max-height和出现压扁.

.flex-parent {
  display: flex;
  max-height: 10vh;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

这就是Chrome 58中的显示方式(在Firefox 54中也是如此).

在flexbox中img的不同渲染. 没有宽度和高度属性,以及

他们为什么渲染不同?管理这种行为的规则是什么?

我的(显然不正确)的理解是,高度和宽度属性会覆盖在图像加载时发现内在的高度和宽度,如果高度和宽度属性等于图像的尺寸,应该是在渲染一旦图像无差异装了.

上下文正在制作一个包含响应图像的页面,其中每个图像

  • 可以有独特的原始尺寸
  • 加载时不会导致重排,即在初始渲染时保留正确的空间(因此使用高度和宽度属性)
  • 可以同时适应所有屏幕(因此我vh在CSS中搞乱)

青蛙图片来自https://en.wikipedia.org/wiki/File:Red_eyed_tree_frog_edit2.jpg

Mic*_*l_B 38

Flex容器的初始设置是align-items: stretch.

这意味着flex项目将跨容器的横轴扩展.

在行方向容器中,如问题中那样,横轴是垂直的.

这意味着物品(图像,在这种情况下)将覆盖容器的整个高度.

但是,当flex项具有已定义的交叉大小时,将覆盖stretch默认值.

从规格:

8.3.交叉轴对齐:align-itemsalign-self 属性

柔性物品可以在柔性容器的当前线的交叉轴上对齐,类似于justify-content但是在垂直方向上.

stretch

如果弹性项目的交叉大小属性计算到auto,并且两个横轴边距都不是auto,则伸展弹性项目.

这是关键语言:

如果flex项的cross size属性计算为 auto

这就是规范定义"交叉大小属性"的方式:

弹性项目的宽度或高度(以交叉维度中的任何一个为单位)是项目的交叉大小.该十字大小属性是取的width或者height是在横向尺寸.

https://www.w3.org/TR/css-flexbox-1/#cross-size-property


因此,您的代码似乎按照规范中的定义进行播放.

这就是你拥有的:

.flex-parent {
  display: flex;
  max-height: 10vh;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

第一个图像在CSS或HTML中没有定义的宽度(主要大小)或高度(交叉大小).因此,它的交叉尺寸可以计算出来auto.

这个说法:

如果flex项的cross size属性计算为 auto

......是真的,并且align-items: stretch生效了.

图像在容器的高度上扩展,为10px.

但是,第二张图像具有明确的尺寸.交叉大小在HTML(height="240")中定义.

现在这句话:

如果flex项的cross size属性计算为 auto

......是假的,align-items: stretch被覆盖了.HTML height属性占优势.

关于第二张图片的两个注释:

  1. 图像忽略了max-height容器的限制,因为CSS中的初始设置是overflow: visible.
  2. HTML widthheight属性映射到它们各自的CSS属性.因此,height="240"覆盖height: auto默认值.请参阅下面的规格参考.*

在Flex容器中渲染图像时,还有两个需要考虑的问题.

  1. 弹性项目的默认最小大小.此设置可防止弹性项目缩小到其内容大小以下.阅读这篇文章了解详情:

  2. 主流浏览器之间的变化行为.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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)


*HTML widthheight属性映射到它们各自的CSS属性.因此,在指定时,它们会覆盖CSS默认值.来自HTML5规范:

10.4.3嵌入内容和图像的属性

widthheight属性上applet,embed,iframe, objectvideo元件,并且input与元件type 在图像按钮状态和属性或者表示图像或用户期望最终将表示图像, 映射到尺寸属性 widthheight分别在元件上.

10.2 CSS用户代理样式表和表示提示

当下面的文本说明元素的属性映射到维度属性(或属性)时,这意味着如果元素具有属性集,并且使用解析维度值规则解析该属性的值不会生成错误,那么用户代理应该使用解析后的维度作为属性的表示提示的值,如果维度是整数,则将值作为像素长度给出,如果维度是a,则给出值作为百分比给出百分比.