序言
书接上文,《CSS Wrapped 2025》一文共分为三个核心章节,分别是可定制的组件(Customizable Components)、 下一代交互(Next-gen Interactions)、 优化的人体工程学(Optimized ergonomics)。本文快速梳理一下第二部分,快速带你了解新特性及特性背后的一些知识。
一、容器的滚动状态查询 (Scroll-state queries)
一句话的解释
滚动状态查询是查询容器是否可滚动,吸附,卡住的状态
前端开发大都熟悉媒体查询(Media Queries)了,比如响应式布局。除了查询设备的尺寸,它还能查询:屏幕的比例,旋转方向,是否高分屏,用户偏好(深浅色模式,是否减少动画),设备类型等等。一次媒体查询匹配,就生成一个媒体查询块,其中的CSS规则仅在匹配时生效。
@media (max-width:600px){
// 小屏幕下的CSS规则
}
@media (600px < width < 768px){ /* 范围语法,仅兼容chrome142+ */
// pad屏幕下的CSS规则
}
本节全面介绍容器查询(Container Queries),它是根据父元素DOM的尺寸特性或其它特性进行匹配,让相应的容器查询块内的CSS规则生效。媒体查询只能感知固定的设备特征,而容器查询可以感知某个父级元素的特征,它的好处不用多介绍,大家也能体会到。
容器查询首先要使用container-type指定容器的元素,之后就可以使用@container +查询条件去开发当前条件下要应用的CSS样式了。接下来全面介绍一下所有容器查询语法:
1、尺寸查询
上篇文章中提到container-type,它就是用来开启容器查询, 尺寸查询示例
- normal: 元素不支持任何查询
- size: 支持 inline 和 block 元素的尺寸的高度和宽度查询
- inline-size: 仅支持 inline 元素的尺寸的宽度查询------以上兼容chrome 105+, ff110+
- scroll-state: 支持滚状态等查询------------------------兼容chrome 133+, 但ff,safari均不支持
- anchored: 查询锚点定位的状态------------------------ 兼容chrome 143+, 但ff,safari均不支持
container-name: 给查询容器的元素起一个标识名字。这样可以更精确的应用容器查询规则。 这2个属性可以用 container一个属性来代替,见下面示例。
.common-wrapper {
container-type: inline-size;
}
.card {
container-name: --card-queryable;
container-type: inline-size;
/* 上面2行等效于下面一行 */
container: --card-queryable / inline-size;
}
@container (max-width:600px){ /** 应用于所有container query */}
@container --card-queryable (max-width:600px){/** 仅应用于 --card-queryable 容器 */}
container-type 尽量不要使用 size, 只使用inline-size即可。 使用size查询,容器默认会应用:会造成容器丢失高度,必须要明确width,height才可以。 而需要查询高度的场景比较罕见。
2、滚动容器的状态查询
给容器元素添加 container-type: scroll-state; 后,它就支持滚动特性的查询了,支持以下3类特性:
-
卡住状态(Stuck state): 一个
position:sticky的容器被它的边界固定时的状态查询。支持stuck:top, stuck:bottom, stuck:left, stuck:right查询值。 -
吸附状态(Snapped state): 。在一个
Scroll Snap容器中,一个子项被捕获时(即处于视口中央或对齐点)的状态查询。支持snapped:inlined, snapped:block, snappped:both查询值。 -
可滚动状态(Scrollable state): 检测容器在某个方向是否可以继续滚动。支持
scrollable:top, scrollable:bottom, scrollable:left, scrollable:right查询值。
详情见滚动状态查询示例, 体会一下各种滚动查询的能力。
3、锚点定位的状态查询
上篇文章讲了 container-type:anchored的用法,用于让popover层感知到自己有没有处于翻转(fallback)状态。详见上篇的示例
它目前仅支持查询 fallback 状态,用法如下:
.tooltip{
position-try-fallbacks: --bottom-position;
....
}
/* 处于fallback状态 */
@container anchored(fallback:--bottom-position){ }
/* 无任何fallback状态 */
@container anchored(fallback:none){ }
总结
容器查询是非常有用的技术,其中 inline-size 查询既有大量应用场景,也有广泛的浏览器支持了,我们可以放心使用了。同时希望firefox,safari能在另外2个特性上尽早的追上标准,因为你们明明都支持Scroll Snap和Anchor Positioning的大特性了,何必遗漏这小小的细节点呢。
二、树计数函数(Tree Counting functions)
一句话的解释
元素能感知它在兄弟之间的序号了完整示例
之前为实现多个子元素具有动态宽度,或不同的动画延时时间,我们可能会在子元素上藏一个私有的css变量,类似: --index: 1, --index:2 这样。然后使用 calc 函数 来动态计算一个宽度或延时的时间。
- sibling-index() : 该css函数返回元素在兄弟之间的序号,从1开始计数。
- sibling-count(): 该css函数返回子元素的总数。
传统的计数函数 counter()是返回某个计数器的当前值的字符串,通常用在 content中,兼容IE, chrome,ff等所有浏览器。由于 counter() 是返回字符串,无法使用在 calc()中进行计算,此次引入的sibling- 函数正是弥补该处不足。
li {
/* 创建一个阶梯延时 */
transition: opacity 0.25s ease, translate 0.25s ease;
transition-delay: calc(0.1s * (sibling-index() - 1));
@starting-style {
opacity: 0;
translate: 1em 0;
}
}
兼容性
支持chrome138+ ,safari 26.2, 但ff不支持。建议回退使用css变量来
scrollIntoView() container
一句话的解释
让scrollIntoView()能够指定需要滚动的容器元素完整示例
slide.scrollIntoView({ container: 'nearest', behavior: 'smooth' });
兼容性
支持chrome140+ 但ff,safari不支持。
嵌套的视图过渡组(Nested View Transition Groups)
一句话的解释
在视图过渡时,能保留3D和 裁剪效果
视图过渡(View Transition)是chrome 111 即支持的转场动画, ff144+, safari 18+ 也同步支持了。可以从下面博客了解更详细的细节: 使用嵌套的视图过渡组来防止视图过渡中的剪裁问题
兼容性
支持chrome140+ 但ff,safari不支持。
moveBefore(DOM State-Preserving Move)
一句话的解释
保活状态的去移动iframe,video 等元素
const iframe = document.querySelector('iframe'); document.body.moveBefore(newSibling);
const $newSibling = getRandomElementInBody();
const $iframe = document.querySelector('iframe');
document.body.moveBefore($iframe, $newSibling);
兼容性
支持chrome133+ ,ff144+,但 safari不支持。