应使用height: 100dvh替代height: 100vh,因dvh动态响应地址栏收起/展开,避免高度跳变;但需html和body同时设置,且Safari 16.4+、Chrome 105+等新版本才支持,旧版须降级fallback。

body 高度设为 100dvh 而非 100vh
直接写 height: 100vh 在移动端容易出问题:地址栏展开/收起时,vh 值会跳变,导致右侧视频区突然缩高或溢出。浏览器实际渲染的“可视区域高度”在滚动过程中并不稳定。
现代解法是改用 dvh(dynamic viewport height):它始终反映当前可见视口高度,不随地址栏状态抖动。但注意兼容性——Safari 16.4+、Chrome 105+、Firefox 110+ 支持,旧版需降级 fallback。
- 必须配合
html, body { height: 100dvh; },只设body不够,父级html也要同步 - 若需兼容 iOS Safari 15.x 或 Android Chrome vh + resize 监听动态更新 CSS 变量
--vh - 不要在 flex 容器里对子项再写
height: 100%—— 这会导致计算循环,尤其当父级是100dvh且自身又含 padding/border 时
双栏容器用 display: flex 且子项不脱离文档流
用 position: absolute 强行撑高右侧栏,看似简单,实则破坏文档流:后续内容(比如新的 <h1>new part</h1>)会从页面顶部开始渲染,被覆盖或挤出视口。
正确做法是让左右栏都作为 flex 子项自然参与布局,高度由父容器 100dvh 统一约束:
立即学习“前端免费学习笔记(深入)”;
.layout {
display: flex;
height: 100dvh;
}
.left { flex: 1; }
.right { flex: 1; min-width: 0; } /* 防止内容过长时 flex 崩溃 */
-
min-width: 0是关键,尤其当.right内含视频或图片时,避免其强行撑宽导致横向滚动 - 不要给
.left或.right单独设height: 100%,flex 子项默认拉伸填满父高 - 如需右侧固定宽度(如 320px),用
flex: 0 0 320px,左侧仍用flex: 1自适应
视频区域需内部自适应而非靠 height: 100%
很多人给视频容器设 height: 100%,结果发现视频被拉伸变形或留白。真正要的是“保持宽高比 + 填满可用空间”,不是强制拉高。
推荐用 aspect-ratio + object-fit 组合:
.video-container {
width: 100%;
aspect-ratio: 16 / 9;
background: #000;
}
.video-container video {
width: 100%;
height: 100%;
object-fit: cover;
}
-
aspect-ratio是现代标准,比 padding-bottom hack 更可靠,支持 Chrome 88+、Firefox 89+、Safari 15.4+ -
object-fit: cover确保视频填满且不畸变;若要完整显示(可能有黑边),改用contain - 避免在
video标签上写width和height属性(如width="640"),这会覆盖 CSS 的响应式行为
移动端堆叠时高度逻辑要重置
双栏在小屏下通常要转为上下堆叠,此时 100dvh 仍生效,但单栏高度不该再占满整个视口——否则用户得滚很久才能看到新内容。
用媒体查询重置高度行为:
@media (max-width: 768px) {
.layout { flex-direction: column; height: auto; }
.right { height: auto; max-height: 60vh; }
}
-
height: auto让布局回归自然流,不再强占整屏 -
max-height: 60vh是经验值,防止视频区过大挤压正文;可根据实际内容微调 - 如果右侧是纯视频背景(无交互控件),建议加
pointer-events: none,避免遮挡下方可点击元素
实际最难处理的不是怎么写,而是怎么让 dvh 和 aspect-ratio 在同一套样式里稳定共存——尤其当右侧栏同时含视频、字幕、按钮时,稍不注意就会触发 flex 最小尺寸计算异常,导致高度塌陷或溢出。调试时优先检查 computed styles 中 height 和 min-height 的最终值,而不是只看声明。



















