容器查询中的 container 和 @container

特别声明:如果您喜欢小站的内容,可以点击申请会员进行全站阅读。如果您对付费阅读有任何建议或想法,欢迎发送邮件至: airenliao@gmail.com!或添加QQ:874472854(^_^)

从《初探CSS容器查询》一文中我们知道了容器查询是是什么以及它的作用。使用 contain来创建一个包含上下文,同时使用 @container 规则,可以在符合条件下为查询容器的后代单独指定样式规则。简单地说,可以使用 CSS 容器查询,让同一个组件根据其容器的不同尺寸向用户呈现不同的UI效果。该特性目前是 CSS Containment Level 3 中的一个特性,这个功能模块中除了 contain@container 之外,还新增了一个容器属性 container,也可以使用 container@container 结合实现容器查询效果。在这篇文章中,我们就来看看 container@container 是如何工作的,它们可能会有哪些功能!感兴趣的同学,请继续往下阅读!

容器查询的相关背景

CSS 的 媒体查询 引发了一场响应式设计的革命,为开发者提供了一种方法来查询用户代理或设备环境的各个方面,比如视窗的大小或用户偏好来改变 Web 页面的风格。直到现在,媒体查询还做不到让元素的样式能根据一个最近的容器的大小来改变样式网格。也正因此,大家一直期待的容器查询来了。

如果你对用户偏好设置是如何向用户呈现不同样式风格感兴趣,那么可以阅读《CSS媒体查询新特性》和《系统偏好设置的那些事儿》。

CSS 容器查询最大的特点是:

容器查询允许开发者定义任何一个元素为包含上下文,查询容器的后代元素可以根据查询容器的大小或计算样式的变化来改变风格

换句话说,一个查询容器是通过使用容器类型属性(container-typecontainer)指定要能的查询类型来建立的。适用于其后代的样式规则可以通过使用@container条件组规则对其进行查询来设定条件。

例如,我们可以把主内容区域(main)和侧边栏(aside)定义为容器,在主内容区域和侧边栏放置同一组件.card,而且 .card组件会根据其容器的大小,展示不同的布局(放在侧边栏里的.card是垂直布局,放在主内容区域的.card是水平布局):

/* 显式声明查询容器 */
main, aside {
    container: inline-size;
}

.card {
    display: grid;
    grid-template: 'img' auto 'content' auto / 100%;
}

@container (inline-size > 45em) {
    .card {
        grid-template: 'img content' auto / auto 1fr;
    }
}

注意,我们也可以使用 contain 来声明一个查询容器,比如:

main, aside {
    contain: layout inline-size style;
}

详细的可以阅读《初探CSS容器查询》一文。

container@container

container@containerCSS Containment Module Level 3 新增的两个属性,它们看上去非常相似,但他们有着本质的区别:

  • containercontainer-typecontainer-name 的简写属性,用来显式声明某个元素是一个查询容器,并且定义查询容器的类型(可以由container-type指定)和查询容器的名称(由container-name指定)。
  • @container(带有@规则),它类似于条件CSS中的@media@supports规则,是一个条件组规则,其条件是一个容器查询,它是大小(size)和(或)样式(style)查询的布尔组合。只有当其条件为真(true),@container规则块中的样式都会被用户代理运用,否则将被视为无效,被用户代理忽略。

我们先从 container 开始!

定义一个包含性上下文

要使用CSS容器查询特性首先要做的是 定义一个包含性上下文(Containment Context)。这样可以告诉浏览器以后要针对只个容器进行查询,以及具体如何查询该特定的容器。即,在元素上显式使用 container 属性。比如,上面示例代码:

main,aside {
    container: inline-size
}

其实,containercontainer-typecontainer-name 的简写属性,其语法规则:

container: <container-type> [/<container-name>]?

<container-name> 可以被省略,如果该值被省略,它将被重置为其初始值(initial)。如果<container-name>未被省略,则需要使用反斜杠(/)和前面的<container-type> 分隔开来,并且最好是在/前后有一个空格符。

也就是说,我们可以使用container同时定义容器类型和容器名称:

main {
    container: size / layout;
}

.component {
    container: inline-size / card;
}

上面代码等同于:

main {
    container-type: size;
    container-name: layout;
}

.component {
    container-type: inline-size;
    container-name: card;
}

即:

  • 使用container-type指定查询容器类型,比如示例中的inline-size,会告诉浏览器查询容器的内联轴尺寸
  • 使用container-name给查询容器命名,该命名可以用于@container规则中,比如 @container card (inline-size > 45em){}

接下来,花点时间了解一下container-typecontainer-name 的具体使用以及作用。

指定查询容器类型:container-type

container-type 属性对所选元素创建了一个包含性上下文格式(Containment Context),简单地说,就是创建了一个查询容器。允许其后代元素查询其样式、尺寸和布局等各个方面,并作出相应的反应。

该属性可接受的值有:

container-type: none | style || state || [size | inline-size | block-size]

其中none是其初始值。每个值的含义是:

  • size :在容器的块轴(Block Axis)和内联轴(Inline Axis)上建立一个查询容器,用于尺寸查询,即查询容器块轴和内联轴的尺寸(block-sizeinline-size)。对元素应用布局(layout)、样式(style)和尺寸(size)限制
  • inline-size :在容器的内联轴(Inline Axis)上建立一个查询容器,用于内联轴尺寸(inline-size)查询。对元素应用布局(layout)、样式(style)和内联轴尺寸(inline-size)的限制
  • block-size :在容器的块轴(Block Axis)上建立一个查询容器,用于块轴尺寸(block-size)查询。对元素应用布局(layout)、样式(style)和块轴尺寸(block-size)的限制
  • style :建立一个查询容器,用于样式查询
  • state :建立一个查询容器,用于状态查询

比如下面这个示例,开发者可以创建一个查询容器,并且让容器后代元素

剩余80%内容付费后可查看

如需转载,烦请注明出处:https://www.w3cplus.com/css/container-queries-with-container-and-at-container.html

如果文章中有不对之处,烦请各位大神拍正。如果你觉得这篇文章对你有所帮助,打个赏,让我有更大的动力去创作。(^_^)。看完了?还不过瘾?点击向作者提问!

赏杯咖啡,鼓励他创作更多优质内容!
返回顶部