D02 响应式文章列表

2026-10-31 17:000 阅读约 11 分钟CSS

D02 响应式文章列表

摘要:文章列表页面的结构固定:标题、筛选、卡片网格、分页。难点在网格的自适应——固定列数在窄屏挤压、在宽屏留白;auto-fit 加 minmax 能让列数随宽度自动变化。本文给出列表页完整布局、两处容器查询与六项验收。
关键词:列表页,自适应网格,断点,分页,容器查询

所属:frontend/css / D-实战 | 上一篇:D01-组件样式按钮与卡片 | 下一篇:D03-暗色主题与设计令牌

1 引言

列表页的布局目标只有一个:不论宽度多少,卡片都不被挤压、不留大片空白、不出现横向滚动。

本文给出一份可直接复用的列表页样式。范围见表 1-1。

项 本文覆盖 本文不覆盖
结构 页头、筛选、网格、分页 数据加载与筛选逻辑
网格 auto-fit + minmax、容器查询 瀑布流布局
细节 卡片等高、摘要对齐、分页状态 无限滚动

2 预备知识

项 要求 核对方式
环境 本地服务器可用 浏览器能打开 localhost
文件 css-practice/list.html 含 9 张卡片结构
前置 D01 卡片样式已可用
前置 A07、A08 网格与断点

3 原理与实现

3.1 列数由可用宽度决定

不再为每个断点写列数,而是给出「最小可接受卡片宽度」,由浏览器算列数,如图 3-1 所示。

flowchart LR
    A["可用宽度 W"] --> B{"auto-fit + minmax(18rem, 1fr)"}
    B --> C["列数 = floor(W / 18rem)"]
    C --> D["剩余空间按 1fr 均分"]
    D --> E["卡片等高、间距一致"]

图 3-1 自适应列数的计算方式

图上可见:卡片最小宽度是唯一需要维护的参数;容器变宽只增加列数,不改变卡片比例。

3.2 完整布局

/* 运行环境:Chrome 130+;css-practice/list.css */
.page {
  max-inline-size: 76rem;
  margin-inline: auto;
  padding-inline: 1rem;
}

.page__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  margin-block: 1.5rem 1rem;
}

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  list-style: none;
  padding: 0;
  margin: 0 0 1.5rem;
}

.filters a {
  display: inline-block;
  padding: 0.25rem 0.75rem;
  border-radius: 999px;
  background: var(--surface-alt, #f1f5f9);
  text-decoration: none;
}

.filters a[aria-current="page"] { background: var(--brand, #1d4ed8); color: #fff; }

.list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr));
  gap: 1rem;
  list-style: none;
  padding: 0;
  margin: 0;
}

.list > li { display: grid; }

.card-wrap { container-type: inline-size; }

@container (min-width: 22rem) {
  .card__title { font-size: 1.25rem; }
}

.pager {
  display: flex;
  justify-content: center;
  gap: 0.5rem;
  margin-block: 2rem;
  list-style: none;
  padding: 0;
}

.pager [aria-current="page"] { font-weight: 700; text-decoration: underline; }

布局要点见表 3-1。

项 写法 目的
网格 repeat(auto-fit, minmax(min(18rem, 100%), 1fr)) 列数自适应,窄屏不溢出
卡片等高 列表项 display: grid 让卡片撑满行高
筛选状态 aria-current="page" 语义与样式同源
分页 nav + ul,当前页标记 可读且可朗读
内边距 页面级 padding-inline 小屏留白

实施清单:

步骤 动作 产出
1 写页面容器与最大宽度 大屏居中
2 写页头与筛选列表 筛选条可用
3 写自适应网格 列数随宽度变化
4 列表项设为 grid 卡片等高
5 补容器查询调整标题字号 大卡片字号更大
6 写分页与当前页标记 状态可辨
7 按 4 节清单验收 六项通过

4 验证与讨论

  1. 从 360 像素拖到 1440 像素,记录列数变化:1 → 2 → 3 → 4。
  2. 检查任意宽度下是否有横向滚动条。
  3. 把某张卡片标题改为三行,确认同行其它卡片高度一致、内容不重叠。
  4. 检查筛选与分页的当前项,确认视觉与语义一致。
序号 验收项 判定标准 依据
1 列数自适应 宽度变化时列数按 1/2/3/4 变化 表 3-1
2 无横向滚动 任意宽度无滚动条 表 3-1
3 卡片等高 同行卡片高度一致 表 3-1
4 筛选状态 当前项与语义一致 表 3-1
5 分页可用 当前页可辨、链接可点 表 3-1
6 容器查询 宽卡片标题更大 3.2 节

五项取舍见表 4-1。

决策点 采用方案 备选方案 不选的理由
列数控制 auto-fit + minmax 三个断点写死列数 断点越多越难维护
卡片高度 列表项 grid 拉伸 固定 min-height 固定值在长标题下仍会溢出
卡片最小宽 18rem 12rem 过窄时标题频繁换行
筛选状态 aria-current 额外 .active 类名 属性同时服务语义与样式
分页 静态列表 无限滚动 静态分页可检索、可直达

讨论与局限。 auto-fit 在卡片数量少时会拉伸卡片填满整行,需要保持统一宽度时应改 auto-fill。另容器查询需要每张卡片外层声明 container-type,层级多时会增加维护成本。

5 常见问题

现象 原因 处理
窄屏出现横向滚动 minmax 下限大于容器宽度 用 min(18rem, 100%)
卡片高度参差 列表项未设 grid 列表项 display: grid
列数与预期不符 容器受 max-width 限制 检查外层宽度
筛选当前项看不出 只加了样式未加属性 用 aria-current="page"
分页点不动 li 内用了 span 而非 a 用链接,当前页才用 span

6 结论

序号 结论 依据
1 只维护卡片最小宽度,列数交给浏览器 图 3-1
2 卡片等高靠列表项 grid 表 3-1
3 状态用属性选择器,语义与样式同源 表 3-1
4 静态分页优于无限滚动 表 4-1

参考文献

[1] MDN Web Docs · CSS Grid 自动填充,https://developer.mozilla.org/zh-CN/docs/Web/CSS/repeat(访问于 2026-10-31)
[2] web.dev · 响应式布局,https://web.dev/articles/responsive-web-design-basics(访问于 2026-10-31)

返回文章列表

评论 0

0/2000

还没有评论,快来抢沙发吧~