For AI agents: the complete documentation index is available at https://lazygophers.github.io/pamphlet/llms.txt, the full documentation bundle is available at https://lazygophers.github.io/pamphlet/llms-full.txt, and this page is available as Markdown at https://lazygophers.github.io/pamphlet/write/html.md.
  • 简体中文
  • 裸 HTML

    这是什么

    源文档里可以直接写 HTML 标签,编译器不做任何过滤:<style> 标签、style 属性、内联 <svg> 全部原样进产物。

    没有 allow-html 这个开关 —— 不是「默认关」,是没有这个概念。

    安全上的唯一防线是产物里那份严格 CSP(内容安全策略:浏览器执行的一份「什么能跑、什么不能跑」的清单)。

    CSP 挡住了什么

    以下全部实测过:

    源文档里写的产物里的结果
    <script>alert(1)</script>被拦 —— script-src 只允许运行时那一个哈希
    <img onerror="..."> 等内联事件属性被拦 —— 内联事件处理器需要 'unsafe-inline'
    <iframe src="https://...">被拦 —— default-src 'none'
    <img src="https://...">被拦 —— img-src 只允许 data:
    <form action="https://...">表单可显示,提交去向被拦

    没挡住的两样

    这两条是明知的、被接受的设计后果,不是 bug。

    一、<style> 标签和 style 属性。 style-src 'unsafe-inline' 是那份 CSP 唯一的松口 —— 样式全部内联,没有别的写法。

    因此源文档里一段 <style> 可以盖掉整个主题系统。

    最常见的来路是复制粘贴

    从别处复制一段带 style 的 HTML 片段贴进文档,然后发现主题坏了 —— 这不是 bug,是设计。

    想改样式的正确做法见换一套主题色,不是往文档里塞 <style>。

    二、内联 <svg>。 它绕过整条图表管线:

    • 不经过 SVG 消毒 —— 可以带 <animate> 等 SMIL 标签,那正是消毒规则明确不放行的东西
    • 不经过颜色替换 —— 切到深色模式时它不会跟着变

    也就是说 SVG 有两条待遇完全不同的路径:引擎产出的 SVG 被严格消毒,作者手写的 SVG 完全不受约束。如果你基于「所有 SVG 都被消毒过」做了别的判断,会踩空。

    为什么不过滤

    考虑过三种更严的做法,全部落选:

    • 剥掉 <style> / style 属性,把内联 <svg> 送进消毒和换色:精确对应 CSP 挡不住的部分。落选。
    • 整体走 DOMPurify 默认白名单:不用自己设计规则,但默认名单随版本漂移,而且它默认就放行 style 属性和 <svg>,并不解决上面两个问题。落选。
    • 原样通过但对 style 给警告:保留作者控制权。落选。

    选原样通过的收益是行为最可预期:作者写什么就是什么,等于 CommonMark 加一个 HTML 渲染器,零意外。这也让「兼容纯 Markdown」这条承诺没有任何例外。

    如果日后要收紧,第一个该收的是 style 属性 —— 它的收益(保住主题系统)最大、对作者的损失最小。

    出处:ADR-0021

    顺带一提:行内公式

    数学公式只有块级围栏,不支持行内 $E=mc^2$。上标下标可以用 <sup> / <sub> 这两个 HTML 标签顶一下。原因和绕行办法见其余七种图表。