下一代 CSS:@container

Chrome 正在试验 CSS @container 查询器功能,这是由 OddbirdMiriam Suzanne 和一群网络平台开发者支持的 CSS 工做组 Containment Level 3 规范@container 查询器使咱们可以根据父容器的大小来设置元素的样式css

@container API 不稳定,会受到语法变化的影响。若是你想要本身尝试一下,可能会遇到一些错误。请将这些错误报告给相应的浏览器引擎!报告错误的连接以下:html

你能够把这些想象成一个媒体查询(@media),但不是依靠 viewport 来调整样式,而是你的目标元素的父容器会调整这些样式。前端

容器查询将是自 CSS3 以来 Web 样式的最大变化,将会改变咱们对“响应式设计”含义的见解。

viewport 和用户代理再也不是咱们建立响应式布局和 UI 样式的惟一目标。经过容器查询,元素将可以定位本身的父元素并相应地应用本身的样式。这意味着存在于侧边栏、主体或头图中的相同元素可能会根据其可用大小和动态看起来彻底不一样。android

@container 实例

本示例中,我在父级中使用了两张带有如下标记的卡片:ios

<div class="card-container">
    <div class="card">
        <figure> ...</figure>
        <div>
            <div class="meta">
                <h2>...</h2>
                <span class="time">...</span>
            </div>
            <div class="notes">
                <p class="desc">...</p>
                <div class="links">...</div>
            </div>
            <button>...</button>
        </div>
    </div>
</div>
复制代码

而后,我在将查询容器样式的父级(.card-container)上设置 Containment(contain 属性)。我还在 .card-container 的父级上设置了一个相对网格布局,所以它的 inline-size 将根据该网格而改变。这就是我使用 @container 查询的内容:git

.card-container {
  contain: layout inline-size;
  width: 100%;
}
复制代码

如今,我能够查询容器样式来调整样式!这与使用基于宽度的媒体查询设置样式的方式很是类似,当元素小于指定尺寸时使用 max-width 设置样式,当元素大于指定尺寸时使用 min-widthgithub

/* 当父容器宽度小于 850px, 再也不显示 .links 而且减少 .time 字体尺寸 */

@container (max-width: 850px) {
  .links {
    display: none;
  }

  .time {
    font-size: 1.25rem;
  }

  /* ... */
}

/* 当父容器宽度小于 650px 时, 减少 .card 元素之间的网格间距到 1rem */

@container (max-width: 650px) {
  .card {
    gap: 1rem;
  }

  /* ... */
}
复制代码

image.png

容器查询 + 媒体查询

容器查询的最佳功能之一是可以将 微观上的布局宏观上的布局 分开。咱们可使用容器查询设置单个元素的样式,建立细微的微观布局,并使用媒体查询(宏布局)设置整个页面布局的样式。这创造了一个新的控制水平,使界面更具响应性。web

这是另外一个示例。它展现了使用媒体查询进行宏观布局(即日历从单面板到多面板)和微观布局(即日期布局/大小和事件边距/大小移动),以建立一个漂亮的和谐的查询。chrome

image.png

容器查询 + CSS 网格

我我的最喜欢的查看容器查询影响的方法之一是查看它们在网格中的工做方式。如下面的植物贸易 UI 为例:后端

image.png

本网站根本没有使用媒体查询。相反,咱们只使用容器查询和 CSS 网格来在不一样的视图中显示购物卡组件。

在产品网格中,布局使用了 grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); 标记建立。这将建立一个布局,告诉卡片占用可用的小数空间,直到它们的大小达到 230px,而后下一格切换到下一行。你能够在 1linelayouts.com 上查看更多网格技巧。

而后,咱们有一个容器查询,当卡片宽度小于 350px 时,它会将卡片样式设置为采用垂直块布局,并经过应用 display: flex(默认状况下具备内联流)转换为水平内联布局。

@container (min-width: 350px) {
  .product-container {
    padding: 0.5rem 0 0;
    display: flex;
  }

  /* ... */
}
复制代码

这意味着每张卡片拥有本身的响应式样式。这是咱们使用产品网格建立宏观布局以及使用产品卡片建立微观布局的另外一个示例,酷毙了!

用法

为了使用@container,首先须要建立一个具备 Containment 的父元素。为此,咱们须要在父级上设置 contain: layout inline-size。由于咱们目前只能将容器查询应用于内联轴,因此咱们只可使用 inline-size。这也能够防止咱们的布局在块方向上中断。

设置 contain: layout inline-size 会建立一个新的 Containment 块 和新的块格式上下文,让浏览器将其与布局的其他部分分开,如今咱们就可使用容器查询了!

限制

目前,您不能使用基于高度的容器查询,只能使用块轴方向上的查询。为了让网格子元素与 @container 一块儿工做,咱们须要添加一个容器元素。尽管如此,添加容器仍可以让咱们得到所需的效果。

试试看

您如今能够在 Chromium 中试验 @container 属性,方法是导航到:Chrome Canary 中的 chrome://flags 页面并打开 #experimental-container-queries 标志。

image.png

若是发现译文存在错误或其余须要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可得到相应奖励积分。文章开头的 本文永久连接 即为本文在 GitHub 上的 MarkDown 连接。


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOS前端后端区块链产品设计人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏

相关文章
相关标签/搜索