此 CSS 属性有助于在自适应布局中保持间距。
宽高比
纵横比最常以两个整数和一个英文冒号的形式表示,即宽度:高度或 x:y。最常见的摄影宽高比为 4:3 和 3:2,而视频和较新款的消费类相机的宽高比往往为 16:9。
随着响应式设计的出现,保持宽高比对 Web 开发者来说变得越来越重要,尤其是在图片尺寸不同且元素大小会根据可用空间而变化的情况下。
以下是一些需要保持宽高比的重要场景示例:
- 创建自适应 iframe,其宽度为父级宽度的 100%,高度应保持特定的视口宽高比
- 为图片、视频和嵌入内容创建内在占位符容器,以防止在这些内容加载并占用空间时重新布局
- 为交互式数据可视化或 SVG 动画创建统一的自适应空间
- 为卡片或日历日期等多元素组件创建统一的自适应空间
- 为尺寸各异的多个图片创建统一的自适应空间(可与
object-fit
搭配使用)
object-fit
定义宽高比有助于我们在自适应环境中调整媒体大小。此分桶中的另一个工具是 object-fit
属性,可让用户描述某个分块中的对象(例如图片)应如何填充该分块:
initial
和 fill
值会重新调整图片以填充空间。在我们的示例中,由于系统会重新调整像素,因此会导致图片变形和模糊。不理想。object-fit: cover
会使用图片的最小尺寸来填充空间,并根据此尺寸剪裁图片以使其适合该空间。它会在其最小边界处“放大”。object-fit: contain
可确保整个图片始终可见,与 cover
相反,后者会采用最大的边界大小(在上面的示例中,这是宽度),并调整图片大小,以便在保持其固有宽高比的同时适应空间。object-fit: none
示例显示了在中心(默认对象位置)以自然尺寸剪裁的图片。
在大多数情况下,object-fit: cover
往往可在处理不同尺寸的图片时确保实现良好的统一界面,但这样会丢失信息(图片会在最长边被剪裁)。
如果这些细节很重要(例如,在处理美妆产品的平铺照片时),则不得剪裁重要内容。因此,理想情况下,自适应图片应具有不同的尺寸,能够适应界面空间,而无需剪裁。
老技巧:使用 padding-top
保持宽高比
为了让这些元素更具响应能力,我们可以使用宽高比。这样,我们就可以设置特定的宽高比尺寸,并将媒体的其余部分基于单个轴(高度或宽度)。
为了根据图片宽度保持宽高比,目前广接受的跨浏览器解决方案被称为“上内边距 Hack”。此解决方案需要一个父容器和一个绝对放置的子容器。然后,将宽高比计算为百分比,以设置为 padding-top
。例如:
- 宽高比为 1:1 = 1 / 1 = 1 =
padding-top: 100%
- 4:3 宽高比 = 3 / 4 = 0.75 =
padding-top: 75%
- 宽高比 3:2 = 2 / 3 = 0.66666 =
padding-top: 66.67%
- 宽高比 16:9 = 9/16 = 0.5625 =
padding-top: 56.25%
确定宽高比值后,我们可以将其应用于父级容器。请参考以下示例:
<div class="container">
<img class="media" src="..." alt="...">
</div>
然后,我们可以编写以下 CSS:
.container {
position: relative;
width: 100%;
padding-top: 56.25%; /* 16:9 Aspect Ratio */
}
.media {
position: absolute;
top: 0;
}
使用 aspect-ratio
保持宽高比
遗憾的是,计算这些 padding-top
值并不直观,并且需要一些额外的开销和定位。借助新的固有 aspect-ratio
CSS 属性,保持宽高比所用的语言更清晰。
使用相同的标记,我们可以将 padding-top: 56.25%
替换为 aspect-ratio: 16 / 9
,并将 aspect-ratio
设置为指定的 width
/ height
比率。
.container { width: 100%; padding-top: 56.25%; }
.container { width: 100%; aspect-ratio: 16 / 9; }
使用 aspect-ratio
代替 padding-top
会更加清晰明了,而且不会更新内边距属性来执行超出其常规范围的操作。
此新属性还添加了向 auto
设置宽高比的功能,其中“具有内在宽高比的替换元素会使用该宽高比;否则,该框没有首选宽高比。”如果同时指定了 auto
和 <ratio>
,则首选宽高比为 width
除以 height
的指定宽高比,除非它是具有固有宽高比的被替换元素,在这种情况下会改用宽高比。
示例:网格中的一致性
这也非常适用于 CSS 网格和 Flexbox 等 CSS 布局机制。假设您有一个列表,其中包含您希望保持 1:1 宽高比的子项,例如赞助商图标网格:
<ul class="sponsor-grid">
<li class="sponsor">
<img src="..." alt="..."/>
</li>
<li class="sponsor">
<img src="..." alt="..."/>
</li>
</ul>
.sponsor-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
}
.sponsor img {
aspect-ratio: 1 / 1;
width: 100%;
object-fit: contain;
}
示例:防止布局偏移
aspect-ratio
的另一项出色功能是,它可以创建占位符空间,以防止累积布局偏移并提供更好的Web Vitals。在第一个示例中,从 Unsplash 等 API 加载资源会在媒体加载完毕时导致布局偏移。
另一方面,使用 aspect-ratio
会创建一个占位符来防止这种布局偏移:
img {
width: 100%;
aspect-ratio: 8 / 6;
}
额外提示:宽高比的图片属性
设置图片宽高比的另一种方法是通过 image 属性。如果您事先知道图片的尺寸,那么最佳实践是将这些尺寸设置为其 width
和 height
。
在上述示例中,我们知道尺寸为 800 x 600 像素,因此图片标记将如下所示:<img src="image.jpg"
alt="..." width="800" height="600">
。如果发送的图片具有相同的宽高比,但不一定具有这些确切的像素值,我们仍然可以使用图片属性值设置宽高比,并结合使用 width: 100%
样式,以便图片占据适当的空间。所有这些代码加起来将如下所示:
<!-- Markup -->
<img src="image.jpg" alt="..." width="8" height="6">
/* CSS */
img {
width: 100%;
height: auto;
}
最终,其效果与通过 CSS 在图片上设置 aspect-ratio
相同,并且可以避免累积布局偏移(请参阅 Codepen 上的演示)。
总结
借助新的 aspect-ratio
CSS 属性,您可以更轻松地在多个现代浏览器中发布应用,并在媒体和布局容器中保持适当的宽高比。
照片由 Amy Shamblen 和 Lionel Gustave 提供,来自 Unsplash。