CSS 容器查询单元
原文链接:ishadeed.com/article/con…
几天前,我看到Miriam Suzanne 的一条推文,关于支持 CSS 查询单元。这最初是由Una Kravets在 Github 上提出的。我忍不住尝试了它们,看看我们如何从 CSS 容器查询中获得更多好处。
我将尽力解释每个单元的工作原理,以及我们可以在哪里使用单元来增强组件对其父宽度的反应。如果您还不了解 CSS 容器查询,我写了一篇介绍,其中包含大量示例以及容器查询如何影响设计人员的工作。我建议在阅读本文之前先阅读它们。
温馨提醒:CSS 容器查询仅在带有实验标志的 Chrome Canary 中受支持。要使用它,请转到
chrome://flags
并搜索“启用 CSS 容器查询”并启用该功能。
让我们潜入。
介绍
在 CSS 中,我们有很多可以用于不同目的的单位。最常用的有px
,rem
和em
。如果与 CSS 容器查询单元的工作方式接近,那么我会说视口单元。
CSS 视口单位以响应浏览器视口大小(宽度或/和高度)的方式工作。这很好,但我们并不总是想使用与视口大小相关的单位。如果我们想查询容器宽度怎么办?这就是查询单元的用途。
为了更清楚,我想强调视口单位和查询单位之间的区别。考虑下图:
在左侧,font-size
由rem
和控制vw
,这将相对于视口宽度。在某些情况下,这可能有效,但可能会导致意外问题,因为它与视口大小有关。
查询单位可以用之类的东西打交道时,我们节省精力和时间font-size
,padding
以及margin
一个组件中。我们可以使用查询单位代替手动增加字体大小。
考虑以下示例。
我们有一个卡片组件,它以堆叠样式开始,当容器很大时一直到类似英雄的样式。对于这样的组件,我们可能需要更改以下内容:
- 缩略图大小
- 字体大小
- 元素之间的间距
如果没有 CSS 查询单元,我们需要手动更改上述内容。
.卡片 {
/* 堆叠的基本样式 */
}
.card__title {
字体大小:1rem;
}
/* 水平样式,v1 */
@container(最小宽度:400px){
.card__title {
字体大小:1.15rem;
}
}
/* 水平样式,v2 */
@container(最小宽度:600px){
.card__title {
字体大小:1.25rem;
}
}
/* 英雄风格 */
@container(最小宽度:800px){
.card__title {
字体大小:2rem;
}
}
注意.card__title
字体大小是如何随着不同的容器查询而改变的。我们可以font-size
通过使用查询单元和 CSS函数来增强它并避免重复clamp()
。
.card__title {
字体大小:夹(1rem,3qw,2rem);
}
有了这个,我们需要定义font-size
唯一一次。如果我们想在视觉上比较它,这是它的外观:
如果您熟悉 CSS 视口单位,这对您来说并不陌生。这就像查询容器而不是浏览器的视口一样。整洁,不是吗?
查询单位
现在我们已经了解了查询单元应该解决的问题,让我们获取单元。根据CSS 规范:
- 查询宽度(qw):容器宽度的 1%。例如, 5qw 将解析为容器宽度的 5%。
- 查询高度(qh):容器高度的1%。例如,5qh 将解析为容器高度的 5%。
- 查询最小值(qmin):查询宽度
qw
或查询高度的较小值qh
。 - 查询最大值 (qmax):
qw
或的较大值qh
。
我们还有另外两个单元:qi
andqb
它们分别表示 Query Inline 和 Query Block。它们可用于我们有不同书写模式的情况。
用例和示例
卡片组件
除了前面解释的卡片示例之外,我们还可以对堆叠卡片使用查询单元,其中我们希望字体大小基于容器宽度稍大。
请注意,字体大小会根据容器大小变大。这对于创建无论放置在哪里都可以使用的堆叠卡片组件非常有用。
基于重要性的变化font-size
当一个元素比另一个元素大时,它更有可能表明它更重要。一个很好的例子是side and main。an 中的标题大小<aside>
应小于部分中的标题<main>
。
请注意 中的标题如何<aside>
小于 中的标题<main>
。由于查询单元,我们可以轻松做到这一点。
首先,我们需要定义<aside>
和<main>
作为内联大小的容器。
在旁边,
主要的 {
容器:内联大小;
}
然后,我们将为部分标题使用查询单元。我们还可以对底部边距使用查询单位。
.section-title {
字体大小:夹子(1.25rem,3qw,2rem);
margin-bottom: 钳位(0.5rem, 1.5qw, 1rem);
}
生物成分
个人简介可以存在于较小的容器中(例如:侧边栏)或显示在移动视口上,或显示在页面标题等大容器中。
我们可以构建一个可以适应其容器宽度的组件。在该示例中,用户头像和字体大小根据其容器宽度而变化。
.bio {
容器:内联大小;
}
.c-头像{
--size: calc(60px + 10qw);
宽度:var(--size, 100px);
高度:var(--size, 100px);
margin-bottom: 钳位(0.5rem, 3qmin, 2rem);
}
带计数器的标题
在某些情况下,我们需要在带有文章正文的标题旁边显示一个计数器。这是查询单元的完美用例。
.article-body {
反复位:航向;
}
h2{
容器:内联大小;
字体大小:夹子(1.25rem,3qw,2rem);
margin-bottom: 钳位(0.5rem, 1.5qw, 1rem);
}
h2:之前{
--size: calc(1.25rem + 3qw);
内容:计数器(标题);
反增量:标题;
宽度:var(--size);
高度:var(--size);
字体大小:计算(0.85rem + 1qw);
边距右: calc(var(--size) / 4);
}
动态间隙
我们一直在使用视口单元来创建带有 CSS 网格的动态间隙。它是这样的:
.包装{
差距:计算(1rem + 2vw);
}
这很酷,但是特定包装器中的组件呢?使用视口单位将不起作用。这就是为什么在这种情况下使用查询单元是一个很好的解决方案。
卡片 {
显示:弹性;
弹性方向:列;
差距:计算(0.5rem + 1qmin);
}
当组件切换到水平样式时,间隙会更大一些。
如果我们在没有定义容器的情况下使用查询单元会发生什么?
根据规范:
如果没有符合条件的查询容器可用,则对该轴使用小视口尺寸。
浏览器将处理查询单位,就好像它们是视口单位一样。考虑以下示例:
h2{
字体大小:夹子(1.25rem,3qw,2rem);
}
如果没有为 定义容器,<h2>
浏览器会认为3qw
它是3%
视口宽度的。这意味着,在不定义容器的情况下使用查询单元可能会导致意外结果。
我希望你喜欢这篇文章。谢谢阅读!