现在有一个 Polyfill 用于 容器查询,其行为就像 Polyfill 应该的那样完美
- 当您检测到浏览器不支持容器查询时,您可以有条件地加载它。
- 您可以像往常一样编写 CSS,包括符合当前规范的容器查询语法代码。
- 它只是工作。
拥有一个如此易于使用的容器查询 Polyfill 真是太棒了,而且它来自 Chrome 本身,它是早期测试实现的先行者。 看起来 Surma 将其整合在一起——感谢 Surma!
Jonathan Neal 开发了一个名为 cqfill 的容器查询 Polyfill,它早于此。 我不确定它是否正式弃用,但它需要额外的非规范 CSS 来工作以及 PostCSS 处理,因此我将其视为弃用,有利于这个较新的 Polyfill。
加载 Polyfill 就像这样
// Support Test
const supportsContainerQueries = "container" in document.documentElement.style;
// Conditional Import
if (!supportsContainerQueries) {
import("https://cdn.skypack.dev/container-query-polyfill");
}
您可以从 npm 拉取它或用作 <script>
,但这种方式对我来说似乎最适合保持轻便和简单。
然后,您可以自由地在 CSS 中使用容器查询的语法。 假设您在 HTML 中有一个天气小部件。 您将需要一个额外的包装器元素来进行查询。 这只是规则:您不能查询您要设置样式的元素。
<div class="weather-wrap">
<dl class="weather">
<div>
<dt>Sunday</dt>
<dd>
<b>26°</b> 7°
</dd>
</div>
<div>
<dt>Monday</dt>
<dd>
<b>34°</b> 11°
</dd>
</div>
<!-- etc -->
</dl>
</div>
包装器被实例化为一个容器
.weather-wrap {
container: inline-size / weather-wrapper;
/* Shorthand for: */
/* container-type: inline-size; */
/* container-name: weather-wrapper; */
/* For quick testing, do this to get a resize handle on desktop: */
/* resize: both; */
/* overflow: hidden; */
}
然后,您编写该组件的任何全局样式,以及容器查询范围内的样式
.weather {
display: flex;
}
@container weather-wrapper size(max-width: 700px) {
.weather {
flex-direction: column;
}
}
容器查询 Polyfill 示例
这是使用实际天气小部件的容器查询 Polyfill 的更详细的演示
我第一次在 Bramus 的博客上 看到这个,他用这个容器查询 Polyfill 做了一个经典的卡片演示。 上下滚动。 您将在顶部看到一行熊卡片(如果您的浏览器窗口足够宽),然后在下面看到以不同布局位置排列的类似熊卡片,这些卡片会根据容器查询更改为更漂亮的格式。
容器查询 Polyfill 浏览器支持
Polyfill 文档 中说
Polyfill 依赖于
ResizeObserver
、MutationObserver
和:is()
。 因此,它应该可以在所有现代浏览器中使用,特别是 Chrome/Edge 88+、Firefox 78+ 和 Safari 14+。
这些文档中还涵盖了各种其他细微的注意事项,包括它支持和不支持的内容。 对我来说,这似乎主要是一些小众的东西——主要的/典型的用例都涵盖了。
改变游戏规则?
当我写这篇文章的时候,我们已经看到了 Chrome 对容器查询的幕后支持,它现在已经成为一项正式的规范草案
今天的 CSSWG 通话
— Mia,on Bass (@TerribleMia) 2021 年 12 月 8 日
🥳 容器级别 3(容器查询)的第一个公开工作草案
🥳 级联级别 6(范围)的 FPWD
这意味着这些提案已升级为正式的正在进行中的规范。 在浏览器发布之前还有很多工作要做,但这是一个很大的进步!
这非常令人兴奋,并且强烈表明浏览器实际上将与容器查询一起发布,即使语法在过程中略有改变(它已经改变了很多次)。 但是,当然,我们不知道容器查询何时以及是否会发布——以及当跨越那个神奇的门槛时,我们也不知道在哪里可以放心地使用它们,就像我们现在可以放心地使用 flexbox 和网格一样。
那个“只需使用它”的日期可能还比较远,但是,如果您喜欢 Polyfill 的想法并小心使用渐进增强,我认为使用容器查询的日期可能就在现在——ish。 对我来说,看起来 Polyfill 脚本的传输大小约为 2.8kb,对于如此重要的东西来说,这个大小非常小。
我怀疑这个 Polyfill 将在今年内迅速提高容器查询的使用率。
FOUC?
您的样式只有在 JavaScript 文件下载并执行后才能正确应用,这会使网站进入无样式内容闪烁 (FOUC) 区域。 这里有一个视频记录,我可以在自己的演示中看到它。 我不确定是否有办法解决这个问题,除非有意延迟渲染,这通常被认为是不可取的。 与加载网络字体类似,FOUC 可能是一件好事,因为它意味着您的内容永远不会被隐藏或延迟,即使偏移不理想。 一旦浏览器支持到位并且 Polyfill 停止加载,FOUC 应该会消失。
享受使用容器查询 Polyfill 的乐趣! 我很想看到更多它的演示。

这太令人兴奋了! 特别是如果我们终于可以根据图像容器的大小而不是窗口宽度来加载图像大小。
https://github.com/w3c/csswg-drafts/issues/5889
我对这个很激动。 也就是说,为什么您要“桌面优先”地设置样式? 我们不是应该默认情况下为“移动设备”设置样式,然后进行更大的处理吗?
通常,我不太关心您使用哪种“方向”进行处理,但在这种情况下,我认为您是对的。 由于存在 FOUC,我认为最好使用在较小空间中有效的默认样式构建组件,然后在可能的情况下,让它增强以在较大空间中重新设置样式。
该演示就是一个很好的例子,其中在一周中的所有天都在水平行中排列的默认设置在 Polyfill 启动之前,在较小的空间中很难容纳。 所以,是的,我完全应该以另一种方式处理它。
我对这个很兴奋。 我正在尝试将其添加到 React 项目中——我实际上很擅长编写 React,但捆绑不是那么擅长。 您如何真正将这个添加到 React 项目中?
嗨,我遇到一个问题。 我已经完成了所有设置,我想使用 @container。 但是,Chrome 似乎没有检测到查询。 我检查了容器 div 的 css,发现“container: inline-size”被检测到了,但我尝试了增加和减少浏览器的大小,什么也没有发生。
如果您能给我一个解决方案,我将不胜感激。
我建议 cq-prolyfill 是比 CQfill 更好的解决方案,因为它为所有 CSS 属性提供了容器查询:宽度、高度、颜色、文本对齐方式等。如果您不想使用预处理器,它可以使用数据属性。 使用 MutationObserver 以及其他 DOM 事件。 [https://ausi.github.io/cq-prolyfill/demo/]
这似乎在 Firefox 中不起作用,而那里最需要它。 我在 Firefox 和 Chrome 上看到您的示例的不同结果。(Firefox 106.0.5 (64 位) 在 MacOS 12.6.1 上)