父容器必须设 min-height: 100vh 而非 height: 100vh,因移动端浏览器地址栏/键盘切换会动态缩放 100vh 导致表单错位;应配合 min-height: -webkit-fill-available 和 min-height: 100dvh,并清空 html、body 默认边距。

父容器必须设 min-height: 100vh,不是 height: 100vh
移动端 Safari 和部分 Android 浏览器在地址栏收起/弹出键盘时会动态缩放 100vh,导致表单突然上移或被截断。用 min-height: 100vh 能保底撑满视口,避免“居中失效”的假象。
更稳妥的写法是:
.login-container {
min-height: 100vh;
min-height: -webkit-fill-available; /* iOS Safari 兜底 */
min-height: 100dvh; /* Chrome 104+/Safari 16.4+ 推荐,不受键盘影响 */
}
别忘了清掉默认边距:html, body { margin: 0; height: 100%; },否则 100vh 可能算不准。
justify-content 和 align-items 必须同时出现
只写 justify-content: center —— 表单水平居中但贴顶;只写 align-items: center —— 垂直方向可能“碰巧”居中(靠内容撑高),但水平完全失控。两者缺一不可。
常见错误场景:
- 误以为
vertical-align: middle对div有效 → 它只管行内元素或table-cell - 写了
align-content: center→ 这个属性只在flex-wrap: wrap且实际换行时才起作用,登录框单行布局下完全无效 - 把
display: flex加在表单自身(.form)上,而不是它的父容器 → 子项(input、button)不会因此居中,只是彼此排列方式变了
表单内部用 flex-direction: column + gap 控制间距
登录表单是垂直流,不需要嵌套额外容器。直接在 .form 上设:
.form {
display: flex;
flex-direction: column;
gap: 1rem;
width: 100%;
max-width: 400px;
padding: 1.5rem;
box-sizing: border-box;
}
gap 比反复写 margin-bottom 更干净,且自动适配响应式(比如 @media (min-width: 768px) 里可改成 flex-direction: row 做左右 label/input 布局)。
注意点:
- 移动端输入框聚焦时,iOS 键盘弹出会挤压视口,
100vh失效 → 优先用100dvh或加 JS 监听resize动态修正高度 -
box-sizing: border-box必须加,否则padding会让width: 100%超出父容器 - 如果表单外层用了
position: fixed,记得补top: 0; left: 0; width: 100%; height: 100%,否则 flex 居中无基准
移动端被截断?先查 body 和 html 的 overflow
很多情况下表单明明 CSS 写对了,却在 iOS 上只显示上半部分——八成是 body 或某个祖先元素加了 overflow: hidden,或者 position: fixed 容器没配全尺寸。
快速排查步骤:
- 打开 DevTools,选中表单最外层容器,看 computed 样式里
height和min-height是否为预期值 - 检查
body的overflow是否为hidden或scroll,临时设为visible看是否恢复 - 确认表单是否挂载在
直接子级;若嵌在router-view或框架组件里,要确保该组件父级也满足全屏约束
真正麻烦的从来不是怎么写居中,而是父容器有没有“被悄悄限制高度”。写完三行 flex 居中后,第一反应不该是调样式,而是打开 Elements 面板往上逐层看 height 计算链。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











