当我说 “即将到来” 时,我的意思是它还没有被任何浏览器支持,而且规格也没有最终确定(在写这篇文章的时候)。也就是说,它在下一个版本的Chrome中是一个标志,而且我毫不怀疑它很快就会出现在所有 “现代” 浏览器中。
什么是容器查询
容器查询类似于媒体查询,但有一个主要的,也是关键的区别。媒体查询可以查询整个文档,并根据这些查询来修改内容。例如,如果文档超过1025px,你可能想把内容移到两列而不是一列。这将看起来像这样。
main.content { column-count: 1; column-gap: 2em; } @media screen and (min-width: 1025px) { main.content { column-count: 2; } }
容器查询遵循同样的原则,但不是查询整个文档,而是查询容器。
他们是如何帮助开发者的
想象一下下面的情况;你有一个联系卡,你想在你的网站上到处显示。在一些地方,它在主要内容中,但在其他地方,你决定将它显示在一个旁侧。在同一个媒体查询中,旁白可能是250px,但主要部分可能是700px,导致卡片需要看起来不同。解决这个问题很简单,你需要用不同的媒体查询为卡片设置不同的类,但还有一个更好的方法…… 容器查询!
如何使用容器查询
要使用容器查询,我们必须告诉容器(我们想要应用查询的元素的父级)我们关心它的尺寸,我们用新的 contain 属性来做。
- none –表示该元素以正常方式呈现,没有应用任何包含规则。
- strict –表示除样式外的所有包含规则都应用于该元素。这等同于 contain: size layout paint。
- content –表示除了size和style之外的所有包含规则都应用于该元素。这等同于包含:layout paint。
- size –表示该元素可以被调整大小,而不需要检查其后代的大小。
- layout –表示元素外部的任何东西都不能影响其内部布局,反之亦然。
- style – 表示对于那些可以对不止一个元素和它的子元素产生影响的属性,这些影响不会转移到包含元素。请注意,这个值在规范中被标记为 “at-risk”,可能不会在任何地方被支持。
- paint –表示该元素的后代不会显示在其边界之外。如果包含的盒子在屏幕外,浏览器不需要画出其包含的元素–这些元素也必须在屏幕外,因为它们完全被该盒子所包含。如果一个后代超出了包含元素的边界,那么这个后裔将被剪裁到包含元素的边界框中。
目前Mozilla上的文档有点缺失,这很罕见。我们想使用
当我们使用媒体查询时,大多数时候我们关心的是可用宽度(或
inline-size )。
实践例子
让我们以前面的联系卡为例,想出一些代码来描述它。
<div> <main> <div> <img src="profile.png" alt="profile" /> <div> <h1>Both Names</h1> <p>Some info about me</p> </div> </div> </main> <aside> <div> <img src="profile.png" alt="profile" /> <div> <h1>Both Names</h1> <p>Some info about me</p> </div> </div> </aside> </div>
这个HTML是相当简单的,但我认为它表达了一个观点,我们有一个联系卡,它在两个地方,有可能有极大的不同宽度。
/* Just some simple css to get it started */ .site { display: flex; max-width: 800px; margin: 0 auto; } main.content { width: 60%; background: #ccc; } aside.side-panel { width: 40%; background: tomato; } /* Real css starts here */ main.content, aside.side-panel { contain: layout inline-size; } .contact-card { display: flex; flex-direction: column; align-items: center; width: 200px; background-color: white; padding: 2em; box-sizing: border-box; border-radius: 2px; margin: 1em; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2), 0 1px 1px rgba(0, 0, 0, 0.4) } .contact-card__profile-image { height: 50px; width: 50px; border-radius: 50px; border: 1px solid black; } .contact-card__profile-information { margin-left: 0.5em; } .contact-card__profile-information h1 { text-align: center; margin: 0; font-size: 1.2em; } .contact-card__profile-information p { text-align: center; margin: 0.5em 0 0 0; } @container (min-width: 450px) { .contact-card { width: 300px; flex-direction: row; align-items: flex-start; } .contact-card__profile-information h1 { text-align: left; } .contact-card__profile-information p { text-align: left; } }
在这个CSS中,我们为
下面是代码的呈现方式(希望有一天我们能在更多的浏览器中试用)。这里是代码,如果在实际工作中,jsfiddle。
影响规范化
正如我在一开始所说的,规范还没有最终确定,如果你想看看人们的建议,或者你想自己提出建议,现在还有时间去做。请到git issues板上看一看。
小结
我对此非常兴奋,我主要是用React工作,我真的很期待组件能够根据其父级的大小来改变。