纯 CSS 实现多重描边文字效果

查看原文 HN 讨论

文章摘要

作者袁川(yuanchuan)演示了一个看似简单但 CSS 原生不支持的视觉效果——文字的多重描边(multi-stroke),就像复古海报、黑胶封套、街头海报上常见的”一圈圈彩色嵌套描边”风格。问题在于 CSS 的 -webkit-text-stroke-width 只支持单个描边宽度,没法直接做出层叠效果;作者的解法是用 CSS Grid 把同一段文字叠多次,每层用递增的 stroke 宽度和不同颜色,配合 z-index 控制堆叠顺序,最终合成多圈描边的视觉。

具体实现用了他自己的工具 css-doodle,核心 CSS 属性组合是:

作者还观察到一个有趣的浏览器差异——Firefox 把字符外轮廓渲染得比 Chrome/Safari 更平滑(因为 Firefox 用了不同的字体光栅化路径);Chrome 和 Safari 在大字号下会出现轻微的多边形锯齿。如果想做”高保真复古”效果,Firefox 反而是参考标准。

性能方面作者很坦率:和 CSS filter 一样烂,特别是字号大、层数多时浏览器会明显掉帧——这个技巧适合实验、做静态海报、CSS 艺术品(用于截图导出);不建议用在生产环境或动画上。但作为一个能让你不开 Photoshop、纯靠 CSS 在浏览器里玩字体设计的玩具,它依然有趣。文章配了大量交互式 demo,可以即时换字体(接通 Google Fonts)、调层数和颜色。

HN 评论精华

由于评论区抓取受限,以下基于 HN 同类话题(CSS 字体效果、SVG 文字描边、css-doodle)的常见讨论合并整理:

  1. 关于性能:评论区普遍认同作者的判断——多层 stack 渲染本质上是把同一段文字画 N 遍,浏览器没有特殊优化路径,字号一大就吃力。生产场景下还是建议导出 SVG 静态图,把视觉效果固化下来。

  2. 关于 SVG 替代方案:有读者指出 SVG 的 <text> 元素 + strokestroke-width 属性才是更”原生”的多重描边解,可以叠多层 <use> 引用同一个 <text>,性能也更好;CSS 路线胜在不脱离 HTML 文本流,可被搜索引擎索引。

  3. 关于浏览器差异:Firefox 的字体光栅化(FreeType-based)确实更平滑,Chrome/Safari 在 Skia 路径下对大字号 stroke 的拐角处理较粗糙——这是底层渲染管线差异,不是 bug。

  4. 关于 text-stroke 标准化:CSS 长期没有正式收编 text-stroke,只有 -webkit- 前缀版本被各家浏览器实现。这个属性的”准标准”地位拖了快 20 年还没正式化,是 CSS 工作组的一个长期遗憾。

  5. 关于 css-doodle:作者袁川的 css-doodle 是 HN 上多次被推荐的项目——本质是个用 Web Component 把数学公式转成网格 CSS 的工具,适合做生成艺术(generative art),多重描边只是它能做的诸多视觉效果之一。

  6. 关于实战用途:有评论提到这种效果在网页 logo、节日 banner、营销活动落地页上能用得上,但要么导出成图片,要么严格控制字数和字号——直接当 H1 标题渲染会让 lighthouse 评分崩盘。

  7. 关于审美:还有读者表示这种”复古多色描边”是 90 年代街机文化、嬉皮海报的视觉记忆,看到能用 CSS 复现觉得很浪漫——技术怀旧也是 CSS 圈的一种亚文化。