使用 CSS Container Queries 解决组件响应式布局痛点
问题
大家都很熟悉使用 Media Query 来控制 CSS 样式,保证页面在不同的显示设备上都有合理的布局。
但是在组件化开发中, Media Query 就显得力不从心了:
-
Media Query 关注的是整个 Viewport 的状态
-
组件往往被复用于多个页面,页面布局各异,组件父元素的布局尺寸也不同,很难根据 Media Query 的结果有效控制组件内部的布局
对组件而言,本质上只关注组件父容器的尺寸,如果能根据组件所在的容器的尺寸做类似 Media Query的适配,那么这个问题就可以完美解决。
实践中常通过 JavaScript 介入来完成此类需求,非常麻烦,同时也导致了不必要的耦合。
不过这都是过去式了, CSS Containment Module Level 3 就带来了此能力,被称为 CSS Container Queries
浏览器兼容性
Chrome 和 Safari 实装不久
实践
Container Queries 的使用也很简单
-
父元素要声明 container-type,来标识其子元素属于一个 containment context。
-
子元素可使用 @container 语法来根据父元素的特征匹配 CSS 规则
先搭建一个普通的页面
<html>
<head>
<style>
body {
text-align: center;
font-size: 20px;
color: #fff;
}
.container {
container-type: inline-size;
border: 2px solid red;
width: 50vw;
padding: 10px;
}
.my-component {
display: grid;
grid-template-columns: repeat(3, 1fr);
row-gap: 20px;
}
.component-content {
width: 200px;
background: blue;
height: 200px;
}
</style>
</head>
<body>
<div class="container">
<div class="my-component">
<div class="component-content">1</div>
<div class="component-content">2</div>
<div class="component-content">3</div>
<div class="component-content">4</div>
<div class="component-content">5</div>
<div class="component-content">6</div>
<div class="component-content">7</div>
<div class="component-content">8</div>
</div>
</div>
</body>
</html>
container 模拟组件外层容器,声明了 container-type 为 inline-size,即在 inline 方向上提供尺寸 query 能力。其余取值请参考 container-type
同时container支持声明 container-name,来实现更精确的匹配 container-name
接下来我们添加关键的 @container 规则
@container (max-width: 600px) {
.my-component {
background: yellow;
grid-template-columns: repeat(2, 1fr);
}
}
@container (max-width: 400px) {
.my-component {
background: pink;
grid-template-columns: 1fr;
}
}
Container Query 的语法接近 Media Query
除了对尺寸做 query 外,还可以对父元素的其它属性做 query
@container style(color: blue) {
/* <stylesheet> */
}
可以实现与父元素在样式层面的自适应。
转载自:https://juejin.cn/post/7188025443100917820