弹幕容器须用 position: relative 的 div 包裹 video,弹幕层需设 pointer-events: none 以保障控件可操作;动画优先用 transform + transition;防重叠必须 js 动态分配轨道并统一 font-size 与 line-height。

弹幕容器必须用 position: relative 包裹 video
直接给 <video></video> 标签设 position: relative 是无效的——它默认是 inline 元素,多数浏览器不将其视为可靠定位上下文。常见错误是只给弹幕层设 position: absolute,结果弹幕飞到页面左上角或顶部空白处。
正确做法是:用一个 <div class="video-wrapper"> 包住 <code><video></video>,并在该 div 上显式声明 position: relative;同时确保该容器宽高与视频一致(推荐用 width: 100% + aspect-ratio 或固定尺寸)。
注意:display: flex 或 grid 的父容器不能替代 position: relative——它们不自动创建定位上下文。
pointer-events: none 必须加在弹幕层上
否则用户点不到播放/暂停按钮、进度条等控件,尤其在移动端会直接失效。这不是可选项,是必填项。
弹幕层(如 #barrageContainer)样式中必须包含:
#barrageContainer {
pointer-events: none;
}
如果需要响应弹幕点击(比如高亮、跳转时间点),不能全局关掉,得改用 pointer-events: auto 配合事件委托,且只对具体弹幕元素启用。
部分旧版 iOS Safari 对 pointer-events: none 支持不稳定,若遇兼容问题,可用 z-index: -1 + 单独一层控件覆盖来兜底。
弹幕动画优先用 transform + transition
用 left 配合 setInterval 或 requestAnimationFrame 更新位置,在低端安卓机和旧 iPhone 上容易掉帧;而 CSS transform 走 GPU 加速,实测在 iPhone 6、Redmi 4 等设备无卡顿。
每个弹幕应:
- 设
position: absolute,初始transform: translateX(100vw) - 动画用
transition: transform 8s linear(时长按视频宽度和速度反推) - 结束时监听
transitionend事件移除 DOM,避免内存堆积
别用 jQuery animate() 或纯 JS 修改 left 值——重排重绘开销大,移动端尤其明显。
防重叠必须靠 JS 动态分配轨道
CSS 无法自动判断哪一行空闲,硬写死 top: 20px、top: 60px 会导致弹幕堆叠或大片留白。必须用 JS 实时分配垂直位置。
操作要点:
- 维护一个数组记录当前各“轨道”的占用状态(例如
[false, false, true, false]表示第 3 行被占) - 新弹幕插入前遍历数组找第一个
false位置,设为top: calc(20% * index)或固定像素偏移 - 轨道数建议设 4–6 行,太多易遮挡画面,太少易拥堵;超出容量时可丢弃或暂存队列
font-size 和 line-height 必须统一控制,否则行高错乱会破坏轨道计算逻辑——这点最容易被忽略,且调试时难定位。











