CSS3 Flexbox保持图像宽高比

cod*_*rMe 107 html css css3 flexbox

使用CSS弹性盒模型,如何强制图像保持其纵横比?

JS小提琴 http://jsfiddle.net/xLc2Le0k/2/

请注意,图像会拉伸或缩小以填充容器的宽度.那很好,但我们是否可以拉伸或缩小高度以保持图像比例?

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>
Run Code Online (Sandbox Code Playgroud)

CSS

.slider {
    display: flex;
}
.slider img {
    margin: 0 5px;
}
Run Code Online (Sandbox Code Playgroud)

Muh*_*mer 63

对于img标签,如果您定义一侧,则调整另一侧的大小以保持纵横比,并且默认情况下图像会扩展为其原始大小.

如果将每个img标记包装到div标签并将其宽度设置为父div的100%,则使用此事实,则高度将根据您的需要根据宽高比.

http://jsfiddle.net/0o5tpbxg/

* {
    margin: 0;
    padding: 0;
}
.slider {
    display: flex;
}
.slider .slide img {
    width: 100%;
}
Run Code Online (Sandbox Code Playgroud)

  • 但是这个答案并没有谈论任何关于flexbox的内容,因为图像在flexbox容器中的行为有所不同.设置一侧不会按比例调整另一侧的大小.将它们包装在非flexbox容器中会有所帮助,但会增加不必要的标记,从而失去语义. (14认同)
  • 但是,这个怎么样?http://jsfiddle.net/xLc2Le0k/15/我认为这个解决方案只是因为图像的比例相同才有效.旁注:通过将图像放置在div中进行定位(尤其是在处理响应图像时),没有任何"语义"丢失. (4认同)
  • 它看起来不像你需要一个包装div来使这项工作:http://jsfiddle.net/xLc2Le0k/120/ (3认同)
  • 我知道有两个答案建议使用div,但我正在将这个答案标记为正确,因为它解释了**为什么**图像高度与我预期的不同.事实上,这是正常和正确的行为,并且不太可能被"修复",因为它不是一个错误. (2认同)

Mat*_*aam 58

为了防止图像在flex父级内的任一轴上拉伸,我找到了几个解决方案.

您可以尝试在图像上使用对象拟合,例如

object-fit: contain;
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/ykw3sfjd/

或者您可以添加flex-specfic规则,这些规则在某些情况下可能会更好.

align-self: center;
flex: 0 0 auto;
Run Code Online (Sandbox Code Playgroud)

  • 如果不是[缺少IE和Edge的支持](http://caniuse.com/#search=object-fit)甚至达到Edge 14,那么object-fit可能是一个很好的解决方案 (4认同)

小智 50

无需添加包含div.

css"align-items"属性的默认值是"stretch",这是导致图像被拉伸到其原始高度的原因.将css"align-items"属性设置为"flex-start"可以解决您的问题.

.slider {
    display: flex;
    align-items: flex-start;  /* ADD THIS! */
}
Run Code Online (Sandbox Code Playgroud)

  • 啊...感谢您以支持的方式进行操作。我一直在阅读答案,直到那个答案,而且简直不敢相信我们所有的东西都是肮脏的骇客。 (3认同)

Sti*_*ers 35

大多数具有固有尺寸的图像,即自然尺寸,如jpeg图像.如果指定的大小定义宽度和高度中的一个,则使用内在比率确定缺失值... - 请参阅MDN.

但据我所知,如果将图像设置为具有当前灵活盒布局模块级别1的直接弹性项目,则无法正常工作.

请参阅这些讨论,并且可能与错误报告有关:


作为一种解决方法,您可以<img>用a <div>或a <span>左右包装每个.

的jsfiddle

.slider {
  display: flex;
}

.slider>div {
  min-width: 0; /* why? see below. */
}

.slider>div>img {
  max-width: 100%;
  height: auto;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

4.5隐含的最小Flex项目大小

为了为flex项提供更合理的默认最小大小,此规范引入了一个新的自动值作为CSS 2.1中定义的min-widthmin-height属性的初始值.


或者,您可以使用CSS table布局,您将获得类似的结果flexbox,它可以在更多浏览器上工作,甚至对于IE8.

的jsfiddle

.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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

  • flexbox规范引入了一个新的`auto`值作为`min-width`和`min-height`的默认值(之前它是'0`).Chrome尚未实现,因此您的第一个代码段正常运行.但是新浏览器需要它以允许弹性项目缩小小于图像的默认宽度. (3认同)
  • +1应该接受答案,因为它谈论的是flexbox模型中的图像,这是**根本问题**在这种情况下...... (2认同)

Muh*_*mer 5

我最近一直在玩flexbox,我通过实验和以下推理来解决这个问题.然而,实际上我不确定这究竟是发生了什么.

如果实际宽度受弹性系统的影响.因此,在元素的宽度达到父级的最大宽度之后,将忽略在css中设置的额外宽度.然后将宽度设置为100%是安全的.

由于img标签的高度来自图像本身,因此将高度设置为0%可以做一些事情.(这是我不清楚的地方......但我认为它应该修复它)

DEMO

(记得先在这里看到它!)

.slider {
    display: flex;
}
.slider img {
    height: 0%;
    width: 100%;
    margin: 0 5px;
}
Run Code Online (Sandbox Code Playgroud)

仅适用于镀铬