移动端底部弹窗应使用 position: fixed + inset: 0 定位,内部内容容器用 display: grid + grid-template-rows: max-content 1fr,并配 max-height: 70vh、overflow: hidden、菜单项 overflow-y: auto 和 min-height: 0,列布局用 repeat(auto-fit, minmax(80px, 1fr)),隐藏项必须用 display: none。

移动端底部弹窗菜单不能直接用 display: grid 套在弹窗外层
弹窗整体(比如 .bottom-sheet)必须用 position: fixed + inset: 0 锚定视口,再靠 display: flex + flex-direction: column + justify-content: flex-end 推到底部——这是唯一稳定兼容 iOS Safari 和 Android Chrome 的方式。如果给外层加 display: grid,会导致弹窗无法上推、遮罩层错位、甚至内容塌陷(尤其在 iOS 16–17)。Grid 只管容器内空间划分,不处理浮层定位逻辑。
grid-template-rows: max-content 1fr 是内容区的正确写法
真正该设 Grid 的是弹窗内部的内容容器(如 .sheet-content),不是整个弹窗。它需要两行:顶部操作栏(固定高度)和下方可滚动菜单项区域。关键配置如下:
-
grid-template-rows: max-content 1fr—— 首行用max-content吸收标题/关闭按钮高度,次行用1fr吃满剩余空间 - 必须配
max-height: 70vh(或类似值)+overflow: hidden,否则1fr没有计算边界,长菜单会撑爆屏幕 - 菜单列表容器(如
.menu-grid)要加overflow-y: auto和min-height: 0,否则 Grid 子项默认最小尺寸限制会让它塌缩成一条线
菜单项用 repeat(auto-fit, minmax(80px, 1fr)) 实现自适应列数
底部弹窗里常放图标+文字的功能入口(如“拍照”“相册”“文件”),不适合硬写 1fr 1fr 1fr。正确做法是让 Grid 自动决定列数:
-
grid-template-columns: repeat(auto-fit, minmax(80px, 1fr))—— 每项至少宽 80px,小屏单列,中屏双列,大屏三列,避免文字被压扁 - 用
auto-fit而非auto-fill:前者合并空轨道,防止右侧留白;后者保留所有轨道,适合预设数量场景 - 子项必须设
display: flex+flex-direction: column+align-items: center+justify-content: center,否则图标和文字上下错位(baseline 对齐问题) - 加
min-height: 48px,满足触控安全区最低要求
隐藏某类菜单项时只能用 display: none
比如在小屏下隐藏“高级功能”组,或根据权限动态隐藏某一项。这时候不能用 visibility: hidden 或 opacity: 0:
- 它们仍占 Grid 轨道位置,
1fr区域会被压缩,导致滚动失效或按钮错位 -
display: none是唯一能让 Grid 自动重排剩余轨道的方式,隐藏后1fr会完整分给可见区域 - 别在媒体查询里重写
grid-template-rows或改1fr为具体像素——那会让响应式逻辑失控
最常漏掉的是 max-height 和 min-height: 0。没这两条,整个网格结构看起来“没反应”,不是代码写错了,而是 Grid 计算的前提根本不存在。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











