容器查询实战案例:响应式卡片布局
通过卡片组件案例,演示容器查询从基础到完整的响应式设计实现。
案例场景
同一卡片组件在不同宽度容器中自适应:
- 紧凑容器:纵向堆叠布局
- 标准容器:图文并排布局
- 宽松容器:多列展示布局
基础实现
HTML结构
HTML
<div class="card-container">
<article class="card">
<div class="card__media">
<img class="card__image" src="photo.jpg" alt="">
</div>
<div class="card__content">
<h3 class="card__title">文章标题</h3>
<p class="card__excerpt">文章摘要内容...</p>
<div class="card__meta">
<span class="card__author">作者名</span>
<span class="card__date">2026-05-16</span>
</div>
<button class="card__action">阅读更多</button>
</div>
</article>
</div>
基础样式
CSS
/* 声明容器 */
.card-container {
container-type: inline-size;
container-name: card;
}
/* 卡片基础样式 */
.card {
background: white;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.card__image {
width: 100%;
height: auto;
object-fit: cover;
}
.card__title {
font-size: 18px;
font-weight: 600;
margin: 0;
}
.card__excerpt {
font-size: 14px;
color: #666;
margin: 8px 0;
}
.card__meta {
display: flex;
gap: 12px;
font-size: 12px;
color: #999;
}
.card__action {
margin-top: 12px;
padding: 8px 16px;
background: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
响应式布局切换
紧凑布局(< 300px)
CSS
/* 默认紧凑布局 */
.card {
display: block;
}
.card__media {
/* 图片全宽 */
}
.card__content {
padding: 12px;
}
.card__title {
font-size: 16px;
}
.card__action {
width: 100%;
}
标准布局(300px - 500px)
CSS
@container card (min-width: 300px) {
.card {
display: flex;
gap: 16px;
}
.card__media {
flex-shrink: 0;
width: 120px;
}
.card__image {
width: 120px;
height: 120px;
object-fit: cover;
}
.card__content {
padding: 16px;
flex: 1;
}
.card__title {
font-size: 18px;
}
.card__action {
width: auto;
}
}
宽松布局(> 500px)
CSS
@container card (min-width: 500px) {
.card {
flex-direction: row;
gap: 24px;
}
.card__media {
width: 200px;
}
.card__image {
width: 200px;
height: 150px;
}
.card__content {
padding: 24px;
display: flex;
flex-direction: column;
}
.card__title {
font-size: 24px;
}
.card__excerpt {
font-size: 16px;
}
.card__meta {
margin-top: auto;
}
}
使用容器单位
相对字体大小
CSS
.card__title {
/* 基于容器宽度的相对字体 */
font-size: calc(14px + 2cqw);
}
/* 容器300px → 14+6=20px */
/* 容器500px → 14+10=24px */
相对间距
CSS
.card__content {
padding: 2cqw 3cqw;
}
/* 容器300px → padding: 6px 9px */
/* 容器500px → padding: 10px 15px */
相对图片尺寸
CSS
@container card (min-width: 300px) {
.card__media {
width: 30cqw;
}
.card__image {
width: 30cqw;
height: 30cqw;
}
}
多容器场景
HTML
<!-- 主内容区 -->
<main class="main-content">
<div class="card-container">
<article class="card">...</article>
</div>
</main>
<!-- 侧边栏 -->
<aside class="sidebar">
<div class="card-container">
<article class="card">...</article>
</div>
</aside>
<!-- 相关推荐区 -->
<section class="related-section">
<div class="card-container">
<article class="card">...</article>
</div>
</section>
CSS
/* 不同容器宽度 */
.main-content {
width: 800px;
}
.sidebar {
width: 250px;
}
.related-section {
width: 400px;
}
/* 同一卡片组件在不同容器中自适应 */
/* 主内容区:宽松布局 */
/* 侧边栏:紧凑布局 */
/* 相关区:标准布局 */
卡片网格
HTML
<div class="grid-container">
<div class="card-container">
<article class="card">...</article>
</div>
<div class="card-container">
<article class="card">...</article>
</div>
<div class="card-container">
<article class="card">...</article>
</div>
</div>
CSS
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 24px;
}
.card-container {
container-type: inline-size;
}
/* 网格项宽度动态变化,卡片自动适应 */
悬停状态增强
CSS
@container card (min-width: 300px) {
.card {
transition: transform 0.2s, box-shadow 0.2s;
}
.card:hover {
transform: translateY(-4px);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}
}
/* 紧凑布局禁用悬停效果 */
@container card (max-width: 299px) {
.card:hover {
/* 无悬停效果 */
}
}
深色模式适配
CSS
@container card (min-width: 300px) {
.card {
background: white;
color: #333;
}
}
/* 媒体查询控制深色模式 */
@media (prefers-color-scheme: dark) {
@container card (min-width: 300px) {
.card {
background: #1a1a1a;
color: #e0e0e0;
}
.card__excerpt {
color: #aaa;
}
}
}
完整代码整合
CSS
/* 容器声明 */
.card-container {
container: card / inline-size;
}
/* 紧凑布局(默认) */
.card {
display: block;
background: white;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.card__content {
padding: 12px;
}
.card__title {
font-size: calc(14px + 2cqw);
font-weight: 600;
}
.card__action {
width: 100%;
margin-top: 12px;
}
/* 标准布局 */
@container card (min-width: 300px) {
.card {
display: flex;
gap: 16px;
}
.card__media {
flex-shrink: 0;
width: 120px;
}
.card__image {
width: 120px;
height: 120px;
}
.card__content {
padding: 16px;
flex: 1;
}
.card__action {
width: auto;
}
}
/* 宽松布局 */
@container card (min-width: 500px) {
.card {
gap: 24px;
}
.card__media {
width: 200px;
}
.card__image {
width: 200px;
height: 150px;
}
.card__content {
padding: 24px;
}
}
要点总结
- 容器声明:
container-type: inline-size启用查询 - 多断点布局:
@container (min-width: Xpx)分级控制 - 容器单位:
cqw实现相对尺寸 - 同一组件在不同容器自动适配
- 结合媒体查询处理深色模式等全局状态
📝 发现内容有误?点击此处直接编辑