新的 CSS 属性,有助于在自适应布局中保持间距。
宽高比
宽高比通常以两个整数和一个英文冒号来表示,即“宽:高”或“x:y”。最常见的摄影宽高比为 4:3 和 3:2,而视频及较新款的消费类相机往往具有 16:9 的宽高比。
![宽高比相同的两张图片。其中一个为 634 x 951 像素,另一个为 200 x 300 像素。两者的宽高比均为 2:3。](https://web.developers.google.cn/static/articles/aspect-ratio/image/two-images-the-same-aspe-c70cc7ed740f8.jpg?authuser=5&hl=bg)
随着自适应设计的出现,保持宽高比对 Web 开发者来说越来越重要,特别是在图片尺寸不同且元素尺寸会根据可用空间发生变化时。
保持宽高比变得非常重要的一些示例如下:
- 创建自适应 iframe,其中它们的宽度等于父视图宽度的 100%,且高度应保持特定的视口比例
- 为图片、视频和嵌入式内容创建固有的占位符容器,以防止在内容加载并占用空间时重新布局
- 为交互式数据可视化或 SVG 动画创建统一的响应式空间
- 为卡片或日历日期等多元素组件创建统一的自适应空间
- 为多张不同尺寸的图片创建统一的自适应空间(可与
object-fit
一起使用)
对象匹配
指定宽高比有助于我们在响应式环境中调整媒体大小。此存储分区中的另一个工具是 object-fit
属性,用户可以通过该属性来说明块中的对象(例如图片)应如何填充该块:
![Object-fit 演示可视化效果](https://web.developers.google.cn/static/articles/aspect-ratio/image/object-fit-demo-visualiza-6e1b75de8297c.jpg?authuser=5&hl=bg)
object-fit
值。请参阅 Codepen 演示。initial
和 fill
值会重新调整图片以填充空间。在我们的示例中,这会导致图片在重新调整像素时被挤压和模糊。不理想。object-fit: cover
会使用图片的最小尺寸来填充空间,并根据此尺寸剪裁图片,使其适应图片大小。它会在最低边界“放大”。object-fit: contain
可确保整个图片始终可见,因此与 cover
相反,后者采用最大边界的大小(在上面的示例中为宽度),并调整图片大小以在适应空间的同时保持其固有宽高比。object-fit: none
情形显示的是在中心(默认对象位置)以其自然尺寸剪裁的图片。
object-fit: cover
在大多数情况下都可以确保处理不同尺寸的图像时能够呈现良好的统一界面,但是,您会以这种方式丢失信息(图像的最长边会被剪裁)。
如果这些细节很重要(例如,在使用美容产品平铺时),则不能剪裁重要内容。因此,理想的场景是大小各异且无需剪裁且适合界面空间的自适应图片。
老技巧:使用 padding-top
保持宽高比
![使用 padding-top 对轮播界面中的博文预览图片设置 1:1 的宽高比。](https://web.developers.google.cn/static/articles/aspect-ratio/image/using-padding-top-set-1-9702b5487f14c.jpg?authuser=5&hl=bg)
padding-top
为轮播界面中的博文预览图片设置 1:1 的宽高比。为了提高响应速度,我们可以使用宽高比。这样一来,我们就可以设置特定的宽高比尺寸,并使其余媒体以单个轴(高度或宽度)为基准。
“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
保持宽高比
![使用宽高比为轮播界面中的帖子预览图片设置 1:1 的宽高比。](https://web.developers.google.cn/static/articles/aspect-ratio/image/using-aspect-ratio-set-e58f152775151.jpg?authuser=5&hl=bg)
aspect-ratio
为轮播界面中的博文预览图片设置 1:1 的宽高比。遗憾的是,计算这些 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
的另一个强大功能是,它可以创建占位符空间,以防止 Cumulative Layout Shift 并提供更好的网页指标。在第一个示例中,从 Unsplash 等 API 加载素材资源会在媒体加载完成后产生布局偏移。
另一方面,使用 aspect-ratio
可创建占位符来防止布局偏移:
img {
width: 100%;
aspect-ratio: 8 / 6;
}
额外提示:适用于宽高比的图片属性
设置图片宽高比的另一种方法是通过图片属性。如果您提前知道图片的尺寸,最好将这些尺寸设置为其 width
和 height
。
对于上面的示例,知道尺寸为 800x600 像素后,图片标记将如下所示:<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%;
}
最后,效果与通过 CSS 在图片上设置 aspect-ratio
相同,并且可以避免累计布局偏移(请参阅 Codepen 上的演示)。
总结
借助新的 aspect-ratio
CSS 属性,可在多种现代浏览器中发布,在媒体和布局容器中保持适当的宽高比会变得更加简单一些。
照片由 Amy Shamblen 和 Lionel Gustave 提供,由 Unsplash。