最近在 Chrome Canary 中支持了一项新的 CSS 语法:Container Queries
,相比 Media Queries
有了更丰富的使用场景。
Chrome Canary: 开发者专用的每日构建版,站上网络科技最前沿(注意:Canary 版可能还不稳定)。
我们经常用枚举查询来实现响应式页面:
1
| @media screen and (min-width: 750px) and (max-width: 1200px) { ... }
|
比如现在要实现这样一个效果:
我们有一张卡片(Card),Card 的宽度能够自适应,且 Card 在屏幕宽度足够的时候,Title 与 Description 在同一行;在屏幕宽度不够的时候(间接导致卡片宽度不够),Title 能够与 Description 呈上下结构,以达到卡片布局的响应式。
即在卡片空间足够时,是这样的效果:
在卡片空间不够时,是这样的:
为了要实现这样的自适应效果,我们可能会这样写:
1 2 3 4 5 6 7 8
| <div class="body"> <div class="content"> <div class="card"> <div class="card-title">Card Title</div> <div class="card-desc">Card Description</div> </div> </div> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| .body { width: 100%; height: 100%; position: absolute; left: 0; top: 0; display: flex; }
.content { position: relative; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; }
.card { width: 50%; height: 200px; border-radius: 4px; background-color: #1d1d1d; color: white; display: flex; align-items: center; justify-content: center; }
.card-title { font-size: 18px; font-weight: 700; margin-right: 8px; }
.card-desc { opacity: .8; }
@media screen and (max-width: 750px) { .card { flex-direction: column; } }
|
拉伸屏幕看了下效果,计划通。
这种做法能处理大部分屏幕适配问题,但响应式布局有时并不只依赖屏宽的变化,比如在上面的基础上,我们加入一个可展开收起的侧导,并希望卡片能够继续做到响应式:即在侧导展开时,能够以上下结构呈现内容;而在侧导收起时(空间更大了),卡片能够以左右结构呈现内容。
有侧导:
无侧导:
演示 Demo
当我们想再次去写 media 查询的时候,发现事情不太对…
侧导展开收起的时候,屏宽并没有变化呀!这时 media 查询就受到了限制,这时你发现,更好的响应式方案,不应该只针对屏幕宽度去做枚举,而是要去对容器宽度去做枚举,这时 Container Queries 就诞生了。
Container Queries
还是刚才的卡片例子,如果要用容器查询,该怎么实现呢?
两个注意点:
- 实验前需要在 Chrome Canary 中输入 chrome://flags/#enable-container-queries 找到容器查询的设置,并将其置为 Enabled 后才可生效
- 在使用 @container 时,父容器需要指定 contain 属性以开启 container 查询,如:contain: layout inline-size;
样例代码:
1 2 3 4 5 6 7 8 9
| <div class="body"> <div class="sidebar">Foldable Sidebar</div> <div class="content"> <div class="card"> <div class="card-title">Card Title</div> <div class="card-desc">Card Description</div> </div> </div> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| .body { width: 100%; height: 100%; position: absolute; left: 0; top: 0; display: flex; }
.sidebar { position: relative; width: 200px; height: 100%; background: #2d2d2d; color: white; display: flex; justify-content: center; align-items: center; resize: horizontal; overflow: auto; }
.content { position: relative; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; contain: layout inline-size; }
.card { width: 50%; height: 200px; border-radius: 4px; background-color: #1d1d1d; color: white; display: flex; align-items: center; justify-content: center; }
.card-title { font-size: 18px; font-weight: 700; margin-right: 8px; }
.card-desc { opacity: .8; }
@container (max-width: 600px) { .card { flex-direction: column; } }
|
效果如图(为了演示方便我把侧导的展开收起改为了可拖拽伸缩):
演示 Demo
更多内容可阅读:Say Hello To CSS Container Queries
Polyfill
cqfill
Comments