使用 CSS flex box 模型,如何强制图像保持其纵横比?
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>
CSS
.slider {
display: flex;
}
.slider img {
margin: 0 5px;
}
background-image: url(...);background-size:contain; background-repeat:no-repeat
的 <div>
为了防止图像在 flex 父级中的任一轴上拉伸,我找到了几个解决方案。
您可以尝试在图像上使用对象拟合,例如
object-fit: contain;
或者您可以添加在某些情况下可能会更好的弹性特定规则。
align-self: center;
flex: 0 0 auto;
对于 img 标签,如果您定义一侧,则会调整另一侧的大小以保持纵横比,并且默认情况下图像会扩展为其原始大小。
使用这个事实,如果你将每个 img 标签包装到 div 标签中并将其宽度设置为父 div 的 100%,那么高度将根据你想要的纵横比。
* {
margin: 0;
padding: 0;
}
.slider {
display: flex;
}
.slider .slide img {
width: 100%;
}
无需添加包含 div。
css“align-items”属性的默认值是“stretch”,这就是导致图像被拉伸到其完整原始高度的原因。将css“align-items”属性设置为“flex-start”可以解决您的问题。
.slider {
display: flex;
align-items: flex-start; /* ADD THIS! */
}
大多数具有固有尺寸的图像,即自然尺寸,如 jpeg 图像。如果指定的大小定义了宽度和高度之一,则使用内在比率确定缺失值... - 请参阅 MDN。
但据我所知,如果使用当前 Flexible Box Layout Module Level 1 将图像设置为直接弹性项目,则这不会按预期工作。
请参阅这些讨论和可能相关的错误报告:
Flexbugs #14 - Chrome/Flexbox Intrinsic Sizing 未正确实现。
Firefox 错误 972595 - Flex 容器应该使用“flex-basis”而不是“width”来计算 flex 项的固有宽度
Chromium 问题 249112 - 在 Flexbox 中,允许固有纵横比通知主尺寸计算。
作为一种解决方法,您可以使用 <div>
或 <span>
等来包装每个 <img>
。
.slider { 显示:弹性; } .slider>div { 最小宽度:0; /* 为什么?见下文。 */ } .slider>div>img { 最大宽度:100%;高度:自动; }
4.5 Flex 项目的隐含最小尺寸 为了给弹性项目提供一个更合理的默认最小尺寸,本规范引入了一个新的 auto 值作为 CSS 2.1 中定义的 min-width 和 min-height 属性的初始值。
或者,您可以改用 CSS table
布局,您将获得与 flexbox
类似的结果,它适用于更多浏览器,甚至适用于 IE8。
.slider { 显示:表格;宽度:100%;表格布局:固定;边框折叠:折叠; } .slider>div { 显示:表格单元;垂直对齐:顶部; } .slider>div>img { 最大宽度:100%;高度:自动; }
min-width: auto
的新浏览器上,第一个代码段需要 .slider > div{min-width:0}
。
auto
值作为 min-width
和 min-height
的默认值(以前是 0
)。 Chrome 还没有实现它,所以你的第一个片段可以工作。但是新的浏览器需要它来允许弹性项目缩小到小于图像的默认宽度。
我最近一直在玩 flexbox,我通过实验和以下推理来解决这个问题。然而,实际上我不确定这是否正是发生的事情。
如果实际宽度受柔性系统影响。因此,在元素的宽度达到父级的最大宽度后,它们在 css 中设置的额外宽度将被忽略。然后将宽度设置为 100% 是安全的。
由于 img 标签的高度来自图像本身,因此将高度设置为 0% 可以做一些事情。 (这是我不清楚什么......但对我来说应该修复它是有道理的)
演示
(记得先在这里看到!)
.slider {
display: flex;
}
.slider img {
height: 0%;
width: 100%;
margin: 0 5px;
}
仅适用于 chrome
auto
"。这就是在 Firefox 上发生的事情。
这种行为是预期的。默认情况下,flex 容器会拉伸它的所有子容器。图片也不例外。 (即,父级将具有 align-items: stretch
属性)
为了保持纵横比,我们有两种解决方案:
将默认的 align-items:stretch 属性替换为 align-items: flex-start 或 align-self: center 等,http://jsfiddle.net/e394Lqnt/3/
或者
将 align 属性专门设置为孩子本身:like, align-self: center 或 align-self: flex-start 等 http://jsfiddle.net/e394Lqnt/2/
声明 display: flex;
被赋予元素的位置。
align-items: center;
实际上我发现图像标签的容器需要有一个高度才能保持图像的比例。例如>
.container{display:flex; height:100%;} img{width:100%;height:auto;}
然后在您的 html 中,您的容器将包装标签图像
<div class="container"><img src="image.jpg" alt="image" /></div>
这适用于 IE 和其他浏览器
我只是有同样的问题。使用 flex align 使元素居中。您需要使用 align-items: center
而不是 align-content: center
。这将保持纵横比,而 align-content 不会保持纵横比。
object-fit: contain;
为我做了诀窍,当我只在 chrome 中遇到问题时,ff 很好。