引言
过去十年,响应式设计的核心工具是 @media 查询。但媒体查询有一个根本缺陷:它只能感知视口的大小,而不是组件所在容器的大小。当你把一个组件放在主内容区和侧边栏时,它的行为应该是不同的——媒体查询无法优雅地处理这种情况。现代 CSS 引入了容器查询、流体函数和全新的选择器,让响应式设计进入了新阶段。
一、Container Queries:组件级响应式
容器查询(@container)允许你根据父容器的大小来设置样式,而不是视口。
1.1 基本用法
/* 声明一个容器 */
.card-wrapper {
container-type: inline-size;
container-name: card;
}
/* 根据容器宽度调整样式 */
@container card (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 200px 1fr;
gap: 1rem;
}
}
@container card (max-width: 399px) {
.card {
display: flex;
flex-direction: column;
}
}
1.2 容器查询长度单位
容器查询带来了全新的相对单位:cqw(容器宽度的 1%)、cqh(容器高度的 1%)、cqi(容器内联尺寸的 1%)、cqb(容器块尺寸的 1%)、cqmin 和 cqmax。
.card-title {
font-size: clamp(1rem, 5cqi, 2rem);
}
二、clamp():流体排版
clamp() 函数接收三个参数:最小值、理想值、最大值。它让字体大小在最小值和最大值之间平滑缩放。
/* 传统方式:需要多个媒体查询 */
h1 { font-size: 1.5rem; }
@media (min-width: 768px) { h1 { font-size: 2.5rem; } }
@media (min-width: 1024px) { h1 { font-size: 3.5rem; } }
/* 现代方式:一行搞定 */
h1 {
font-size: clamp(1.5rem, 4vw + 0.5rem, 3.5rem);
}
实用流体排版示例
:root {
--text-sm: clamp(0.875rem, 0.8rem + 0.25vw, 1rem);
--text-base: clamp(1rem, 0.9rem + 0.35vw, 1.25rem);
--text-lg: clamp(1.25rem, 1rem + 0.5vw, 1.75rem);
--text-xl: clamp(1.5rem, 1.2rem + 0.8vw, 2.5rem);
--text-2xl: clamp(2rem, 1.5rem + 1.2vw, 3.5rem);
}
三、CSS 嵌套
CSS 嵌套语法(CSS Nesting)终于原生支持了,不再需要 Sass/Less 的预处理器。
/* 原生 CSS 嵌套 */
.card {
background: white;
border-radius: 12px;
& .title {
font-size: 1.25rem;
font-weight: 700;
}
& .body {
color: #666;
line-height: 1.6;
}
&:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
@container (min-width: 500px) {
display: grid;
grid-template-columns: 1fr 1fr;
}
}
四、:has() 选择器:父级感知
:has() 被称为"父选择器",它允许你根据子元素的状态来设置父元素的样式。
/* 当卡片包含图片时,使用两栏布局 */
.card:has(img) {
grid-template-columns: 200px 1fr;
}
/* 当表单包含错误信息时,给输入框加红框 */
.form-group:has(input:invalid) {
border-color: #ef4444;
}
/* 侧边栏有空状态时,调整主内容宽度 */
main:has(aside:empty) {
max-width: 800px;
margin-inline: auto;
}
五、视口单位新成员
传统的 vh 单位在移动端有严重问题:浏览器地址栏的显示/隐藏会导致 100vh 的实际高度变化。CSS 引入了新的视口单位来解决这个问题:
- svh / svw:小视口(地址栏展开时)
- lvh / lvw:大视口(地址栏收起时)
- dvh / dvw:动态视口(自动适应当前状态)
/* 全屏 Hero 区域,使用 dvh 避免被地址栏遮挡 */
.hero {
min-height: 100dvh;
}
/* 固定底栏,使用 svh 确保始终可见 */
.bottom-bar {
position: fixed;
bottom: 0;
height: max(60px, 10svh);
}
六、无媒体查询的响应式模式
利用以上技术,很多常见的响应式布局可以完全不用媒体查询:
/* 自动响应式网格:不用任何媒体查询 */
.auto-grid {
display: grid;
grid-template-columns: repeat(
auto-fit,
minmax(min(100%, 300px), 1fr)
);
gap: 1.5rem;
}
/* 侧边栏布局:自动折叠 */
.with-sidebar {
display: flex;
flex-wrap: wrap;
gap: 2rem;
}
.with-sidebar > main {
flex: 1 1 500px;
}
.with-sidebar > aside {
flex: 0 1 300px;
}
总结
容器查询让我们从"视口响应式"进化到"组件响应式";clamp() 让排版从阶梯式变成流体式;CSS 嵌套降低了预处理器的依赖;:has() 打破了 CSS 只能向下选择的限制。这些特性组合在一起,让响应式设计的代码更少、更清晰、更健壮。浏览器兼容性方面,2026 年这些特性已经获得了所有主流浏览器的支持,是时候在生产环境中全面采用了。
返回文章列表
标签:CSS响应式设计Container Queries