如今,当图像单独出现在布局中时,创建流体图像非常容易。但是,随着更复杂的界面出现,我们经常需要将图像放置在响应式元素内部,例如这张卡片

现在,假设这张图像不是语义内容,而只是装饰。这是使用 `background-image` 的一个很好的用途。由于在此上下文中,图像包含一个对象,我们不能在响应式情况下允许任何部分被裁剪,因此我们将选择 `background-size: contain`。
这里开始变得棘手:在移动设备上,这张卡片会改变方向并变成垂直的,图像在顶部。我们可以使用任何类型的 CSS 布局技术实现这一点,并且可能最好使用 CSS 网格或 flexbox 处理。

但是,当我们测试更小的屏幕时,由于 `background-size: contain` 属性,我们会得到以下结果

这不太好。图像会调整大小以保持其纵横比,不会切断任何细节,如果图像非常重要的内容并且不应该被裁剪,我们就不能将 `background-size` 更改为 `cover`。
此时,我们可能会想到下一个尝试:将图像内联放置,而不是背景。
在桌面版上,这工作正常

在移动版上也不错

但在更小的屏幕上,由于所有固定大小,图像的比例会失真。

我们可以花几个小时调整图像、卡片、flex 属性,来回调整。或者,我们可以……
将主要内容与背景分离
这是在响应式图像方面获得更多灵活性和弹性的基础。这可能并非始终可以实现,但在很多情况下,可以通过在设计方面稍微努力来实现,特别是如果事先计划了这种方法。
在我们的下一个迭代中,我们将草莓图像放置在透明背景上,并使用 CSS 设置光栅图像中的蓝色。通过调整示例空间的大小,继续在演示中玩转视窗大小!
更深入地观察样式,请注意,我们还为包含图像的 div 添加了填充,因此草莓不会太靠近边缘。我们可以通过这种填充完全控制草莓与边缘之间的距离。
请注意,我们还使用负边距来弥补外部卡片包装上的填充,否则图像周围会出现空白。
对内联图像使用 `object-fit` 属性
尽管之前的演示有效,但我们仍然可以改进这种方法。到目前为止,我们假设图像是非语义内容——但通过这种布局,图像插图也很可能不仅仅是装饰。
如果是这样,我们绝对不希望图像被裁剪掉,因为这将相当于数据丢失。将图像内联放置而不是背景,在语义上更好,可以防止这种情况,我们可以使用 `object-fit` 属性来实现这一点。
我们将草莓从背景中提取出来,现在它是一个内联 `<img>` 元素,但我们保留了该图像 div 中的相同背景颜色。
最后,将 `object-fit: contain` 与 100% 的宽度结合起来,可以调整窗口大小并保持草莓的纵横比。然而,这种方法的缺点是我们需要为桌面版本上的图像设置一个固定高度——否则它将遵循设置宽度的比例(缩小它将改变布局)。如果我们需要生成带有可变文本量的卡片,这些文本会换行,这可能会让布局过于受限。
即将推出:`aspect-ratio`
针对上述问题的解决方案可能即将推出,使用即将推出的 `aspect-ratio` 属性。这将使我们能够为元素设置一个固定比率,例如
.el {
aspect-ratio: 16 / 9;
}
这意味着我们可以消除固定高度并用计算出的纵横比替换它。例如,最后一个示例的桌面断点中的尺寸如下所示
.image {
/* ... */
height: 184px;
width: 318px;
}
使用 `aspect-ratio`,我们可以删除高度声明并进行计算以获得最接近 184 的比率
.image {
/* ... */
width: 318px; /* Base width */
height: unset; /* Resets the height that was set outside the media query */
aspect-ratio: 159 / 92; /* Amounts close to a 184px height */
}
如果您想了解更多信息,可以在 这篇文章 中进一步了解这个即将推出的属性。
最后,在可变比例布局中,有多种方法可以实现可靠的响应式图像。但是,使这项工作变得更轻松、更好的技巧并不一定在于 CSS;它可能很简单,只需调整图像即可,无论是在分离前景和背景(如我们所做的那样),还是选择即使边缘被裁剪掉很大一部分也能正常工作的特定图像。
您可以使用以下方法进行比率设置:使用图像容器上的 `:before` 和 `top padding`(以 % 为单位),然后使用 `position: absolute` 和 `object-fit` 设置图像,或者将其作为背景并使用 `size: cover`。
感谢您发表了这篇发人深省的文章。
如果我理解这篇文章,在“移动”展示中,您不希望图像比例更改为在较大展示中显示的比例,而只是希望主题变得更大并保持居中。您也不希望图像和内容之间出现任何奇怪的间距,即使图像保持比例。
对于移动展示,这可以通过将图像放置在容器中来实现,这样图像会放大,并且容器设置为 `overflow: hidden`。两种技术的缺点取决于原始图像居中程度以及它独立于是否指定了固定高度的缩放程度。当然,如果图像没有居中,可以将其平移到看起来居中的位置。
请查看:https://codepen.io/jlevin/pen/qBbxXjO
我不明白为什么要通过修改草莓图像来去除其背景以实现这种效果。
您目前可以使用 `display: grid` 包装器和一个简单的 `<svg>` 来实现 `aspect-ratio`。
请查看此 SO 答案:https://stackoverflow.com/a/53245657/1891677
由于 css `aspect-ratio` 尚未可用(如文章所述),我一直在使用 `padding-top` 技巧来控制图像的纵横比。
这不是理想的方法,但它确实使很多事情变得更容易。尤其是在卡片中,因为我可以轻松地将一张图片渲染到不同大小/尺寸的卡片上(使用 `object-fit: cover` 而不是 `contain`)。
请查看代码:https://jsfiddle.net/r2sw78c4/
谢谢!这很有帮助
您好,感谢您发表这篇文章,我有一个问题
如果我们提供不同大小的图像会发生什么?在图像作为背景的一部分的方法中,我可以更改图像大小,但在内联方法中,我看不出如何做到这一点?