CSS Painting API Level 1
CSS Painting API Level 1
Editor’s Draft
25 February 2026
More details about this document
This version:
Latest published version:
Previous Versions:
Feedback:
public-houdini@w3.org
with subject line “
[css-paint-api]
… message topic …
” (
archives
GitHub
Editors:
Ian Kilpatrick
Dean Jackson
Former Editor:
Shane Stephens
World Wide Web Consortium
W3C
liability
trademark
and
permissive document license
rules apply.
Abstract
An API for allowing web developers to define a custom CSS
with javascript, which will
respond to style and size changes.
See
EXPLAINER
Status of this document
This is a public copy of the editors’ draft.
It is provided for discussion only and may change at any moment.
Its publication here does not imply endorsement of its contents by W3C.
Don’t cite this document other than as work in progress.
Please send feedback
by
filing issues in GitHub
(preferred),
including the spec code “css-paint-api” in the title, like this:
“[css-paint-api]
…summary of comment…
”.
All issues and comments are
archived
Alternately, feedback can be sent to the (
archived
) public mailing list
www-style@w3.org
This document is governed by the
18 August 2025 W3C Process Document
1.
Introduction
The paint stage of CSS is responsible for painting the background, content and highlight of a
box based on that box’s size (as generated by the layout stage) and computed style.
This specification describes an API which allows developers to paint a part of a box in
response to size / computed style changes with an additional
function.
Note:
In a future version of the spec, support could be added for defining the clip, global alpha,
filter on a portion of a box (for example on the background layers).
2.
Paint Worklet
The
paintWorklet
attribute allows access to the
Worklet
responsible for all the classes
which are related to painting.
The
paintWorklet
’s
worklet global scope type
is
PaintWorkletGlobalScope
The
paintWorklet
’s
worklet destination type
is
"paintworklet"
partial
namespace
CSS
SameObject
readonly
attribute
Worklet
paintWorklet
};
PaintWorkletGlobalScope
is a global execution context of the
paintWorklet
PaintWorkletGlobalScope
has a
devicePixelRatio
property which is
identical to the Window.
devicePixelRatio
property.
Global
=(
Worklet
PaintWorklet
),
Exposed
PaintWorklet
interface
PaintWorkletGlobalScope
WorkletGlobalScope
undefined
registerPaint
DOMString
name
VoidFunction
paintCtor
);
readonly
attribute
unrestricted
double
devicePixelRatio
};
The
PaintRenderingContext2DSettings
contains the settings for the rendering context associated
with the paint canvas. The
PaintRenderingContext2DSettings
provides a supported subset of canvas
rendering context 2D settings. In the future, it may be extended to support color management in
paint canvas.
dictionary
PaintRenderingContext2DSettings
boolean
alpha
true
};
Note: The shape of the class should be:
class
MyPaint
static
get inputProperties
()
return
'--foo'
];
static
get inputArguments
()
return
'
];
static
get contextOptions
()
return
alpha
true
};
paint
ctx
size
styleMap
// Paint code goes here.
3.
Concepts
paint definition
is a
struct
which describes the information needed by the
PaintWorkletGlobalScope
about the author defined
(which can be referenced by the
function). It consists of:
class constructor
which is the class
constructor
paint function
which is the paint
Function
callback function
type.
constructor valid flag
input properties
which is a
list
of
DOMStrings
PaintRenderingContext2DSettings object
document paint definition
is a
struct
which describes the information
needed by the
document
about the author defined
function (which can be referenced
by the paint function). It consists of:
input properties
which is a
list
of
DOMStrings
input argument syntaxes
which is a
list
of
syntax definitions
PaintRenderingContext2DSettings object
4.
Registering Custom Paint
The
document
has a
map
of
document paint definitions
. Initially
this map is empty; it is populated when
registerPaint(name, paintCtor)
is called.
PaintWorkletGlobalScope
has a
map
of
paint definitions
. Initially this map
is empty; it is populated when
registerPaint(name, paintCtor)
is called.
PaintWorkletGlobalScope
has a
map
of
paint class instances
. Initially this
map is empty; it is populated when
draw a paint image
is invoked by the user agent.
Instances of paint classes in the
paint class instances
map may be disposed and removed from
the map by the user agent at any time. This may be done when a
function no longer is
used, or the user agent needs to reclaim memory.
When the
registerPaint(
name
paintCtor
method is
called, the user agent
must
run the following steps:
If the
name
is an empty string,
throw
TypeError
and abort all these steps.
Let
paintDefinitionMap
be
PaintWorkletGlobalScope
’s
paint definitions
map.
If
paintDefinitionMap
name
exists
throw
InvalidModificationError
DOMException
and abort all these steps.
Let
inputProperties
be an empty
sequence
Let
inputPropertiesIterable
be the result of
Get
paintCtor
, "inputProperties").
If
inputPropertiesIterable
is not undefined, then set
inputProperties
to the result of
converting
inputPropertiesIterable
to a
sequence
. If an
exception is
thrown
, rethrow the exception and abort all these steps.
Filter
inputProperties
so that it only contains
supported CSS properties
and
custom properties
Note:
The list of CSS properties provided by the input properties getter can either be custom or
native CSS properties.
Note:
The list of CSS properties may contain shorthands.
Note:
In order for a paint image class to be forwards compatible, the list of CSS properties can
also contains currently invalid properties for the user agent. For example
margin-bikeshed-property
Let
inputArguments
be an empty
sequence
Let
inputArgumentsIterable
be the result of
Get
paintCtor
, "inputArguments").
If
inputArgumentsIterable
is not undefined, then set
inputArguments
to the result of
converting
inputArgumentsIterable
to a
sequence
. If an
exception is thrown, rethrow the exception and abort all these steps.
Let
inputArgumentSyntaxes
be an
empty
list
For each
item
in
inputArguments
perform the following substeps:
Attempt to
consume a syntax definition
from
item
If failure was returned,
throw
TypeError
and abort all these steps.
Otherwise, let
parsedSyntax
be the returned
syntax definition
Append
parsedSyntax
to
inputArgumentSyntaxes
Let
contextOptionsValue
be the result of
Get
paintCtor
, "contextOptions").
Let
paintRenderingContext2DSettings
be the result of
converting
contextOptionsValue
to a
PaintRenderingContext2DSettings
If an exception is
thrown
, rethrow the exception and abort all these steps.
Note:
Setting
paintRenderingContext2DSettings.alpha
is
false
allows user agents
to anti-alias text in addition to performing "visibility" optimizations, e.g. not
painting an image behind the paint image as the paint image is opaque.
If the result of
IsConstructor
paintCtor
) is false,
throw
TypeError
and abort all these steps.
Let
prototype
be the result of
Get
paintCtor
, "prototype").
If the result of
Type
prototype
) is not Object,
throw
TypeError
and
abort all these steps.
Let
paintValue
be the result of
Get
prototype
, "paint").
Let
paint
be the result of
converting
paintValue
to the
Function
callback function
type. Rethrow any exceptions from the conversion.
Let
definition
be a new
paint definition
with:
class constructor
being
paintCtor
paint function
being
paint
constructor valid flag
being
true
input properties
being
inputProperties
PaintRenderingContext2DSettings object
being
paintRenderingContext2DSettings
Set
paintDefinitionMap
name
] to
definition
Queue a task
to run the following steps:
Let
documentPaintDefinitionMap
be the associated
document’s
document paint definitions
map
Let
documentDefinition
be a new
document paint definition
with:
input properties
being
inputProperties
input argument syntaxes
being
inputArgumentSyntaxes
PaintRenderingContext2DSettings object
being
paintRenderingContext2DSettings
If
documentPaintDefinitionMap
name
exists
, run the following steps:
Let
existingDocumentDefinition
be the result of
get
documentPaintDefinitionMap
name
].
If
existingDocumentDefinition
is
"invalid"
, abort all these steps.
If
existingDocumentDefinition
and
documentDefinition
are not equivalent, (that is
input properties
input argument syntaxes
, and
PaintRenderingContext2DSettings object
are different), then:
Set
documentPaintDefinitionMap
name
] to
"invalid"
Log an error to the debugging console stating that the same class was registered
with different
inputProperties
inputArguments
, or
paintRenderingContext2DSettings
Otherwise,
set
documentPaintDefinitionMap
name
] to
documentDefinition
Note:
The list of input properties should only be looked up once, the class doesn’t have the
opportunity to dynamically change its input properties.
Note:
In a future version of the spec, the author could have the ability to receive a different type
of RenderingContext. In particular the author may want a WebGL rendering context to render 3D
effects. There are complexities in setting up a WebGL rendering context to take the
PaintSize
and
StylePropertyMap
as inputs.
5.
Paint Notation
paint()
= paint(
The
function is an additional notation to be supported by the
type.
style
logo
background-image
paint
company
-logo
);
chat-bubble
background-image
paint
chat
-bubble
blue
);
style
For the
cursor
property, the
function should be treated as an
invalid image
and
fallback to the next supported
At
computed value
time the
function does
not
need to match the grammar
registered by
registerPaint()
. Instead this will result in an
invalid image
when the
parsing occurs inside
draw a paint image
6.
The 2D rendering context
Exposed
PaintWorklet
interface
PaintRenderingContext2D
};
PaintRenderingContext2D
includes
CanvasState
PaintRenderingContext2D
includes
CanvasTransform
PaintRenderingContext2D
includes
CanvasCompositing
PaintRenderingContext2D
includes
CanvasImageSmoothing
PaintRenderingContext2D
includes
CanvasFillStrokeStyles
PaintRenderingContext2D
includes
CanvasShadowStyles
PaintRenderingContext2D
includes
CanvasRect
PaintRenderingContext2D
includes
CanvasDrawPath
PaintRenderingContext2D
includes
CanvasDrawImage
PaintRenderingContext2D
includes
CanvasPathDrawingStyles
PaintRenderingContext2D
includes
CanvasPath
Note:
The
PaintRenderingContext2D
implements a subset of the
CanvasRenderingContext2D
API.
Specifically it doesn’t implement the
CanvasImageData
CanvasUserInterface
CanvasText
, or
CanvasTextDrawingStyles
APIs.
PaintRenderingContext2D
object has a
output bitmap
This is initialised when the object is created.
The size of the
output bitmap
is the
concrete object size
of the object it is rendering to.
PaintRenderingContext2D
object also has an
alpha
flag,
which can be set to true or false.
Initially, when the context is created,
its alpha flag must be set to true.
When a
PaintRenderingContext2D
object has its alpha flag set to false,
then its alpha channel must be fixed to 1.0 (fully opaque) for all pixels,
and attempts to change the alpha component of any pixel must be silently ignored.
The size of the
output bitmap
does not necessarily represent the size of the actual bitmap
that the user agent will use internally or during rendering. For example, if the visual viewport is
zoomed the user agent may internally use bitmaps which correspond to the number of device pixels in
the coordinate space, so that the resulting rendering is of high quality.
Additionally the user agent may record the sequence of drawing operations which have been applied to
the
output bitmap
such that the user agent can subsequently draw onto a device bitmap at the
correct resolution. This also allows user agents to re-use the same output of the
output bitmap
repeatably while the visual viewport is being zoomed for example.
Whenever
"currentColor"
is used as a color in the
PaintRenderingContext2D
API, it
is treated as opaque black.
The code below will produce a solid black rectange.
registerPaint
'currentcolor'
class
paint
ctx
size
ctx
fillStyle
'currentColor'
ctx
fillRect
size
width
size
height
);
});
When the user agent is to
create a PaintRenderingContext2D object
for a given
width
height
, and
paintRenderingContext2DSettings
, it
must
run the following steps:
Create a new
PaintRenderingContext2D
Set bitmap dimensions
for the context’s
output bitmap
to the rounded values of
width
and
height
Set the
PaintRenderingContext2D
’s
alpha
flag to
paintRenderingContext2DSettings
’s
alpha
Return the new
PaintRenderingContext2D
Note:
The initial state of the rendering context is set inside the
set bitmap dimensions
algorithm, as it invokes
reset the rendering context to its default state
and clears the
output bitmap
6.1.
Drawing a CSSImageValue
The
CanvasImageSource
typedef is extended to also include the
CSSImageValue
type to be used
as an image source.
For interfaces which use the
CanvasDrawImage
mixin:
When a
CanvasImageSource
object represents an
CSSImageValue
, the result of invoking
the value’s underlying image algorithm must be used as the source image for the purposes of
drawImage
Note:
This should eventually be moved to the canvas section of the HTML specification.
See
Issue 819
7.
Drawing an image
If a
function image for a
box
is within the visual viewport, the user agent
must
display an image output from an invocation of the
draw a paint image
algorithm.
Note:
The user agent doesn’t have to run
draw a paint image
each frame for a
function within the visual viewport. It can cache results, (potentially using additional
invalidation steps) to display the correct image output.
Note:
The user agent can optionally defer drawing images which are outside the visual viewport.
If an author updates a style inside a
requestAnimationFrame
, e.g.
requestAnimationFrame
function
()
element
styleMap
set
'--custom-prop-invalidates-paint'
42
);
});
And the
element
is inside the visual viewport, the user agent is required to
draw a paint image
and display the result for the current frame.
The
draw a paint image
function is invoked by the user agent during the
object size negotiation
algorithm which is responsible for rendering an
, with
snappedConcreteObjectSize
defined as follows. Let
concreteObjectSize
be the
concrete object size
of the
box
. The
snappedConcreteObjectSize
is usually the same as the
concreteObjectSize
. However, the user agent may adjust the size such that it paints to pixel
boundaries. If it does, the user agent should adjust the
snappedConcreteObjectSize
by the
proportional change from its original size such that the
function can adjust the drawing
accordingly.
For the purposes of the
object size negotiation
algorithm,
the paint image has no
natural dimensions
Note:
In a future version of the spec, the author could have the ability to specify the
natural dimensions
of the paint image. This will probably be exposed as a callback allowing the
author to define static
natural dimensions
or dynamically updating the
natural dimensions
based on computed style and size changes.
The
PaintSize
object represents the size of the image that the author should draw. This is
the
snappedConcreteObjectSize
given by the user agent.
Note:
See
CSS Images 3
§ 4.4 Examples of CSS Object Sizing
for examples on how the
concrete object size
is calculated.
The
draw a paint image
function may be speculatively invoked by the user agent at any point,
with any
snappedConcreteObjectSize
. The resulting image is not displayed.
Note:
User agents may use any heuristic to speculate a possible future value for
snappedConcreteObjectSize
, for example speculating that the size remains unchanged.
Note:
Although the image is not displayed, it may still be cached, and subsequent invocations of
may use the cached image.
Exposed
PaintWorklet
interface
PaintSize
readonly
attribute
double
width
readonly
attribute
double
height
};
When the user agent wants to
draw a paint image
of a
function for a
box
into its appropriate stacking level (as defined by the property the CSS property its associated
with), given
snappedConcreteObjectSize
it
must
run the following steps:
Let
paintFunction
be the
function on the
box
which the user agent wants to
draw.
Let
name
be the first argument of the
paintFunction
Let
documentPaintDefinitionMap
be the associated
document’s
document paint definitions
map.
If
documentPaintDefinitionMap
name
] does not
exist
, let the image output
be an
invalid image
and abort all these steps.
Let
documentDefinition
be the result of
get
documentPaintDefinitionMap
name
].
If
documentDefinition
is
"invalid"
, let the image output be an
invalid image
and abort all these steps.
Let
inputArgumentSyntaxes
be
documentDefinition
’s
input argument syntaxes
Let
inputArguments
be the
list
of all the
paintFunction
arguments
after
the "paint name" argument.
If
inputArguments
do not match the registered grammar given by
inputArgumentSyntaxes
, let
the image output be an
invalid image
and abort all these steps.
This step may fail in the following cases:
// paint.js
registerPaint
'failing-argument-syntax'
class
static
get inputArguments
()
return
'
];
paint
ctx
size
styleMap
args
/* paint code here. */
});
style
example-1
background-image
paint
failing
-argument-syntax
red
);
example-2
background-image
paint
failing
-argument-syntax
px
px
);
style
div
class
example-1
>
div
div
class
example-2
>
div
script
CSS
paintWorklet
addModule
'paint.js'
);
script
example-1
produces an
invalid image
as
"red"
does not
match the registered grammar.
example-2
produces an
invalid image
as there are too many function
arguments.
Let
workletGlobalScope
be a
PaintWorkletGlobalScope
from the the paint
Worklet
’s
global scopes
, following the rules defined in
§ 7.1 Global Scope Selection
The user agent
may
also
create a worklet global scope
at this time, given the
paint
Worklet
Run
invoke a paint callback
given
name
inputArguments
snappedConcreteObjectSize
workletGlobalScope
optionally
in parallel
Note:
If the user agent runs
invoke a paint callback
on a thread
in parallel
it should select a paint worklet global scope which can be used on that thread.
When the user agent wants to
invoke a paint callback
given
name
inputArguments
snappedConcreteObjectSize
, and
workletGlobalScope
, it
must
run the following steps:
Let
paintDefinitionMap
be
workletGlobalScope
’s
paint definitions
map.
If
paintDefinitionMap
name
] does not
exist
, run the following steps:
Queue a task
to run the following steps:
Let
documentPaintDefinitionMap
be the associated
document
’s
document paint definitions
map.
Set
documentPaintDefinitionMap
name
] to
"invalid"
The user agent
should
log an error to the debugging console stating that a
class wasn’t registered in all
PaintWorkletGlobalScope
s.
Let the image output be an
invalid image
and abort all these steps.
Note:
This handles the case where there could be a paint worklet global scope which didn’t
receive the
registerPaint(name, paintCtor)
for
name
(however another global scope
did). A paint callback which is invoked on the other global scope could succeed, but
wont succeed on a subsequent frame when
draw a paint image
is called.
Let
definition
be the result of
get
paintDefinitionMap
name
].
Let
paintClassInstanceMap
be
workletGlobalScope
’s
paint class instances
map.
Let
paintInstance
be the result of
get
paintClassInstanceMap
[|name]|. If
paintInstance
is null, run the following steps:
If the
constructor valid flag
on
definition
is false, let the image output be an
invalid image
and abort all these steps.
Let
paintCtor
be the
class constructor
on
definition
Let
paintInstance
be the result of
Construct
paintCtor
).
If
construct
throws an exception,
set the
definition
’s
constructor valid flag
to false,
let the image output be an
invalid image
and abort all these
steps.
Set
paintClassInstanceMap
name
] to
paintInstance
Let
inputProperties
be
definition
’s
input properties
Let
styleMap
be a new
StylePropertyMapReadOnly
populated with
only
the
computed value
’s for properties listed in
inputProperties
Let
renderingContext
be the result of
create a PaintRenderingContext2D object
given:
"width" - The width given by
snappedConcreteObjectSize
"height" - The height given by
snappedConcreteObjectSize
"paintRenderingContext2DSettings" - The
PaintRenderingContext2DSettings object
given by
definition
Note:
The
renderingContext
is not be re-used between invocations of paint. Implicitly this
means that there is no stored data, or state on the
renderingContext
between
invocations. For example you can’t setup a clip on the context, and expect the same clip
to be applied next time the paint method is called.
Note:
Implicitly this also means that
renderingContext
is effectively "neutered" after a
paint method is complete. The author code may hold a reference to
renderingContext
and
invoke methods on it, but this will have no effect on the current image, or subsequent
images.
Let
paintSize
be a new
PaintSize
initialized to the width and height defined by
snappedConcreteObjectSize
At this stage the user agent may re-use an image from a previous invocation if
paintSize
styleMap
inputArguments
are equivalent to that previous invocation. If so let the image
output be that cached image and abort all these steps.
In the example below, both
div-1
and
div-2
have paint
functions which have equivalent javascript arguments. A user-agent can cache the result
of one invocation and use it for both elements.
// paint.js
registerPaint
'simple'
class
paint
ctx
size
ctx
fillStyle
'green'
ctx
fillRect
size
width
size
height
);
});
style
div-1
width
50
px
height
50
px
background-image
paint
simple
);
div-2
width
100
px
height
100
px
background-size
50
50
background-image
paint
simple
);
style
div
class
div-1
>
div
div
class
div-2
>
div
script
CSS
paintWorklet
addModule
'paint.js'
);
script
Let
paintFunctionCallback
be
definition
’s
paint function
Invoke
paintFunctionCallback
with arguments «
renderingContext
paintSize
styleMap
inputArguments
» and "`rethrow`", and with
paintInstance
as the
callback this value
If
paintFunctionCallback
does not complete within an acceptable time (as determined by the
user agent, i.e. it is a "long running script") the user agent
may
terminate the
script, let the image output be an
invalid image
, and abort all these steps.
Note:
User agents could provide tooling within their debugging tools to show authors how
expensive their paint classes are. User agents could also how an "unresponsive script"
dialog in this case if appropriate.
The image output is to be produced from the
renderingContext
given to the method.
If an exception is
thrown
the let the image output be an
invalid image
Note:
The contents of the resulting image are not designed to be accessible. Authors can communicate
any useful information through the standard accessibility APIs.
7.1.
Global Scope Selection
When the user agent needs to select a
PaintWorkletGlobalScope
from the paint
Worklet
’s
global scopes
list
it
must
Select from at
least
two
PaintWorkletGlobalScope
s, unless the user agent is under
memory constraints.
Not
re-use the same
PaintWorkletGlobalScope
more than 1000 times in a row.
Note:
The 1000 limit was picked as a high upper bound, this limit may improve (downwards)
over time.
Note:
These rules exist to ensure that authors do not rely on being able to store state on the
global object or non-regeneratable state on the class. See
the
discussion in the worklets specification about code idempotence
8.
Examples
8.1.
Example 1: Colored Circle
The example below makes use of the fact that
functions are able to be animated. E.g.
when the textarea is focused in the example below, the
--circle-color
property will
transition from
deepskyblue
to
purple
This ability isn’t limited to just transitions, it also applies to CSS animations, and the Web
Animations API.
style
example
--circle-color
deepskyblue
background-image
paint
circle
);
font-family
sans-serif
font-size
36
px
transition
--
circle
color
example
focus
--circle-color
purple
style
textarea
id
"example"
CSS is awesome.
textarea
script
CSS
registerProperty
({
name
'--circle-color'
syntax
'
initialValue
'black'
inherits
false
});
CSS
paintWorklet
addModule
'circle.js'
);
script
// circle.js
registerPaint
'circle'
class
static
get inputProperties
()
return
'--circle-color'
];
paint
ctx
geom
properties
// Change the fill color.
const
color
properties
get
'--circle-color'
);
ctx
fillStyle
color
cssText
// Determine the center point and radius.
const
geom
width
const
geom
height
const
radius
Math
min
);
// Draw the circle \o/
ctx
beginPath
();
ctx
arc
radius
Math
PI
false
);
ctx
fill
();
});
8.2.
Example 2: Image Placeholder
It is possible for an author to use paint to draw a placeholder image while an image is being
loaded.
style
example
--image
url
'#someUrlWhichIsLoading'
);
background-image
paint
image
-with-placeholder
);
style
div
id
"example"
>
div
script
CSS
registerProperty
({
name
'--image'
syntax
'
initialValue
'none'
});
CSS
paintWorklet
addModule
'image-placeholder.js'
);
script
// image-placeholder.js
registerPaint
'image-with-placeholder'
class
static
get inputProperties
()
return
'--image'
];
paint
ctx
geom
properties
const
img
properties
get
'--image'
);
switch
img
state
case
'ready'
// The image is loaded! Draw the image.
ctx
drawImage
img
geom
width
geom
height
);
break
case
'pending'
// The image is loading, draw some mountains.
drawMountains
ctx
);
break
case
'invalid'
default
// The image is invalid (e.g. it didn't load), draw a sad face.
drawSadFace
ctx
);
break
});
8.3.
Example 3: Arcs
style
example
width
200
px
height
200
px
background-image
paint
arc
purple
0.4
turn
0.8
turn
40
px
15
px
),
paint
arc
blue
-20
deg
170
deg
30
px
20
px
),
paint
arc
red
45
deg
220
deg
50
px
10
px
);
style
div
id
"example"
>
div
script
CSS
paintWorklet
addModule
'arc.js'
);
script
// arc.js
registerPaint
'arc'
class
static
get inputArguments
()
return
'
'
// startAngle
'
// endAngle
'
// radius
'
// lineWidth
];
paint
ctx
geom
args
ctx
strokeStyle
args
].
cssText
// Determine the center point.
const
geom
width
const
geom
height
// Convert the start and end angles to radians.
const
startAngle
this
convertAngle
args
])
Math
PI
const
endAngle
this
convertAngle
args
])
Math
PI
// Convert the radius and lineWidth to px.
const
radius
this
convertLength
args
]);
const
lineWidth
this
convertLength
args
]);
ctx
lineWidth
lineWidth
ctx
beginPath
();
ctx
arc
radius
startAngle
endAngle
false
);
ctx
stroke
();
convertAngle
angle
switch
angle
unit
case
'deg'
return
angle
value
Math
PI
180
case
'rad'
return
angle
value
case
'grad'
return
angle
value
Math
PI
200
case
'turn'
return
angle
value
Math
PI
0.5
default
throw
Error
`Unknown angle unit:
${
angle
unit
);
convertLength
length
switch
length
type
case
'px'
return
length
value
default
throw
Error
`Unkown length type:
${
length
type
);
});
8.4.
Example 4: Different Colors (based on size)
h1
Heading 1
h1
h1
Another heading
h1
style
h1
background-image
paint
heading
-color
);
style
script
CSS
paintWorklet
addModule
'heading-color.js'
);
script
// heading-color.js
registerPaint
'heading-color'
class
static
get inputProperties
()
return
[];
paint
ctx
geom
properties
// Select a color based on the width and height of the image.
const
width
geom
width
const
height
geom
height
const
color
colorArray
[(
width
height
colorArray
length
];
// Draw just a solid image.
ctx
fillStyle
color
ctx
fillRect
width
height
);
});
8.5.
Example 5: Drawing outside an element’s area
It is possible to draw outside an element’s area by using the
border-image
property.
style
overdraw
--border-width
10
border-style
solid
border-width
calc
var
--border-width
px
);
border-image-source
paint
overdraw
);
border-image-slice
fill
border-image-outset
calc
var
--border-width
px
);
width
200
px
height
200
px
style
div
id
"overdraw"
>
div
script
CSS
paintWorklet
addModule
'overdraw.js'
);
script
// overdraw.js
registerPaint
'overdraw'
class
static
get inputProperties
()
return
'--border-width'
];
paint
ctx
geom
properties
const
borderWidth
parseInt
properties
get
'--border-width'
));
ctx
shadowColor
'rgba(0,0,0,0.25)'
ctx
shadowBlur
borderWidth
ctx
fillStyle
'rgba(255, 255, 255, 1)'
ctx
fillRect
borderWidth
borderWidth
geom
width
borderWidth
geom
height
borderWidth
);
});
9.
Security Considerations
There are no known security issues introduced by these features.
10.
Privacy Considerations
The timing of paint callbacks can be used as a high-bandwidth channel for detecting "visited" state for links.
details
This is not a fundamentally new privacy leak,
as visited state leaks from many interactions,
but absent any further mitigations,
this is a particularly high-bandwidth channel of the information.
No official mitigations are planned at this time,
as this privacy leak needs to be addressed more directly
to fix all such channels.
11.
Changes
Changes since the
9 August 2018 CR publication
Filtered the list of input properties to a paint worklet to be only known or custom properties.
Added alpha flag to
PaintRenderingContext2D
to control whether the rendering surface is forced opaque or allows transparency.
Fix definition for the size of the output bitmap:
The size of the output bitmap is the
concrete object size of the object it is rendering to
size of the fragment it is rendering
Conformance
Document conventions
Conformance requirements are expressed with a combination of
descriptive assertions and RFC 2119 terminology. The key words “MUST”,
“MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”,
“RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this
document are to be interpreted as described in RFC 2119.
However, for readability, these words do not appear in all uppercase
letters in this specification.
All of the text of this specification is normative except sections
explicitly marked as non-normative, examples, and notes.
[RFC2119]
Examples in this specification are introduced with the words “for example”
or are set apart from the normative text with
class="example"
like this:
This is an example of an informative example.
Informative notes begin with the word “Note” and are set apart from the
normative text with
class="note"
, like this:
Note, this is an informative note.
Advisements are normative sections styled to evoke special attention and are
set apart from other normative text with
, like
this:
UAs MUST provide an accessible alternative.
Conformance classes
Conformance to this specification
is defined for three conformance classes:
style sheet
CSS
style sheet
renderer
UA
that interprets the semantics of a style sheet and renders
documents that use them.
authoring tool
UA
that writes a style sheet.
A style sheet is conformant to this specification
if all of its statements that use syntax defined in this module are valid
according to the generic CSS grammar and the individual grammars of each
feature defined in this module.
A renderer is conformant to this specification
if, in addition to interpreting the style sheet as defined by the
appropriate specifications, it supports all the features defined
by this specification by parsing them correctly
and rendering the document accordingly. However, the inability of a
UA to correctly render a document due to limitations of the device
does not make the UA non-conformant. (For example, a UA is not
required to render color on a monochrome monitor.)
An authoring tool is conformant to this specification
if it writes style sheets that are syntactically correct according to the
generic CSS grammar and the individual grammars of each feature in
this module, and meet all other conformance requirements of style sheets
as described in this module.
Partial implementations
So that authors can exploit the forward-compatible parsing rules to
assign fallback values, CSS renderers
must
treat as invalid (and
ignore
as appropriate
) any at-rules, properties, property values, keywords,
and other syntactic constructs for which they have no usable level of
support. In particular, user agents
must not
selectively
ignore unsupported component values and honor supported values in a single
multi-value property declaration: if any value is considered invalid
(as unsupported values must be), CSS requires that the entire declaration
be ignored.
Implementations of Unstable and Proprietary Features
To avoid clashes with future stable CSS features,
the CSSWG recommends
following best practices
for the implementation of
unstable
features and
proprietary extensions
to CSS.
Non-experimental implementations
Once a specification reaches the Candidate Recommendation stage,
non-experimental implementations are possible, and implementors should
release an unprefixed implementation of any CR-level feature they
can demonstrate to be correctly implemented according to spec.
To establish and maintain the interoperability of CSS across
implementations, the CSS Working Group requests that non-experimental
CSS renderers submit an implementation report (and, if necessary, the
testcases used for that implementation report) to the W3C before
releasing an unprefixed implementation of any CSS features. Testcases
submitted to W3C are subject to review and correction by the CSS
Working Group.
Further information on submitting testcases and implementation reports
can be found from on the CSS Working Group’s website at
Questions should be directed to the
public-css-testsuite@w3.org
mailing list.
Index
Terms defined by this specification
alpha
dfn for PaintRenderingContext2D
, in § 6
dict-member for PaintRenderingContext2DSettings
, in § 2
class constructor
, in § 3
constructor valid flag
, in § 3
create a PaintRenderingContext2D object
, in § 6
devicePixelRatio
, in § 2
document paint definition
, in § 3
document paint definitions
, in § 4
draw a paint image
, in § 7
height
, in § 7
input argument syntaxes
, in § 3
input properties
dfn for document paint definition
, in § 3
dfn for paint definition
, in § 3
invoke a paint callback
, in § 7
output bitmap
, in § 6
paint()
, in § 5
paint class instances
, in § 4
paint definition
, in § 3
paint definitions
, in § 4
paint function
, in § 3
PaintRenderingContext2D
, in § 6
PaintRenderingContext2DSettings
, in § 2
PaintRenderingContext2DSettings object
dfn for document paint definition
, in § 3
dfn for paint definition
, in § 3
PaintSize
, in § 7
paintWorklet
, in § 2
PaintWorkletGlobalScope
, in § 2
registerPaint(name, paintCtor)
, in § 4
width
, in § 7
Terms defined by reference
[]
defines the following terms:
Construct
constructor
Get
IsConstructor
type
TypeError
[CSS-BACKGROUNDS-3]
defines the following terms:
border-image
[CSS-CASCADE-5]
defines the following terms:
computed value
[CSS-DISPLAY-4]
defines the following terms:
box
[CSS-IMAGES-3]
defines the following terms:
concrete object size
natural dimension
object size negotiation
[CSS-IMAGES-4]
defines the following terms:
invalid image
[CSS-PROPERTIES-VALUES-API-1]
defines the following terms:
consume a syntax definition
syntax definition
[CSS-SYNTAX-3]
defines the following terms:
function
[CSS-TYPED-OM-1]
defines the following terms:
CSSImageValue
StylePropertyMap
StylePropertyMapReadOnly
[CSS-UI-4]
defines the following terms:
cursor
[CSS-VALUES-4]
defines the following terms:
[CSS-VARIABLES-2]
defines the following terms:
custom property
[CSSOM-1]
defines the following terms:
CSS
supported CSS property
[CSSOM-VIEW-1]
defines the following terms:
devicePixelRatio
[DOM]
defines the following terms:
document
[HTML]
defines the following terms:
CanvasCompositing
CanvasDrawImage
CanvasDrawPath
CanvasFillStrokeStyles
CanvasImageData
CanvasImageSmoothing
CanvasImageSource
CanvasPath
CanvasPathDrawingStyles
CanvasRect
CanvasRenderingContext2D
CanvasShadowStyles
CanvasState
CanvasText
CanvasTextDrawingStyles
CanvasTransform
CanvasUserInterface
Worklet
WorkletGlobalScope
create a worklet global scope
drawImage()
global scopes
in parallel
queue a task
reset the rendering context to its default state
set bitmap dimensions
worklet destination type
worklet global scope type
[INFRA]
defines the following terms:
append
empty
exist
for each
get
list
map
set
struct
[WEBIDL]
defines the following terms:
DOMException
DOMString
Exposed
Global
InvalidModificationError
SameObject
VoidFunction
boolean
callback function
callback this value
converting
double
invoke
throw
undefined
unrestricted double
References
Normative References
[CSS-BACKGROUNDS-3]
Elika Etemad; Brad Kemper.
CSS Backgrounds and Borders Module Level 3
. URL:
[CSS-CASCADE-5]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr..
CSS Cascading and Inheritance Level 5
. URL:
[CSS-DISPLAY-4]
Elika Etemad; Tab Atkins Jr..
CSS Display Module Level 4
. URL:
[CSS-IMAGES-3]
Tab Atkins Jr.; Elika Etemad; Lea Verou.
CSS Images Module Level 3
. URL:
[CSS-IMAGES-4]
Elika Etemad; Tab Atkins Jr.; Lea Verou.
CSS Images Module Level 4
. URL:
[CSS-PROPERTIES-VALUES-API-1]
Tab Atkins Jr.; Alan Stearns; Greg Whitworth.
CSS Properties and Values API Level 1
. URL:
[CSS-SYNTAX-3]
Tab Atkins Jr.; Simon Sapin.
CSS Syntax Module Level 3
. URL:
[CSS-TYPED-OM-1]
Tab Atkins Jr.; François Remy.
CSS Typed OM Level 1
. URL:
[CSS-UI-4]
Tab Atkins Jr.; Florian Rivoal.
CSS Basic User Interface Module Level 4
. URL:
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad.
CSS Values and Units Module Level 4
. URL:
[CSS-VARIABLES-2]
CSS Custom Properties for Cascading Variables Module Level 2
. Editor's Draft. URL:
[CSSOM-1]
Daniel Glazman; Emilio Cobos Álvarez.
CSS Object Model (CSSOM)
. URL:
[CSSOM-VIEW-1]
Simon Fraser; Emilio Cobos Álvarez.
CSSOM View Module
. URL:
[DOM]
Anne van Kesteren.
DOM Standard
. Living Standard. URL:
[HTML]
Anne van Kesteren; et al.
HTML Standard
. Living Standard. URL:
[INFRA]
Anne van Kesteren; Domenic Denicola.
Infra Standard
. Living Standard. URL:
[RFC2119]
S. Bradner.
Key words for use in RFCs to Indicate Requirement Levels
. March 1997. Best Current Practice. URL:
[WEBIDL]
Edgar Chen; Timothy Gu.
Web IDL Standard
. Living Standard. URL:
IDL Index
partial
namespace
CSS
SameObject
readonly
attribute
Worklet
paintWorklet
};
Global
=(
Worklet
PaintWorklet
),
Exposed
PaintWorklet
interface
PaintWorkletGlobalScope
WorkletGlobalScope
undefined
registerPaint
DOMString
name
VoidFunction
paintCtor
);
readonly
attribute
unrestricted
double
devicePixelRatio
};
dictionary
PaintRenderingContext2DSettings
boolean
alpha
true
};
Exposed
PaintWorklet
interface
PaintRenderingContext2D
};
PaintRenderingContext2D
includes
CanvasState
PaintRenderingContext2D
includes
CanvasTransform
PaintRenderingContext2D
includes
CanvasCompositing
PaintRenderingContext2D
includes
CanvasImageSmoothing
PaintRenderingContext2D
includes
CanvasFillStrokeStyles
PaintRenderingContext2D
includes
CanvasShadowStyles
PaintRenderingContext2D
includes
CanvasRect
PaintRenderingContext2D
includes
CanvasDrawPath
PaintRenderingContext2D
includes
CanvasDrawImage
PaintRenderingContext2D
includes
CanvasPathDrawingStyles
PaintRenderingContext2D
includes
CanvasPath
Exposed
PaintWorklet
interface
PaintSize
readonly
attribute
double
width
readonly
attribute
double
height
};
MDN
CSS/paintWorklet_static
In only one current engine.
Firefox
None
Safari
None
Chrome
65+
Opera
Edge
79+
Edge (Legacy)
IE
None
Firefox for Android
iOS Safari
Chrome for Android
Android WebView
Samsung Internet
Opera Mobile
MDN
PaintWorkletGlobalScope/devicePixelRatio
In only one current engine.
Firefox
None
Safari
None
Chrome
65+
Opera
Edge
79+
Edge (Legacy)
IE
None
Firefox for Android
iOS Safari
Chrome for Android
Android WebView
Samsung Internet
Opera Mobile
MDN
PaintWorkletGlobalScope/registerPaint
In only one current engine.
Firefox
None
Safari
None
Chrome
65+
Opera
Edge
79+
Edge (Legacy)
IE
None
Firefox for Android
iOS Safari
Chrome for Android
Android WebView
Samsung Internet
Opera Mobile
MDN
PaintWorkletGlobalScope
In only one current engine.
Firefox
None
Safari
None
Chrome
65+
Opera
Edge
79+
Edge (Legacy)
IE
None
Firefox for Android
iOS Safari
Chrome for Android
Android WebView
Samsung Internet
Opera Mobile
MDN
image/paint
In only one current engine.
Firefox
None
Safari
None
Chrome
65+
Opera
Edge
79+
Edge (Legacy)
IE
None
Firefox for Android
iOS Safari
Chrome for Android
Android WebView
Samsung Internet
9.2+
Opera Mobile