paint worklet 是浏览器提供的底层绘制 api,需通过 css.paintworklet.addmodule() 加载独立 js 文件并用 registerpaint 注册后,才能在 css paint() 中调用;不支持内联、跨域或旧版浏览器。

Paint Worklet 是什么,为什么不能直接写在 CSS 里
Paint Worklet 不是 CSS 函数,也不是 HTML 属性,它是一套浏览器提供的底层绘制 API,必须通过 registerPaint 注册后,才能在 CSS 的 paint() 函数中调用。直接在样式里写 background: paint(myPattern) 而不注册,控制台会报 TypeError: Failed to execute 'registerProperty' on 'CSS': The name is not a valid CSS identifier 或更常见的 Invalid property value —— 这是因为浏览器根本没加载或没识别这个 worklet。
关键点:Worklet 必须单独作为 JS 文件加载,且需通过 CSS.paintWorklet.addModule() 加载,不能内联、不能用 eval、不能跨域(必须同源或配 CORS)。
- Worklet 文件必须是独立的
.js文件,不能写在<script></script>标签里 -
CSS.paintWorklet.addModule()是异步操作,要等它 resolve 后再应用相关 CSS,否则样式无效 - Chrome/Edge ≥ 88 支持,Firefox 和 Safari 当前(2024)仍不支持,别在生产环境默认启用
怎么写一个最简可用的 Paint Worklet
假设你要画一个带旋转动画的渐变圆点图案,worklet 文件(比如叫 dot-pattern.js)内容必须严格符合规范:
class DotPattern {
static get inputProperties() { return ['--dot-size', '--dot-color']; }
paint(ctx, geom, props) {
const size = props.get('--dot-size').value || 8;
const color = props.get('--dot-color').value || '#3b82f6';
ctx.fillStyle = color;
for (let x = 0; x <p>注意三点:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill8272" title="anything-to-html"><img
src="https://img.php.cn/upload/skill/000/000/081/179195588450431.jpg" alt="anything-to-html" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill8272" title="anything-to-html" class="overflowclass">anything-to-html</a>
<p class="overflowclass">将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。</p>
</div>
<a rel="nofollow" href="/xiazai/skill8272" title="anything-to-html" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
-
registerPaint第一个参数是字符串名,必须和 CSS 中paint(dot-pattern)完全一致(区分大小写) -
inputProperties列出所有要从 CSS 读取的自定义属性,必须以--开头,且在使用前要在元素上声明(如style="--dot-size: 6") -
paint()方法里不能访问 DOM、window、document,也不能用setTimeout或fetch—— Worklet 是沙箱环境
CSS 怎么安全调用 paint() 且降级
不能裸写 background: paint(dot-pattern)。浏览器不支持时会整个丢弃该声明,导致背景变透明或继承默认色。要用 @supports 包裹,并提供 fallback:
.patterned {
background-color: #f9fafb; /* fallback */
background-image: url("data:image/svg+xml,%3Csvg..."); /* 可选 SVG fallback */
}
@supports (background: paint(dot-pattern)) {
.patterned {
background-image: paint(dot-pattern);
--dot-size: 10;
--dot-color: #10b981;
}
}
常见错误:
- 把
paint()写在background复合属性里(如background: paint(...) no-repeat),会导致整个声明失效 —— 必须用background-image - 忘记在元素上设置
--dot-size等自定义属性,Worklet 里读到的是 undefined,可能报Cannot read property 'value' of null - 在伪元素(
::before)上用paint()时,若父元素没设position: relative,可能导致定位错乱(因为geom基于伪元素盒模型)
调试 Paint Worklet 的实际技巧
Chrome DevTools 的 Rendering 面板里有 “Paint Profiler”,但对 Worklet 友好度低。更实用的方法是:
- 在 Worklet 文件开头加
console.log('dot-pattern loaded')—— 如果没输出,说明addModule()失败(检查路径、CORS、MIME 类型是否为text/javascript) - 在
paint()里临时加ctx.fillRect(0,0,10,10)和console.log(geom),确认是否被调用及尺寸是否合理 - 用
CSS.supports('background', 'paint(dummy)')在控制台快速验证环境支持性 - 修改 worklet 文件后,必须硬刷新(Ctrl+Shift+R),因为 Worklet 缓存极强,Service Worker 更会加剧这个问题
真正难的不是写法,而是接受它“不可交互、无 DOM、无状态”的限制——你没法响应鼠标事件,也不能动态改 canvas 内容,所有变化都得靠 CSS 自定义属性触发重绘。这点容易被教程忽略,但决定了它只适合静态/半静态图案,而非复杂 UI 绘制。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










