应使用env()函数补偿安全区、clamp()或vw单位替代写死像素值,并配合aspect-ratio与object-fit维持画中画比例,否则小屏下会遮挡输入框、被刘海裁切或滚动闪烁。

为什么 fixed 定位在小屏上会错位或遮挡内容
直接给 video 加 position: fixed 并设 right: 20px; bottom: 20px,在桌面端看起来正常,但一到手机上就可能压住输入框、被刘海吃掉、甚至滚动时闪烁。这不是 CSS 不够用,而是 fixed 的坐标系默认以视口为基准,没考虑安全区、触摸热区和动态滚动行为。
尤其 iOS Safari 对 fixed 元素的渲染有已知抖动问题,单纯靠 transform 或 z-index 无法根治。必须用 env() 补偿,且不能只依赖像素值。
- 必须用
calc(20px + env(safe-area-inset-bottom, 0px))替代硬写bottom: 20px - 避免
left: 10px这类写死偏移,改用right: clamp(12px, 5vw, 24px)控制横向间距 - 小屏下建议把画中画尺寸限制在
max-width: 300px,否则会挤占可操作区域
如何用 IntersectionObserver 触发画中画切换而不卡顿
监听 video 是否离开视口,是主流做法,但容易踩两个坑:一是 threshold: 0 在快速滚动时频繁触发,二是未处理用户手动关闭后又进入视口的逻辑冲突。
关键不是“是否可见”,而是“是否应激活小窗”——这取决于状态优先级:用户手动关闭 > 滚动离开 > 自动恢复。
-
IntersectionObserver的rootMargin设为"0px 0px -100% 0px",即元素顶部刚离开视口就触发,比threshold: 0更灵敏 - 不要在回调里直接操作 DOM 类名,改用 Vue 的
ref或 React 的useState批量更新,避免 layout thrashing - 用户点击关闭按钮后,设
userDismissed = true,只有当isIntersecting === true且userDismissed === false时才恢复原位
画中画容器的宽高比怎么保持不拉伸也不裁剪
小窗模式下,video 脱离文档流,不能再靠父容器的 padding-top 维持比例。此时必须用 aspect-ratio + object-fit 组合,否则要么变形,要么黑边失控。
注意:iOS 16.4+ 才完整支持 aspect-ratio,旧版本需降级 fallback。
- 小窗
video必须显式设aspect-ratio: 16/9,同时加object-fit: cover(保证画面填满) - 若要兼容 Safari 15.6 及更早版本,用伪元素 padding-bottom 方案:外层包裹
div设position: relative; padding-bottom: 56.25%,video绝对定位填满 - 禁用
width: 100%; height: auto—— 这在fixed下会失效,必须用width和aspect-ratio联合控制
如何让画中画按钮在不同设备上都可点、不误触
画中画右下角的关闭按钮,常因尺寸太小、位置太靠边、或未适配安全区,导致手指点不中。这不是交互逻辑问题,是 CSS 布局没覆盖物理约束。
按钮不是装饰,是功能入口,必须满足 WCAG 2.1 最小点击尺寸(44×44px)和安全距离要求。
- 按钮本身用
min-width: 44px; min-height: 44px,内边距用padding而非font-size控制尺寸 - 定位用
right: env(safe-area-inset-right, 0px); bottom: env(safe-area-inset-bottom, 0px),再叠加calc()微调 - 禁用
transform: scale()做视觉缩放——它放大了渲染像素但没扩大点击热区,反而导致边缘误触
position: fixed,而是让这个固定位置在各种屏幕、各种滚动状态下都“稳得住”。很多项目卡在最后 10%,就差一个 env(safe-area-inset-bottom) 或一次正确的 rootMargin 设置。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











