编写响应式样式代码是一个前端开发工程师必备的技能之一,媒体查询是响应式设计的核心,它可以根据设备的特性(如屏幕宽度、分辨率等)来应用不同的样式规则。
然而,随着设计系统的复杂性和组件的重用性需求的增加,媒体查询开始显示出其局限性。这就是容器查询的用武之地。容器查询是一种新的 CSS 提案,它允许样式根据父容器的大小而不是整个视口来变化,从而为组件级别的响应式设计提供了可能。
媒体查询
在没有容器查询之前,我们会使用媒体查询来编写响应式布,媒体查询仅应用于视口大小查询,举个简单的 🌰
/* 默认样式 */
body {
font-size: 16px;
}
/* 当屏幕宽度小于600px时应用以下样式 */
@media (max-width: 600px) {
body {
font-size: 14px;
}
}
/* 当屏幕宽度在600px到900px之间时应用以下样式 */
@media (min-width: 600px) and (max-width: 900px) {
body {
font-size: 18px;
}
}
/* 当屏幕宽度大于900px时应用以下样式 */
@media (min-width: 900px) {
body {
font-size: 20px;
}
}
上述例子,我们会在符合视口大小的条件代码块里编写相关元素的 CSS 样式代码。
容器查询
CSS 容器查询(Container Queries)是 CSS 新的功能,可以让我们基于容器的大小编写样式,而不仅仅是视口(viewport)窗口大小。
新建一个 html,创建一个 post 元素,里面有 card 元素,card 元素有 title。
<div class="post">
<div class="card">
<h2>标题</h2>
</div>
</div>
通过 container-type
创建容器上下文
.post {
container-type: inline-size;
}
然后,使用 @container
规则定义一个容器查询。根据 post
的宽度来进行卡片样式改动。
/* 默认的卡片标题样式 */
.card h2 {
font-size: 18px;
}
/* 如果容器宽度大于1200px */
@container (min-width: 960px) {
.card h2 {
font-size: 36px;
}
}
/* 如果容器宽度大于1200px */
@container (min-width: 1200px) {
.card h2 {
font-size: 48px;
}
}
注意: @container
只能修改子元素样式,不能修改自身样式,例如上述的 post
元素。
container-type
size
:当设置为 size 时,容器查询将基于容器的内联(inline)和块级(block)尺寸。简单说就是宽度和高度都可以作为容器查询。
inline-size
:当设置为 inline-size 时,容器查询仅基于容器的内联尺寸。简单来说就是只有宽度可以作为容器查询。
normal
:当设置为 normal 时,元素不会作为任何基于容器尺寸的查询容器,但它仍然可以作为基于容器样式查询容器。比如下面的容器样式查询例子:
容器样式查询
容器样式查询(Container Style Queries)可以基于容器的样式查询来实现响应式设计。这个功能可以让我们根据容器的样式来应用不同的样式规则。
语法如下:
@container style(<style-feature>),
not style(<style-feature>),
style(<style-feature>) and style(<style-feature>),
style(<style-feature>) or style(<style-feature>) {
/* <stylesheet> */
}
可以举个简单的例子,比如我们给 post
元素设置一个背景颜色,然后根据背景颜色的不同来改变 card
元素的样式。
容器查询的使用场景
既然有了媒体查询,为什么还需要容器查询呢?
虽然媒体查询可以满足大比分场景需求,但是现在对网站响应式设计的要求越来越高,部分场景无法使用媒体查询实现。总结一句话,只要你想基于元素宽度来设置子元素的字体大小或者进行子元素布局,容器查询将会是最好的选择。
兼容性
容器查询毕竟是一个新的特性,少部分主流浏览器支持,如果对兼容性有要求,还是要慎重考虑。