Canvas不解析CSS变量,需用getComputedStyle().getPropertyValue()读取并trim()后赋值;高频绘制应缓存变量避免强制布局;注意色域、缩放、深色模式及主题切换后重绘。

Canvas不认CSS变量,必须手动“翻译”
直接写 ctx.fillStyle = "var(--primary-color)" 会静默失败,Canvas 渲染为黑色或透明——这不是 bug,是 Canvas 2D 上下文根本不解析 CSS 语法。它只接受最终计算出的颜色字符串:"#3b82f6"、"rgb(59, 130, 246)"、"LightGreen"(注意大小写),其他一律忽略。
用 getComputedStyle 安全读取变量值
这是唯一可靠方式,但容易踩坑:
- 必须传入已挂载的元素,读全局变量用
document.documentElement;读组件级变量(如<div id="chart" style="--bg: #1e293b">)就得传 <code>document.getElementById("chart") - 必须用
.getPropertyValue('--primary-color'),不是.style.--primary-color(语法错误),也不是.cssText(不包含变量值) - 返回值是字符串,但可能带前导/尾随空格或换行,务必加
.trim();否则 Safari 旧版直接忽略,ctx.fillStyle失效变黑 - 变量未定义时返回空字符串
"",不是undefined,别用== null判断,建议兜底:const color = getComputedStyle(root).getPropertyValue('--primary').trim() || '#000' - 主题初始化或
themechange事件中读一次,缓存为 JS 变量 - 后续所有绘图直接用缓存值,比如
ctx.fillStyle = primaryColor - 如果变量本身是
rgba(59, 130, 246, 0.8)这类格式,Canvas 原生支持,但确保 alpha 是小数(0.8),不是百分比(80%) - Canvas 不做色彩管理,忠实地把输入值映射到 sRGB 输出通道;若设计稿来自 P3 色域(如 macOS Display P3 屏),数值相同但感知不同
-
canvas.width/canvas.height和canvas.style.width/canvas.style.height不一致时,图形被拉伸,抗锯齿混入额外像素,间接改变边缘颜色感知 - 深色模式下系统自动提亮文字(Chrome 对
color-scheme: dark的补偿)不会影响 Canvas 内文本渲染,导致 DOM 文字与 Canvas 文字明暗不一致
高频绘制时别反复调用 getComputedStyle
在 requestAnimationFrame 或动画循环里每帧都读,会触发强制同步布局,明显卡顿。正确做法是:
颜色一致 ≠ 视觉一致,还要防色域和缩放干扰
即使你读对了、赋对了,Canvas 里画出来的颜色仍可能“发灰”或“偏暗”,原因不在代码逻辑,而在底层:
立即学习“前端免费学习笔记(深入)”;
--primary-color,却忘了调用 ctx.clearRect() 和重新执行绘图逻辑。


















