优先用 grid 而非 flexbox 实现响应式卡片网格:grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)) 自动适配列数,gap 统一控间距,避免 flex-wrap 不稳定、列宽不均及键盘弹出导致的布局错位等问题。

直接用 display: grid + minmax() + auto-fit,配合 Angular 的组件封装机制,就能避开 90% 的移动端布局坑。别再靠 flex-wrap 硬撑多列,也别在组件里写全局 .container 类。
为什么不要用 Flexbox 做多列网格
Flexbox 的 flex-wrap: wrap 在移动端实际表现极不稳定:
-
flex-basis: 0常被浏览器悄悄覆盖,尤其 Android Chrome 对min-width: 0继承行为不一致 - iOS Safari 横竖屏切换时重算
flex-basis,若父容器含padding或未设width: 100%,列数就错乱 - 输入框、图片等元素自带最小宽度(
min-width: auto),导致flex: 1失效,列宽不均 -
calc(100% / 3)在小数像素渲染上出问题,Safari 偶发一列换行
Grid 实现响应式等宽列的标准写法
以下 CSS 在 iOS 15+、Android Chrome 110+ 中稳定运行,无需媒体查询:
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 12px;
}
关键点:
-
240px是手指点击热区下限,不是随意写的;低于此值自动退为单列 -
auto-fit会收缩空轨道,auto-fill则保留,动态加载内容时优先选auto-fit -
gap不参与列宽计算,但视觉上“压缩”每列——若设计稿要求内容区域等宽,需把gap折算进minmax(),比如两列间一个gap: 12px,则写minmax(264px, 1fr)
Angular 组件内如何安全使用 Grid 样式
Grid 本身不依赖 Angular 封装,但和 ViewEncapsulation.Emulated 协同时要注意:
- 避免在组件样式中写全局选择器如
div.card-grid,改用组件专属类名.my-card-grid,防止被外部样式穿透 - 不要用
::ng-deep调整 Grid 容器内部子项——它破坏封装且未来会被移除;如需定制第三方卡片高度,用 wrapper 元素套一层 BEM block:<div class="my-card"><third-party-card></third-party-card></div> - 子项高度不一致时,别依赖
align-items: stretch(它只拉伸内容区);统一设grid-auto-rows: minmax(100px, auto)防塌陷 - Sass 中禁用嵌套写法
.card-grid { &__item { } }以外的结构,否则生成带空格的选择器,无法命中 Angular 注入的[_ngcontent-xxx]属性
移动端键盘弹出时布局错位怎么办
这是最易被忽略的真问题:Safari 的 vh 在软键盘弹出时会剧烈波动,导致 Grid 容器高度失真。
- 绝对不要用
height: 100vh作为 Grid 容器高度基准;改用min-height: 100vh+grid-template-rows: 1fr - 若需垂直居中内容,优先用
place-items: center(Grid 原生支持),它不依赖父容器高度链传递,比 Flexbox 的align-items: center更稳 - Grid 容器内慎用
position: absolute元素——它们脱离文档流,会让place-items和grid-auto-rows失去计算依据
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











