常见问题
关于使用方式、原理、兼容性与模板生态的常见疑问。
使用
我必须使用某个命令行工具吗?
不需要。这套方案的本质,就是在每个 HTML 的 </body> 之前插入一段文本。你完全可以用现有的发布流程:手动粘贴、写个几行的脚本、接到 CI 里,都行。工具不重要,格式对了就可以。
页面里要写什么,不该写什么?
写:页面的正文内容,放在 <article> 里;以及只服务于这段内容的样式。
不写:站点的 header、侧边栏、footer、站点级导航。这些属于模板,整站共享一份。
区分标准很简单:如果换个页面还是同样的东西,它就不属于页面,属于模板。
已有网站想迁移,工作量大吗?
取决于现状。基本流程是:
- 从现有页面里抽出 header / 导航 / footer,合成一份模板文件。
- 把每个页面里重复的这些部分删掉,只留下正文。
- 按新流程发布(在发布前注入模板)。
页面越多、越同质,收益越大。如果站点本来页面就少、风格随意,可以先只对新增页面用这套流程。
一个网站能用多个模板吗?
可以,而且很常见。典型做法是按一级菜单分板块,每个板块一套模板——比如"博客模板""文档模板""产品模板"。注入时按页面归属选择对应的模板文件即可。
原理
为什么用 Shadow DOM,而不是 iframe?
iframe 也能做到样式隔离,但代价明显:SEO 不友好、无法共享字体和滚动上下文、每个页面都要多发一次请求、跨文档通信要走 postMessage。
声明式 Shadow DOM 在同一个文档里完成隔离,没有这些负担:内容就在 HTML 里、爬虫能读、浏览器原生渲染、页面和模板共享同一份字体与滚动。
样式真的完全隔离吗?
是双向隔离,但有两处会穿透边界:
- 可继承属性:
color、font-family、line-height、font-size等会从宿主继承进 Shadow DOM。 - CSS 自定义属性:
--var会穿透边界,可以当设计令牌用。
前者需要在模板里显式重置(比如 :host { font-family: ... }),后者正是"换肤"的钩子。
页面能主动控制模板吗?
能,通过 CSS 自定义属性。模板里如果用 var(--brand-color, #4f46e5) 这类写法,页面或站点就可以在宿主上统一覆盖:
/* 站点或页面里的某处 */
html {
--brand-color: #7c3aed;
}
模板读到这个变量就会自动应用新色值。这是"一键整站换肤"的技术基础——不用改模板、不用改页面,改一个变量即可。
页面里的 position: sticky 还能用吗?
能。页面内容自己的定位不受模板影响;模板里的 sticky(比如吸顶导航)也只在模板的坐标系里工作。两者互不干扰。
工程
浏览器兼容性如何?
声明式 Shadow DOM(shadowrootmode 属性)已经在主流浏览器落地:
- Chrome / Edge 111+
- Safari 16.4+
- Firefox 123+
旧浏览器会忽略 <template>,页面仍然能显示内容,只是没有站点布局。不会报错,也不会白屏。
对 SEO 有影响吗?
没有负面影响。页面内容和模板都在同一个 HTML 文档里,爬虫能抓取到全部内容——这也是它比 iframe 更适合静态站的原因。
对性能有影响吗?
几乎没有。不引入额外请求,不引入运行时脚本,也不需要构建步骤。浏览器解析声明式 Shadow DOM 是原生行为,和解析普通元素的开销相当。
会不会出现内容闪烁?
不会。声明式 Shadow DOM 是 HTML 解析的一部分,跟普通标签一样即时渲染,不像运行时 JS 注入那样会有先渲染再补布局的闪烁。
对无障碍(a11y)有影响吗?
大部分场景不受影响:<slot> 投影的内容仍然在被投影的位置参与无障碍树。需要留意的是跨边界的标题层级——比如模板里的站点标题如果用 <h1>,会和页面正文的 <h1> 冲突。建议模板里用 <h2> 或 <div> 承担站点标题。
生态
换肤具体怎么做?
替换模板文件即可。整站共用一份模板,改一处、全站生效。如果模板对设计令牌做了充分参数化(颜色、圆角、字体都走 CSS 变量),甚至可以在不改模板文件的前提下,只覆盖变量完成主题切换。
会有模板市场吗?
这是项目的愿景之一。模板是纯文本文件,天然可被分享、收集、交易。一套精良的模板可以直接服务成千上万个页面——这种"一份模板、无限复用"的特性,正是模板生态能成立的前提。