容器查询是CSS中最常用的新功能之一。我最近有机会与他们一起玩一些旋转的新语法。
我想出了这款书店的演示。每本书都可以拖动,可以移动到三个部分中的一个,具有不同的可用空间。根据放置的位置,不同的风格将应用于书籍。 CODEPEN上的完整源代码。这是它看起来的看法:
此演示目前仅在Chrome Canary工作。下载最新版本,然后在Chrome下启用容器查询://标志以查看它们。
这些书籍中的每一个都是自定义元素或“Web组件”。它们每个都包含一个封面图像,标题和作者。在标记中,他们看起来像这样:
然后,它将应用于定义组件的内部阴影DOM的模板。 < slot>将通过我们传递的实际内容替换。
当我们对此应用一些内部样式时,魔法就会发生。内部内部的一切< style>标签将被选中到组件 - 而且由于样式无法泄漏出暗影DOM,而且我们不能(轻松地)从外部中的内容中的内容,我们有真正的组件封装。
容器查询是组件驱动设计中的最后几个丢失的拼图之一。它们使我们能够提供组件内在风格,这意味着它们可以使自己适应它们的任何周围环境。
包含的新关键属性包含 - 它允许我们将元素定义为容器以比较容器查询。 Layout的值表示元素外部的内部不影响其内部布局,反之亦然。
这允许浏览器优化创建页面布局所需的计算次数。通过向规则添加内联大小,我们还告诉浏览器响应容器宽度的变化。
/ *使用Web组件作为布局容器* /:host {display:block;包含:布局内联尺寸; } ......
在书店演示中,我创建了三个依赖于组件:主机的宽度的变体(它转换为< book-compent>本身)。我省略了一些在这里的简洁性的样式,但这部分是我们定义多列或3D书样式的地方。
/ *小变种:简单封面+标题* / @container(max-width:199px){.book {padding:0; }} / *介质变量:多列,带作者* / @container(min-width:200px)和(max-width:399px){.book {display:grid;网格模板列:1FR 1FR;差距:1REM; } / *大型变体:3D透视图* / @container(min-width:400px){.book {位置:相对;变换风格:Preserve-3D;变换:旋转(-25deg); }}
通过添加Dragula.js来启用拖放功能,我们可以移动各个组件。一旦它们移动到DOM中的不同部分,它就会重新计算其内部样式以匹配新环境,并且应用相应的CSS块。魔法!
现在,我们可以通过使用级联本身来实现类似的效果。例如,我们可以将3D样式应用于所有.books .stage。但这会有一些问题:
它不会响应 - 如果.stage曾经太狭窄了,它会破裂
在CSS中,从“内容”组件中分开“布局”,这通常是一个好主意,并让每个人处理自己的特定责任领域。我喜欢将日本的Bento盒子视为一个隐喻:一个容器分为可以充满任何东西的具体部分。
它是一个分为三个部分的网格,中间包含嵌套的灵活网格本身。
/ *主布局部分* / .stage,.content,.cart {填充:var(--spacing); } / *嵌套子网格* / .itemlist {显示:网格;网格模板列:重复(自动填充,minmax(200px,1fr));差距:var(--spacing); } / *桌面布局* / @media(min-width:1024px){.layout {display:grid;身高:100VH;网格模板列:480px 1fr 130px; }}
布局的部分仅涉及盒子的对齐和尺寸。除了为他们提供一定的空间以外,他们对他们的孩子没有任何影响。就像一个Bento盒子一样,它不在乎我们投入的东西,因此我们可以轻松重新使用完全不同产品的布局。它是满足的无话可标。
这就是为什么容器查询与CSS网格相吻合。 Grid定义了从外部的灵活布局,而容器查询适应其内部的内容,以实现可用空间的最佳大小。
容器查询为我们带来了一个更接近“内在布局”的一步,以及真正独立,组件驱动的设计的未来。令人兴奋的东西!