用语义化 拆分故事节点,配合 html { scroll-behavior: smooth; }、伪元素绘制时间线、scroll-snap-type 控制停驻节奏,即可纯 html+css 实现可滚动、有节奏感的故事线页面。

直接用 HTML + CSS 就能做出可滚动、有节奏感的故事线页面,不需要框架或 JS 驱动动画——关键在语义结构、CSS 伪元素和 scroll-behavior 控制。
怎么用 <section></section> 拆分故事节点而不破坏语义
每个故事阶段必须用独立的 <section></section>,不是 <div>。浏览器靠这个识别内容区块,屏幕阅读器、SEO、以及后续加滚动监听都依赖它。
<ul>
<li>
<code><section></section> 必须有明确的 id(如 id="chapter-1"),方便锚点跳转和 URL 定位
<section></section> 内只放标题 <h2></h2>、正文 <p></p>、配图 <img>,不塞导航栏或页脚<figure></figure> + <figcaption></figcaption>,别用 <div class="slide">
<h3>
<code>scroll-behavior: smooth 必须写在 html 元素上
很多人写在 body 或某个容器里,结果无效。只有 html 标签上的这个声明才能触发整页平滑滚动。
- 正确写法:
html { scroll-behavior: smooth; } - 不兼容 IE 和旧版 Safari,但现代 Chrome/Firefox/Edge 都支持;若需降级,不用加 JS polyfill,用户只是失去“滑动感”,不影响跳转
- 配合
@#@#@#@#@#@#@#@#@#@0使用,点击即平滑滚动到对应<section id="chapter-3"></section> - 别在
<section></section>上设overflow-y: auto,否则会创建局部滚动上下文,scroll-behavior失效
时间线类故事用 CSS 伪元素画主线,别用图片或 SVG
用 ::before 在每段之间画连接线,比切图或内联 SVG 更轻量、更易维护,也天然适配暗色模式。
- 主线必须用绝对定位 +
position: relative父容器,例如:section { position: relative; } section::before { content: ""; position: absolute; top: 0; left: 50%; transform: translateX(-50%); height: 100%; width: 2px; background: #666; } - 每个
<section></section>的顶部加圆点标记,用::after实现:section::after { content: ""; position: absolute; top: 0; left: 50%; transform: translate(-50%, -50%); width: 12px; height: 12px; border-radius: 50%; background: #fff; border: 2px solid #333; } - 如果故事节点高度差异大,主线长度会不准——这时不要调
height,改用bottom: 0+top: 1.5em(避开标题行高)来锚定起止点
移动端滚动卡顿?检查 will-change 和图片加载
长故事页在 iOS Safari 上一滚动就掉帧,90% 是因为图片没做懒加载,或用了未优化的背景图。
- 所有
<img>必须带loading="lazy",哪怕只有 3 张图——iOS 对非懒加载图片的渲染优先级极低 - 背景图(如
background-image: url(...))别用大尺寸 JPG,改用 WebP +background-size: cover+background-attachment: fixed时加will-change: transform到父容器 - 别给
<section></section>加transform: translateZ(0)强制 GPU 加速,现代浏览器已自动优化;反而可能引发 iOS 输入框失焦 - 如果用了自定义字体,确保
@font-face中含font-display: swap,否则首屏文字会长时间空白
真正难的不是画出那条线,而是让每段文字在滚动中自然停驻、呼吸——这靠的是 scroll-snap-type 和精准的 min-height 匹配,而不是 JS 动画库。别急着加交互,先让滚动本身成为叙事节奏的一部分。











