ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

前端精读:不再需要 JS 的 5 件事——用 HTML 与 CSS 原生能力替代脚本实现

前端精读:不再需要 JS 的 5 件事——用 HTML 与 CSS 原生能力替代脚本实现 文档技术博客教程【免费下载链接】weekly前端精读周刊。帮你理解最前沿、实用的技术。项目地址https://gitcode.com/GitHub_Trending/we/weekly点击查看免费下载关注 JavaScript 太久容易养成“任何功能都用 JS 实现”的习惯反而忽略了 HTML 与 CSS 本身就具备的功能特征。本篇文章以前端精读周刊《不再需要 JS 做的 5 件事》为骨架系统拆解 SVG 线条动画、hover 侧边栏、sticky 黏性定位、details 手风琴、暗色主题这 5 个可以零 JS 落地的经典场景并追加幻灯片滚动与原生颜色选择器两个实战案例帮助你建立“综合使用技术工具、按场景选型”的前端思维读完即可把这些方案直接应用到自己的页面中。引言不要让 JS 成为唯一的锤子很多前端同学的习惯是页面一有交互需求第一反应就是写 JS 监听事件、操作 DOM。但事实上有一部分“看起来必须用 JS 才能做”的功能浏览器已经通过 HTML 标签、CSS 属性和媒体查询原生提供了。用 JS 实现这些功能往往是“吃力不讨好”代码量更大、需要额外维护状态与监听逻辑在滚动定位、动画等场景下JS 与浏览器渲染管线是异步关系容易产生抖动原生方案由浏览器引擎直接处理性能与一致性都更好。技术选型能力的本质就是知道每种工具适合的领域并能“在合适的场景选择 CSS 方案”。下文从 5 个原案例出发逐一还原实现细节与原理。一、用 CSS 控制 SVG 动画stroke-dasharray 的“绘图”效果原文绘制了一个“放烟花”的 SVG 动画例子核心思路是用 CSS 控制 SVG 路径的线条外观与偏移从而产生线条从起点逐步“画”到终点的效果。核心代码如下.trail { stroke-width: 2; stroke-dasharray: 1 10 5 10 10 5 30 150; animation-name: trail; animation-timing-function: ease-out; } keyframes trail { from, 20% { stroke-width: 3; stroke-dashoffset: 80; } 100%, to { stroke-width: 0.5; stroke-dashoffset: -150; } }这段代码里有两个关键属性stroke-dasharray控制线条的“实线段 空白段”模式它接受一组长度值。上例中的1 10 5 10 10 5 30 150会被浏览器依次循环解释为实线 1、空白 10、实线 5、空白 10……如此往复形成疏密不一的花样虚线这正是“烟花轨迹”斑驳质感的来源。stroke-dashoffset控制虚线图案的起始偏移量。动画从stroke-dashoffset: 80变化到-150等价于让整段虚线图案沿路径方向发生位移。配合stroke-width从 3 收窄到 0.5轨迹逐渐变细视觉上就产生了“线条被一笔一笔绘制出来、尾部渐渐淡出”的烟花效果。值得强调的是CSS 样式对 SVG 绘制的路径是完全生效的stroke-*系列属性、fill、transform以及 CSS 动画都可以直接作用于 SVG 元素无需引入任何 JS 或动画库。这正是“用 CSS 描述标准动画行为”的典型代表——关于 CSS 动画与 Web Animations API 的取舍可以进一步阅读本仓库的《精读 CSS Animations vs Web Animations API》标准动画场景优先 CSS需要编程式控制动画节奏、串联动画时再考虑 JS 侧方案。二、纯 CSS 的 hover 侧边栏:hover 与 :focus-within侧边栏“平时隐藏、hover 时滑出”同样可以完全用 CSS 实现不需要监听 mouseenter/mouseleavenav { position: absolute; right: 100%; transition: 0.2s transform; } nav:hover, nav:focus-within { transform: translateX(100%); }原文代码中的position: absolute带有引号属于无效写法实际应写作position: absolute。这段实现的三个要点right: 100%让导航栏整体偏移到容器右侧之外处于不可见区域transform: translateX(100%)百分比位移是相对元素自身宽度计算的所以translateX(100%)恰好把导航栏平移回自己宽度的身位正好滑入可视区。用 transform 而非 left/top 做位移动画是因为 transform 通常走合成器线程动画更流畅、不易引发重排:focus-within只要导航栏内部任意元素获得焦点例如用户用 Tab 键把焦点移入链接导航栏同样会滑出。这是:hover覆盖不到的键盘场景——:hover只管鼠标:focus-within管键盘焦点两者互补。如果需要“hover 后延迟展示”加上transition-delay即可例如transition: 0.2s transform 0.5s表示延迟 0.5 秒后开始 0.2 秒的位移动画。整个交互零 JS、零监听纯声明式描述状态与样式的关系。三、position: sticky 黏性定位浏览器帮你解决抖动让元素滚动到某个位置后“吸顶”JS 写法需要监听父容器滚动事件、计算偏移、动态切换定位方式逻辑繁琐且容易抖动CSS 的position: sticky一句话就能解决.square { position: sticky; top: 2em; }其行为可以这样理解该元素在其父容器内始终参与正常文档流类似 relative但当滚动使其与视口顶部的距离小于top: 2em这个阈值时它会“黏”在距视口顶部 2em 处不再随页面滚走表现类似 fixed直到父容器滚出可视范围为止。为什么原文强调“用 JS 判断还是挺复杂的”因为 JS 版本你必须设法监听父元素的滚动事件并在回调中做边界判断在定位切换的瞬间由于JS 执行与 CSS 渲染是异步关系状态同步不及时页面极易出现肉眼可见的抖动jank。而position: sticky是浏览器在合成与布局阶段原生处理的引擎自己保证定位切换的平滑性既省代码又消除抖动。这也是“浏览器有能力解决转换时抖动问题”的直接体现。四、手风琴菜单一个 HTML 标签搞定展开折叠“展开/折叠”是最常见的基础交互之一其实 HTML 原生提供了语义化组件detailsdetails summarytitle/summary p1/p p2/p /details行为规则非常清晰summary的内容总是展示充当可点击的标题栏点击summary会在“展开”与“收起”之间切换details内其他元素即p等的显隐展开状态下details元素会带有一个open属性这为样式定制提供了天然入口。例如本仓库的《精读使用 CSS 属性选择器》就展示了如何利用details[open]这个属性选择器给“打开状态”设置专属样式details[open] { background-color: hotpink; }也就是说details不仅能做功能还能结合属性选择器优雅地表达“状态样式”。它的局限也很明确做不了特殊动画效果展开/收起是浏览器默认的瞬时行为。所以原文的判断很务实——如果只是要一个普通的展开折叠功能用 HTML 标签就够了如果需要手风琴展开动画、多面板互斥联动这类非标准交互再考虑 JS 或组件库。五、暗色主题prefers-color-scheme 与纯 CSS 的开关方案暗色主题看似是“定制业务逻辑”但因为需求过于普遍操作系统与浏览器都内置了支持CSS 也提供了对应的媒体查询——prefers-color-scheme用于判断当前系统主题是亮色还是暗色media (prefers-color-scheme: light) { /** 系统为亮色主题时应用的样式 */ } media (prefers-color-scheme: dark) { /** 系统为暗色主题时应用的样式 */ } media (prefers-color-scheme: no-preference) { /** 用户未声明偏好时的兜底样式 */ }既然浏览器能感知系统主题那么网站暗色主题最好与操作系统设置保持一致用户体验才更连贯系统切到暗色站点自动跟随全程不需要 JS 参与。如果想给用户一个“手动切换暗色”的开关也可以只用 CSS 完成用 Checkbox 的勾选状态作为主题开关配合兄弟选择器实现样式切换#checkboxId:checked ~ .container { background-color: black; }这里的关键是~通用兄弟选择器selector1 ~ selector2表示选中“位于 selector1 之后、满足 selector2 条件的兄弟节点”。所以只要.container是 checkbox 的后续兄弟元素勾选 checkbox 就会命中.container并套用暗色样式。更进阶的玩法是结合 CSS 变量Custom Properties在:root定义一套颜色变量再在media (prefers-color-scheme: dark)中覆盖变量值全站颜色自动换肤。这一方向在本仓库的《精读使用 css 变量生成颜色主题》中有完整展开包括如何根据颜色明度决定按钮文字用黑还是白、如何由主题色派生第二第三主题色等工程细节值得延伸阅读。六、追加案例一scroll-snap 幻灯片滚动除了原文的 5 个例子精读部分还补充了两个高频场景。首先是“幻灯片滚动”每次滚动都按固定步长把一个完整子元素展示进可视区域绝不会出现上下两个子元素各露出一截的“割裂”状态。这种效果在两类场景中非常常见浏览器式幻灯片组件很多产品官网首页把首屏切分成 5 个纵向区块每个区块展示一个产品特性滚动不再是连续滑行而是从一个区块完整切换到下一个区块。而它同样可以零 JS 实现html { scroll-snap-type: y mandatory; } .child { scroll-snap-align: start; }工作原理scroll-snap-type: y mandatory声明滚动容器为“y 轴强制吸附”。mandatory表示必须吸附浏览器会强制将滚动停到吸附点上此外还有proximity接近吸附点时吸附允许自由滚动方向也支持x、bothscroll-snap-align: start声明子元素的对齐方式可取start/center/end表示吸附时子元素的哪条边对齐容器。当用户滚轮滚动、拖动滚动条松手或键盘上下按键时浏览器会精准捕捉这一垂直滚动行为并将子元素完整滚动到可视区域——所有吸附计算都由引擎完成无需 JS 监听滚动位置、无需手动对齐计算。七、追加案例二原生颜色选择器 input[typecolor]颜色选择器在很多后台系统里是“必做”功能但 HTML 原生就内置了一个input typecolor value#000000value是#rrggbb格式的十六进制颜色值浏览器会渲染出系统自带的拾色器面板。这个方案的优势非常突出性能极好零 JS、零依赖、零渲染成本可维护性极好没有三方库版本升级、样式覆盖等问题部分浏览器实现甚至支持捕捉桌面上的颜色取色器可以直接吸取屏幕任意位置的颜色。代价是无法对拾色器面板本身做定制弹层外观、色板布局都由浏览器决定。因此适合对“选色交互”没有强定制要求的场景如果产品需要自定义色板、色相环、吸管工具等品牌化体验则仍应回到 JS 组件方案。八、技术选型边界CSS 与 JS 如何分工读罢这些例子容易产生另一个极端——“既然 CSS 这么强是不是什么功能都该用 CSS 实现”原文对此给出了冷静的边界判断这里展开为三条选型原则标准交互行为优先 CSS非标准交互行为用 JS。CSS 是描述性语言能精确控制样式、动画、滚动吸附等“声明式”行为但像“自定义位置弹出 Modal”“用 SVG 绘制完全自定义路径动画”这类需要精确过程控制的交互JS 依然是正确选择。状态需要跨元素响应、甚至触发副作用时用 JS。CSS 伪类:hover、:checked、:focus-within等能表达大部分“单点状态 → 样式响应”但如果要“监听状态变化后发一个请求、写日志、联动远端数据”CSS 就无能为力了——强行用 CSS 实现只会产出非常 trick 的 hack违背技术选型的初衷。“能不能用 CSS 实现”本身也是一种选型能力。前端工具箱里不止 JS 一把锤子HTML 标签提供语义与基础交互CSS 提供样式、动画与滚动/定位能力JS 负责复杂状态与过程控制。综合使用技术工具才能让代码更少、性能更好、维护成本更低。结语本文基于前端精读周刊的《不再需要 JS 做的 5 件事》完整还原了 SVG 线条动画、hover 侧边栏、sticky 黏性定位、details 手风琴、暗色主题这 5 个零 JS 方案并追加了 scroll-snap 幻灯片滚动与原生颜色选择器两个实战补充。这些能力在现代浏览器中都是开箱即用的标准特性建议在真实项目中优先评估“HTML/CSS 能否覆盖需求”再决定是否引入 JS——正确的技术选型往往从“不写那行 JS”开始。延伸阅读本仓库的《精读使用 CSS 属性选择器》可了解details[open]等属性选择器的更多用法《精读使用 css 变量生成颜色主题》深入讲解主题换肤工程实践《精读 CSS Animations vs Web Animations API》帮助你判断动画场景何时用 CSS、何时交给 JS。赞分享文档技术博客教程【免费下载链接】weekly前端精读周刊。帮你理解最前沿、实用的技术。项目地址https://gitcode.com/GitHub_Trending/we/weekly点击查看免费下载相关推荐终极指南为什么现代前端开发不再需要jQuery原生JavaScript替代方案全解析终极指南为什么现代前端开发不再需要jQuery原生JavaScript替代方案全解析 在当今快速发展的前端生态系统中jQuery作为曾经的DOM操作利器教程前端现代前端开发指南为什么你可能不再需要jQuery现代前端开发指南为什么你可能不再需要jQuery 在当今的前端开发生态中YouMightNotNeedjQuery项目为开发者提供了一个重要的参考资源展示前端教程高级开发者必看youmightnotneedjquery项目源码架构深度分析高级开发者必看youmightnotneedjquery项目源码架构深度分析 在现代前端开发中jQuery曾经是必不可少的工具库但随着浏览器标准的完善和现前端教程上一篇144Hz显示器却锁60帧艾尔登法环帧率解锁终极方案照抄就能跑通下一篇ncmdumpGUI保姆级教程三步把网易云NCM文件还原成MP3、FLAC夺回你的音乐收藏创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进