css变量不能直接写在中,因其内容被浏览器跳过解析;须通过js将变量注入组件容器并用类名限定作用域,如.theme-light{--card-bg:#fff},再由组件样式var(--card-bg)引用。

为什么直接在 <template></template> 里写 CSS 变量没用
浏览器解析 <template></template> 时会跳过其内容,<style></style> 标签不执行、CSS 变量不注册、:root 也不生效。你写的 --card-bg: #fff; 就是纯文本,不会进入 CSSOM。常见现象:克隆后插入 DOM,背景色仍是默认值,控制台查不到该变量。
<template></template> 组件的主题必须靠 JS 注入变量作用域
真正起作用的是把变量“挂”到组件容器上,而不是塞进模板内部。实操分三步:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 模板只保留结构和语义化 class(如
.card、.card-title),不写任何样式或变量 - 渲染时用 JS 创建一个包裹容器(如
const host = document.createElement('div')),并给它加上主题类(如host.className = 'card theme-light') - 在
:root或全局<style></style>中定义主题变量,但通过类名限定作用域:.theme-light { --card-bg: #fff; --card-border: #e0e0e0; },再让组件内样式用background: var(--card-bg)
避免变量污染:命名空间 + 作用域限定是刚需
如果你的 <template></template> 要复用于多个主题(比如 light/dark/card/panel),不加隔离会互相覆盖。关键点:
- 变量名必须带前缀,如
--card-bg、--panel-shadow,禁用--bg这类泛义名 - 不要把所有主题变量都堆在
:root;而是用类名切换变量值:.theme-dark { --card-bg: #1f2937; --card-text: #f9fafb; } - 若组件需独立于页面主题(比如嵌入第三方站点的卡片),改用内联 style 注入变量:
host.style.cssText = '--card-bg: #fff; --card-text: #333;';
动态更新主题时,别忘了重置变量作用域
用户点击切换主题后,仅改 类名不够——如果旧主题变量仍挂在某个已渲染的 <div class="card"> 上,新变量不会自动继承。必须:
<ul>
<li>每次更新前清空旧容器的 class 列表(<code>host.className = '')
host.classList.add('theme-dark'))host.setAttribute('data-theme', 'dark') 配合属性选择器 [data-theme='dark'] { --card-bg: ... }
容易被忽略的是:Shadow DOM 场景下,:root 变量不可穿透,必须显式在 shadowRoot 内注入 <style></style> 或用 getComputedStyle(host).getPropertyValue('--card-bg') 手动读取再设 inline style。










