用row+col控制筛选项宽度、data属性+classlist.toggle控制卡片显隐,可实现响应式筛选网格;筛选区须独立于网格容器,卡片必须为col直接子元素,内部用h-100+d-flex拉齐高度,图片加img-fluid,筛选逻辑优先用data-category和classlist.toggle。

直接用 row + col 组合控制筛选项宽度,再用 data- 属性 + classList.toggle 控制卡片显隐,就能实现真正响应式、不崩塌、可触控的筛选网格——不需要 JS 遍历 DOM,也不依赖第三方库。
筛选区必须独立于网格容器,否则小屏下输入框会被压缩
常见错误是把搜索框或下拉菜单塞进 row 里,比如:<div class="row"><div class="col-md-6"><input type="search"></div></div>。这样会让表单控件参与栅格计算,小屏下被强制等宽,失去自适应能力。
- 筛选区应单独包裹,不加
col类,用form-control w-100或col-12 col-md-auto控制宽度 - 多个筛选控件并排时,用
d-flex flex-wrap替代row,更可控 - 移动端入口建议固定底部或用
offcanvas,避免遮挡内容 - 给筛选区加
mb-4或pb-3预留足够间距,防止紧贴网格卡片
网格卡片必须为 col 的直接子元素,中间不能嵌套包装层
很多人写成:<div class="col-md-4"><div class="card-wrapper"><div class="card">...</div></div></div>。这会导致栅格宽度计算失准,小屏下换行错位、列间空白异常。
- 每个卡片必须是
col的直接子元素:<div class="col-md-4"><div class="card">...</div></div> - 卡片内部用
h-100+d-flex flex-column拉齐高度,按钮自动贴底 - 图片加
img-fluid,别设固定height,否则响应式下裁切或拉伸 - 避免在
col上用mb-3等垂直间距类,统一用row的g-3控制间隙
筛选逻辑优先用 data-category 和 classList.toggle
用 querySelectorAll('.grid-item') 再逐个设 style.display = 'none' 是最慢也最容易出错的方式——切回手机后隐藏项可能没恢复,resize 后布局错乱。
- 给每张卡片加语义化属性,如
data-category="news"、data-tag="urgent" - 筛选时只操作
classList.add('d-none')/classList.remove('d-none'),依赖 Bootstrap 原生类 - 避免手动改
style,否则媒体查询生效时会和col-12的 flex 行为冲突 - 需要动画?用
transition: all 0.2s ease配合d-none切换,比 JS 动画更轻量稳定
移动端点击区域太小?stretched-link 是最简解法
默认 btn 或 badge 的 padding 是 0.375rem 0.75rem(约 6×12px),远低于 WCAG 要求的 44×44px 可触控区。
- 把整个筛选项(即
col内容)包一层<a href="#" class="stretched-link"></a>,链接区域自动填满父容器 - 同时加
text-decoration-none去掉下划线,视觉不变,触控面积翻倍 - 别给
col加cursor: pointer——它没事件绑定,纯装饰,用户点不中 - 图标统一用
fs-2或style="font-size:1.5rem",避免不同尺寸导致列高不一致
真正容易被忽略的点:筛选状态切换后,要确保所有卡片都重绘了高度上下文;row-cols-* 类虽能强制等高,但它会覆盖 col 的断点行为,慎用。











