ChatGPT解决这个技术问题 Extra ChatGPT

更改高度时保持图像纵横比

使用 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;
}
据我所知,最好的解决方案是使用带有 CSS background-image: url(...);background-size:contain; background-repeat:no-repeat<div>
这里有一些有趣的线索,但是当图像的比例不同时怎么办?添加和“额外”的 div 是我们需要担心的最后一件事。为什么不使用这样的测试用例:jsfiddle.net/sheriffderek/999Lg9qv

M
Matty Balaam

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

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

object-fit: contain;

http://jsfiddle.net/ykw3sfjd/

或者您可以添加在某些情况下可能会更好的弹性特定规则。

align-self: center;
flex: 0 0 auto;

如果没有 missing support in IE and Edge 甚至到 Edge 14,object-fit 可能是一个很好的解决方案
我自己一直在使用那个后备,效果很好。
@daniels Edge 现在正在开发对象匹配:developer.microsoft.com/en-us/microsoft-edge/platform/status/…
object-fit: contain; 为我做了诀窍,当我只在 chrome 中遇到问题时,ff 很好。
S
Samuel Liew

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

使用这个事实,如果你将每个 img 标签包装到 div 标签中并将其宽度设置为父 div 的 100%,那么高度将根据你想要的纵横比。

http://jsfiddle.net/0o5tpbxg/

* {
    margin: 0;
    padding: 0;
}
.slider {
    display: flex;
}
.slider .slide img {
    width: 100%;
}

我知道有两个答案建议使用 div,但我将这个答案标记为正确,因为它解释了为什么图像高度与我预期的不同。事实上,这是正常且正确的行为,不太可能被“修复”,因为它不是错误。
但是这个答案并没有谈论任何关于 flexbox 的内容,因为图像在 flexbox 容器中的行为确实不同。设置一侧不会按比例调整另一侧的大小。将它们包装在非 flexbox 容器中会有所帮助,但这会增加不必要的标记,从而失去语义。
看起来您不需要包装 div 来完成这项工作:jsfiddle.net/xLc2Le0k/120
但是,这个呢? jsfiddle.net/xLc2Le0k/15 我认为这个解决方案是侥幸,因为图像的比例都是相同的。旁注:通过将图像放置在 div 中进行定位/尤其是在处理响应式图像时,不会丢失任何“语义”。
真的是最干净的解决方案,它适用于图片!
M
Marvin Herbold

无需添加包含 div。

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

.slider {
    display: flex;
    align-items: flex-start;  /* ADD THIS! */
}

啊...感谢您以受支持的方式实际做事。我一直在阅读答案,直到那个答案,不敢相信我们所拥有的只是肮脏的黑客......
这应该是答案
没有其他答案有效,你拯救了我的一天!
S
Stickers

大多数具有固有尺寸的图像,即自然尺寸,如 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>

jsFiddle

.slider { 显示:弹性; } .slider>div { 最小宽度:0; /* 为什么?见下文。 */ } .slider>div>img { 最大宽度:100%;高度:自动; }

< div>

4.5 Flex 项目的隐含最小尺寸 为了给弹性项目提供一个更合理的默认最小尺寸,本规范引入了一个新的 auto 值作为 CSS 2.1 中定义的 min-width 和 min-height 属性的初始值。

或者,您可以改用 CSS table 布局,您将获得与 flexbox 类似的结果,它适用于更多浏览器,甚至适用于 IE8。

jsFiddle

.slider { 显示:表格;宽度:100%;表格布局:固定;边框折叠:折叠; } .slider>div { 显示:表格单元;垂直对齐:顶部; } .slider>div>img { 最大宽度:100%;高度:自动; }

< div>


在支持 min-width: auto 的新浏览器上,第一个代码段需要 .slider > div{min-width:0}
flexbox 规范引入了一个新的 auto 值作为 min-widthmin-height 的默认值(以前是 0)。 Chrome 还没有实现它,所以你的第一个片段可以工作。但是新的浏览器需要它来允许弹性项目缩小到小于图像的默认宽度。
+1这应该被接受的答案,因为它谈到了flexbox模型中的图像,这是这种情况下的根本问题......
如果你的布局在不同的断点处没有改变,那么表格就很棒,但现在这不太可能。
当图像的比例不同时怎么办? jsfiddle.net/sheriffderek/5u7y21we
M
Muhammad Umer

我最近一直在玩 flexbox,我通过实验和以下推理来解决这个问题。然而,实际上我不确定这是否正是发生的事情。

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

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

演示

(记得先在这里看到!)

.slider {
    display: flex;
}
.slider img {
    height: 0%;
    width: 100%;
    margin: 0 5px;
}

仅适用于 chrome


有趣,但它似乎是一个错误。根据the spec,“百分比是相对于生成框的包含块的高度计算的。如果包含块的高度没有明确指定(即取决于内容高度),则该元素不是绝对定位的,该值计算为 auto"。这就是在 Firefox 上发生的事情。
jsfiddle.net/xLc2Le0k/8 解释 ff 和 chrome 的区别。为了这
width 似乎在 ff 中做了什么 height 在 chrome 中做了什么。
这很有趣,但恐怕只有 X 浏览器的解决方案并不是真正的解决方案。您在此处评论的小提琴:jsfiddle.net/xLc2Le0k/8 在 FF 中绝对是令人着迷。这似乎表明 FF 正在使图像高度与图像高度“成比例”,如果它真的是 100%。换句话说,img 并不“知道”容器的显示:这解释了为什么在 FF 中,如果将 img 的宽度设置为 100%,则图像比将宽度设置为 auto 时更高。
这有点接近...但仅适用于 Chrome:jsfiddle.net/sheriffderek/xLc2Le0k/270
A
Asim K T

这种行为是预期的。默认情况下,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/


Z
ZungTa

声明 display: flex; 被赋予元素的位置。
align-items: center;


k
kengreg

实际上我发现图像标签的容器需要有一个高度才能保持图像的比例。例如>

.container{display:flex; height:100%;} img{width:100%;height:auto;}

然后在您的 html 中,您的容器将包装标签图像

<div class="container"><img src="image.jpg" alt="image" /></div>

这适用于 IE 和其他浏览器


C
Clinton Green

我只是有同样的问题。使用 flex align 使元素居中。您需要使用 align-items: center 而不是 align-content: center。这将保持纵横比,而 align-content 不会保持纵横比。


关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅