纯静态歌词滚动采用单div容器+textContent,固定高度隐藏溢出,每行用p标签包裹并设active类高亮当前句,用requestAnimationFrame结合二分查找同步时间轴,避免transform和setInterval。

用 <div> + textContent 实现纯静态歌词滚动
极简风不需要动画、不依赖音频 API,核心是「只显示当前行,其余隐藏」。最轻量的做法是用一个 <div> 容器设固定高度和 overflow: hidden,内部用 <p> 或 <span> 列出所有歌词行,再通过 JS 控制 scrollTop 或切换 className 来高亮当前句。
注意:别用 transform: translateY() 做位移——它会触发重绘,且在低端设备上易卡顿;也别一开始就加载整首歌词进 innerHTML 再切片,容易因换行符或空格导致错位。
- 每行歌词用
<p class="lyric-line">包裹,避免用<br>换行(语义差、难控制单行样式) - 容器设
height: 60px(刚好容下一行文字)、line-height: 60px、text-align: center - 当前行加
class="active",CSS 里单独定义颜色/字体粗细,不要用opacity或visibility切换——它们仍占布局空间
用 requestAnimationFrame 同步时间轴,避开 setInterval 累积误差
歌词同步本质是「按时间戳匹配当前句」。如果用 setInterval(fn, 100) 轮询,JS 执行延迟、页面失焦、GC 都会导致跳行或卡顿。正确做法是用 requestAnimationFrame 在每一帧读取音频 currentTime,再二分查找匹配到的歌词索引。
示例逻辑:
立即学习“前端免费学习笔记(深入)”;
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
const lines = [
{ time: 0, text: "天青色等烟雨" },
{ time: 4.2, text: "而我在等你" },
{ time: 8.7, text: "炊烟袅袅升起" }
];
function syncLyric(currentTime) {
let i = 0;
while (i < lines.length - 1 && lines[i + 1].time <= currentTime) i++;
document.querySelector(".lyric-line.active")?.classList.remove("active");
document.querySelectorAll(".lyric-line")[i]?.classList.add("active");
}- 歌词数组必须按
time升序排列,否则二分失效 - 别在
syncLyric里反复调用querySelectorAll——提取为常量缓存 - 音频
play()后首次currentTime可能为 0,需监听timeupdate事件再启动 rAF 循环,避免空跑
移动端适配时,font-size 必须用 rem 或 vw,禁用 px
极简风在手机上常全屏居中,但硬写 font-size: 18px 在 iPhone 15 Pro 和 iPad mini 上观感差异极大。直接后果是:歌词行高溢出容器、active 行被截断、用户误判同步位置。
- 推荐用
font-size: 4.5vw(视口宽的 4.5%),配合max-width: 500px限制最大字号 - 容器
height也得响应式:height: calc(4.5vw * 1.4)(1.4 是行高倍数),否则overflow: hidden失效 - iOS Safari 对
vh有滚动条高度 bug,别用height: 20vh做容器高
真·极简场景下,连 JS 都可以不要
如果你只是做静态展示页(比如发朋友圈的 demo 页),根本不需要实时同步。用 CSS @keyframes + animation-delay 就能模拟逐行高亮,零 JS、零请求、秒开。
关键点:
- 每行
<p>设置不同animation-delay,例如第 2 行animation-delay: 4.2s - 动画只改
color和font-weight,别动transform或opacity - 总动画时长要 ≥ 最后一行时间戳,否则结尾突兀
这种方案在微信内嵌浏览器里最稳——毕竟连 AudioContext 都可能被静音策略拦截,而 CSS 动画永远可执行。
真正难的不是让字动起来,而是让「当前这行」在任意设备、任意网络、任意后台状态下,都精准落在用户视线中央。越想极简,越要提前想清楚:你同步的到底是时间,还是人的注意力。


















