CSS 容器查询单元

558 阅读6分钟

CSS 容器查询单元

原文链接:ishadeed.com/article/con…

几天前,我看到Miriam Suzanne 的一条推文,关于支持 CSS 查询单元。这最初是由Una Kravets在 Github 上提出的。我忍不住尝试了它们,看看我们如何从 CSS 容器查询中获得更多好处。

我将尽力解释每个单元的工作原理,以及我们可以在哪里使用单元来增强组件对其父宽度的反应。如果您还不了解 CSS 容器查询,我写了一篇介绍,其中包含大量示例以及容器查询如何影响设计人员的工作。我建议在阅读本文之前先阅读它们。

温馨提醒:CSS 容器查询仅在带有实验标志的 Chrome Canary 中受支持。要使用它,请转到chrome://flags并搜索“启用 CSS 容器查询”并启用该功能。

让我们潜入。

介绍

在 CSS 中,我们有很多可以用于不同目的的单位。最常用的有pxremem。如果与 CSS 容器查询单元的工作方式接近,那么我会说视口单元。

CSS 视口单位以响应浏览器视口大小(宽度或/和高度)的方式工作。这很好,但我们并不总是想使用与视口大小相关的单位。如果我们想查询容器宽度怎么办?这就是查询单元的用途。

为了更清楚,我想强调视口单位和查询单位之间的区别。考虑下图:

img

在左侧,font-sizerem和控制vw,这将相对于视口宽度。在某些情况下,这可能有效,但可能会导致意外问题,因为它与视口大小有关

查询单位可以用之类的东西打交道时,我们节省精力和时间font-sizepadding以及margin一个组件中。我们可以使用查询单位代替手动增加字体大小。

考虑以下示例。

img

我们有一个卡片组件,它以堆叠样式开始,当容器很大时一直到类似英雄的样式。对于这样的组件,我们可能需要更改以下内容:

  • 缩略图大小
  • 字体大小
  • 元素之间的间距

如果没有 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 {
    字体大小:夹(1rem3qw,2rem);
}

有了这个,我们需要定义font-size唯一一次。如果我们想在视觉上比较它,这是它的外观:

img

如果您熟悉 CSS 视口单位,这对您来说并不陌生。这就像查询容器而不是浏览器的视口一样。整洁,不是吗?

演示

查询单位

现在我们已经了解了查询单元应该解决的问题,让我们获取单元。根据CSS 规范

  • 查询宽度(qw):容器宽度的 1%。例如, 5qw 将解析为容器宽度的 5%。
  • 查询高度(qh):容器高度的1%。例如,5qh 将解析为容器高度的 5%。
  • 查询最小值(qmin):查询宽度qw或查询高度的较小值qh
  • 查询最大值 (qmax):qw或的较大值qh

我们还有另外两个单元:qiandqb它们分别表示 Query Inline 和 Query Block。它们可用于我们有不同书写模式的情况。

用例和示例

卡片组件

除了前面解释的卡片示例之外,我们还可以对堆叠卡片使用查询单元,其中我们希望字体大小基于容器宽度稍大。

img

请注意,字体大小会根据容器大小变大。这对于创建无论放置在哪里都可以使用的堆叠卡片组件非常有用。

演示

基于重要性的变化font-size

当一个元素比另一个元素大时,它更有可能表明它更重要。一个很好的例子是side and main。an 中的标题大小<aside>应小于部分中的标题<main>

img

请注意 中的标题如何<aside>小于 中的标题<main>。由于查询单元,我们可以轻松做到这一点。

首先,我们需要定义<aside><main>作为内联大小的容器。

在旁边,
主要的 {
    容器:内联大小;
}

然后,我们将为部分标题使用查询单元。我们还可以对底部边距使用查询单位。

.section-title {
    字体大小:夹子(1.25rem3qw,2rem);
    margin-bottom: 钳位(0.5rem, 1.5qw, 1rem);
}

演示

生物成分

img

个人简介可以存在于较小的容器中(例如:侧边栏)或显示在移动视口上,或显示在页面标题等大容器中。

我们可以构建一个可以适应其容器宽度的组件。在该示例中,用户头像和字体大小根据其容器宽度而变化。

.bio {
    容器:内联大小;
}

.c-头像{
    --size: calc(60px + 10qw);
    宽度:var(--size, 100px);
    高度:var(--size, 100px);
    margin-bottom: 钳位(0.5rem, 3qmin, 2rem);
}

演示

带计数器的标题

在某些情况下,我们需要在带有文章正文的标题旁边显示一个计数器。这是查询单元的完美用例。

img

.article-body {
    反复位:航向;
}

h2{
    容器:内联大小;
    字体大小:夹子(1.25rem3qw,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);
}

这很酷,但是特定包装器中的组件呢?使用视口单位将不起作用。这就是为什么在这种情况下使用查询单元是一个很好的解决方案。

img

卡片 {
    显示:弹性;
    弹性方向:列;
    差距:计算(0.5rem + 1qmin);
}

当组件切换到水平样式时,间隙会更大一些。

如果我们在没有定义容器的情况下使用查询单元会发生什么?

根据规范

如果没有符合条件的查询容器可用,则对该轴使用小视口尺寸

浏览器将处理查询单位,就好像它们是视口单位一样。考虑以下示例:

h2{
    字体大小:夹子(1.25rem3qw,2rem);
}

如果没有为 定义容器,<h2>浏览器会认为3qw它是3%视口宽度的。这意味着,在不定义容器的情况下使用查询单元可能会导致意外结果。

我希望你喜欢这篇文章。谢谢阅读!