CSS Images Module Level 4
CSS Images Module Level 4
Editor’s Draft
23 December 2025
More details about this document
This version:
Latest published version:
Previous Versions:
Feedback:
CSSWG Issues Repository
Tracker
Inline In Spec
Editors:
Tab Atkins Jr.
Google
Elika J. Etemad / fantasai
Apple
Lea Verou
Invited Expert
Suggest an Edit for this Spec:
GitHub Editor
Delta Spec:
yes
Test Suite:
World Wide Web Consortium
W3C
liability
trademark
and
permissive document license
rules apply.
Abstract
This module contains the features of CSS level 4 relating to the

type and replaced elements.
It includes and extends the functionality of CSS level 2
[CSS2]
and in the previous level of this specification
[css-images-3]
The main extensions compared to "CSS Images Module Level 3"
[css-images-3]
are several additions to the

type, such as the
image()
notation, the
element()
notation, and conic gradients.
This level is currently maintained as a diff spec over the level 3 module.
CSS
is a language for describing the rendering of structured documents
(such as HTML and XML)
on screen, on paper, etc.
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-images” in the title, like this:
“[css-images]
…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
This section is not normative.
This module introduces additional ways of representing 2D images,
for example as
a URL with color fallback
as
conic gradients
or as the
rendering of another element in the document
1.1.
Value Definitions
This specification follows the
CSS property definition conventions
from
[CSS2]
using the
value definition syntax
from
[CSS-VALUES-3]
Value types not defined in this specification are defined in CSS Values & Units
[CSS-VALUES-3]
Combination with other CSS modules may expand the definitions of these value types.
In addition to the property-specific values listed in their definitions,
all properties defined in this specification
also accept the
CSS-wide keywords
as their property value.
For readability they have not been repeated explicitly.
2.
2D Image Values: the

type
The

value type denotes a 2D image. It can be a
url reference
image notation
or
gradient notation
Its syntax is:


image
()
image-set
()
cross-fade
()
element
()

An

can be used in many CSS properties,
including the
background-image
list-style-image
cursor
properties
[CSS2]
(where it replaces the

component in the property’s value).
In some cases an image is invalid,
such as a

pointing to a resource that is not a valid image format
or that has failed to load.
An
invalid image
is rendered
as a solid-color
transparent
image with no
natural dimensions
However,
invalid images
can trigger error-handling clauses
in some contexts.
For example, an
invalid image
in
list-style-image
it is treated as
none
allowing the
list-style-type
to render in its place.
[CSS2]
While an image is loading,
is a
loading image
Loading images
are
not
invalid images
but have similar behavior:
they are rendered as a solid-color
transparent
image with no
natural dimensions
and may trigger fallback rendering in contexts that offer it,
but must not trigger loading of fallback resources.
Alternately, if a
loading image
happens to be replacing
an already-loaded image
(for example due to changes in the document or style sheet)
and the UA is tracking this information,
it may continue to render the already-loaded image
in place of the
loading image
Partially-loaded images (whose
natural dimensions
are known, but whose image data is not fully loaded)
may be either treated as
loading images
or as loaded images rendered with partial data.
For example, a UA may render an interlaced GIF in place
as soon as its first pass of pixel data has loaded
or even as soon as the image header (which contains sizing data) has parsed
and refresh the rendering as more data loads;
or it may wait until the entire image has loaded before using it.
computed

value
is the
specified value
with any

s,

s, and

s computed.
2.1.
Image File Formats
At minimum, the UA must support the following image file formats
when referenced from an

value,
for all the properties in which using

is valid:
PNG, as specified in
[PNG]
SVG, as specified in
[SVG11]
using the
secure static mode
(See
[SVG-INTEGRATION]
If the UA supports animated

s,
SVG, as specified in
[SVG11]
using the
secure animated mode
(See
[SVG-INTEGRATION]
The UA may support other file formats as well.
2.2.
Image References: the
url()
notation
Note:
No change from
[css-images-3]
2.3.
Fetching External Images
To
fetch an external image for a stylesheet
given a

url
and a
CSS declaration block
declaration
fetch a style resource
given
url
with ruleOrDeclaration being
declaration
destination "image",
CORS mode "no-cors",
and processResponse being the following steps
given
response
res
and null, failure or
a byte stream
byteStream
If
byteStream
is a byte stream, load the image from the byte stream.
2.4.
Resolution/Type Negotiation: the
image-set()
notation
Delivering the most appropriate image resolution for a user’s device can be a difficult task.
Ideally, images should be in the same resolution as the device they’re being viewed in,
which can vary between users.
However, other factors can factor into the decision of which image to send;
for example, if the user is on a slow mobile connection,
they may prefer to receive lower-res images
rather than waiting for a large proper-res image to load.
The
image-set()
function allows an author to ignore most of these issues,
simply providing multiple resolutions of an image
and letting the UA decide which is most appropriate in a given situation.
This solution assumes that resolution is a proxy for filesize,
and therefore doesn’t appropriately handle multi-resolution sets of vector images,
or mixing vector images with raster ones (e.g. for icons).
For example, use a vector for high-res,
pixel-optimized bitmap for low-res,
and same vector again for low-bandwidth (because it’s much smaller, even though it’s higher resolution).
The syntax for
image-set()
is:
image-set
()
image-set





||
type

We should add "w" and "h" dimensions as a possibility
to match the functionality of HTML’s
picture
Each

inside
image-set()
represents a

The
image-set()
function can not be nested inside of itself,
either directly
or indirectly
(as an argument to another

type).
Each

defines a possible image for the
image-set()
function to represent,
composed of three parts:
An image reference (required).
This can be a URL,
or a CSS generated image,
such as a
linear-gradient()

(optional).
This is used to help the UA decide which

to choose.
If the image reference is for a raster image,
it also specifies the image’s
natural resolution
overriding any other source of data that might supply a
natural resolution
If not specified,
it behaves as
1x
for the purpose of selecting which

to use.
It also
defaults
the image’s
natural resolution
to
1x
but if some other source of data supplies a
natural resolution
that resolution must be honored instead.
type(

function (optional),
specifying the image’s MIME type in the

If the

when parsed as a
valid MIME type string
is either not valid,
or is valid but doesn’t specify a supported image format,
the

does not define a valid option.
(This has no effect on the validity of the
image-set()
function.)
It does not have any effect on the image itself;
an

like
url
"picture.png"
type
"image/jpeg"
is valid,
and if chosen will display the linked PNG image,
even though it was declared to be a JPEG.
If not specified,
it has no effect on the

Tests
image-set-all-options-invalid.html
(live test)
(source)
image-set-calc-x-rendering-2.html
(live test)
(source)
image-set-calc-x-rendering.html
(live test)
(source)
image-set-computed.sub.html
(live test)
(source)
image-set-conic-gradient-rendering.html
(live test)
(source)
image-set-content-rendering.html
(live test)
(source)
image-set-dpcm-rendering.html
(live test)
(source)
image-set-dpi-rendering-2.html
(live test)
(source)
image-set-dpi-rendering.html
(live test)
(source)
image-set-dppx-rendering.html
(live test)
(source)
image-set-empty-url-rendering.html
(live test)
(source)
image-set-first-match-rendering.html
(live test)
(source)
image-set-linear-gradient-rendering.html
(live test)
(source)
image-set-negative-resolution-rendering-2.html
(live test)
(source)
image-set-negative-resolution-rendering-3.html
(live test)
(source)
image-set-negative-resolution-rendering.html
(live test)
(source)
image-set-no-res-rendering-2.html
(live test)
(source)
image-set-no-res-rendering.html
(live test)
(source)
image-set-no-url-rendering.html
(live test)
(source)
image-set-parsing.html
(live test)
(source)
image-set-radial-gradient-rendering.html
(live test)
(source)
image-set-rendering-2.html
(live test)
(source)
image-set-rendering.html
(live test)
(source)
image-set-repeating-conic-gradient-rendering.html
(live test)
(source)
image-set-repeating-linear-gradient-rendering.html
(live test)
(source)
image-set-repeating-radial-gradient-rendering.html
(live test)
(source)
image-set-resolution-001.html
(live test)
(source)
image-set-resolution-002.html
(live test)
(source)
image-set-resolution-003.html
(live test)
(source)
image-set-type-first-match-rendering.html
(live test)
(source)
image-set-type-rendering-2.html
(live test)
(source)
image-set-type-rendering-3.html
(live test)
(source)
image-set-type-rendering.html
(live test)
(source)
image-set-type-skip-unsupported-rendering.html
(live test)
(source)
image-set-type-unsupported-rendering-2.html
(live test)
(source)
image-set-type-unsupported-rendering.html
(live test)
(source)
image-set-unordered-res-rendering.html
(live test)
(source)
image-set-zero-resolution-rendering-2.html
(live test)
(source)
image-set-zero-resolution-rendering.html
(live test)
(source)
An
image-set()
function contains a list of one or more

s,
and must select only one of them
to determine what image it will represent:
First, remove any

s from the list
that specify an unknown or unsupported MIME type in their
type()
value.
Second, remove any

s from the list
that have the same

as a previous option in the list.
If there are no

left at this point,
the function represents an
invalid image
Finally, among the remaining

s,
make a UA-specific choice of which to load,
based on whatever criteria deemed relevant
(such as the resolution of the display,
connection speed,
etc).
The
image-set()
function then represents the

of the chosen

UAs
may
change which

they wish to use for a given
image-set()
over the lifetime of the page,
if the criteria used to determine which option to choose change significantly enough to make it worthwhile in the UA’s estimation.
This example shows how to use
image-set()
to provide an image in three versions:
a "normal" version,
a "high-res" version,
and an extra-high resolution version for use in high-quality printing
(as printers can have
extremely
high resolution):
background-image
image-set
"foo.png"
"foo-2x.png"
"foo-print.png"
600
dpi
);
This example shows use of the
type()
function
to serve multiple versions of the same image
in both new, higher-quality formats,
and older, more widely-supported formats:
background-image
image-set
"foo.avif"
type
"image/avif"
),
"foo.jpg"
type
"image/jpeg"
);
Note that the AVIF image is given first;
since both images have the same resolution
(defaulting to
1x
since it’s unspecified),
the JPEG image,
coming second,
is automatically dropped in UAs that support AVIF images.
In older UAs, however,
the AVIF image is ignored
(because the UA knows it doesn’t support
"image/avif"
files),
and so the JPEG is chosen instead.
Raster images can be mixed with vector images,
or even CSS generated images.
For example, in this code snippet
a high-resolution image with subtle details is used on screens that can do it justice,
while an ordinary CSS
linear-gradient()
is used instead for low-resolution situations:
background-image
image-set
linear-gradient
cornflowerblue
white
url
"detailed-gradient.png"
);
2.5.
Image Fallbacks and Annotations: the
image()
notation
The
image()
function allows an author to:
use
media fragments
to clip out a portion of an image
use a solid color as an image
fallback to a solid-color image, when the image at the specified url can’t be downloaded or decoded
automatically respect the image orientation specified in the image’s metadata
The
image()
notation is defined as:
image
()
image




ltr
rtl




used in
image()
represents a

As usual for URLs in CSS,
relative URLs are resolved to an absolute URL
(as described in Values & Units
[CSS-VALUES-3]
when a specified
image()
value is computed.
If the image has an orientation specified in its metadata,
such as EXIF,
the UA must rotate or flip the image to correctly orient it
as the metadata specifies.
2.5.1.
Image Fallbacks
If both a URL and a

are specified in
image()
then whenever the URL represents an
invalid image
or
loading image
the
image()
function renders as if the URL were not specified at all;
it generates a solid-color image as specified in
§ 2.5.3 Solid-color Images
If just a URL is specified (no

and it represents an
invalid image
or
loading image
the
image()
function represents the same.
Tests
css-image-fallbacks-and-annotations.html
(live test)
(source)
css-image-fallbacks-and-annotations002.html
(live test)
(source)
css-image-fallbacks-and-annotations003.html
(live test)
(source)
css-image-fallbacks-and-annotations004.html
(live test)
(source)
css-image-fallbacks-and-annotations005.html
(live test)
(source)
The fallback color can be used to ensure that text is still readable
even when the image fails to load.
For example, the following legacy code works fine if the image is rectangular and has no transparency:
body
color
black
background
white
p.special
color
white
background
url
"dark.png"
black
When the image doesn’t load,
the background color is still there to ensure that the white text is readable.
However, if the image has some transparency,
the black will be visible behind it,
which is probably not desired.
The
image()
function addresses this:
body
color
black
background
white
p.special
color
white
background
image
"dark.png"
black
);
Now, the black won’t show at all if the image loads,
but if for whatever reason the image fails,
it’ll pop in and prevent the white text from being set against a white background.
2.5.2.
Image Fragments
When a URL specified in
image()
represents a portion of a resource
(e.g. by the use of
media fragment identifiers
that portion is clipped out of its context and used as a standalone image.
For example, given the following image and CSS:
background-image
image
'sprites.svg#xywh=40,0,20,20'
...the background of the element will be the portion of the image that starts at (40px,0px) and is 20px wide and tall,
which is just the circle with a quarter filled in.
So that authors can take advantage of CSS’s forwards-compatible parsing rules to provide a fallback for image slices,
implementations that support the
image()
notation
must
support the
xywh=#
form of media fragment identifiers
for images specified via
image()
[MEDIA-FRAGS]
Note that image fragments can also be used with the
url()
notation.
However, a legacy UA that doesn’t understand the media fragments notation
will ignore the fragment and simply display the entirety of the image.
Since the
image()
notation requires UAs to support media fragments,
authors can take advantage of CSS’s forward-compatible parsing rules
to provide a fallback when using an image fragment URL:
background-image
url
'swirl.png'
);
/* old UAs */
background-image:
image
'sprites.png#xywh=10,30,60,20'
);
/* new UAs */
If a URL uses a fragment identifier syntax that the implementation does not understand,
or does not consider valid for that type of image,
the URL must be treated as representing an
invalid image
Note:
This error-handling is limited to
image()
and not in the definition of URL,
for legacy compat reasons.
2.5.3.
Solid-color Images
If the
image()
function is specified with only a

argument (no URL),
it represents a solid-color image of the specified color with no
natural dimensions
For example,
one can use this as a simple way to "tint" a background image,
by overlaying a partially-transparent color over the top of the other image:
background-image
image
rgba
255
.5
)),
url
"bg-image.png"
);
background-color
does not work for this,
as the solid color it generates always lies
beneath
all the background images.
2.5.4.
Bidi-sensitive Images
Before listing any
s
the author may specify a directionality for the image,
similar to adding a
dir
attribute to an element in HTML.
If a directional image is used on or in an element with opposite
direction
the image must be flipped in the inline direction
(as if it was transformed by, e.g.,
scaleX
-1
, if the inline direction is the X axis).
Note:
Absent this declaration,
images default to no directionality at all,
and thus don’t care about the directionality of the surrounding element.
A list may use an arrow for a bullet that points into the content.
If the list can contain both LTR and RTL text,
though, the bullet may be on the left or the right,
and an image designed to point into the text on one side will point out of the text on the other side.
This can be fixed with code like:
ul
style
"list-style-image: image(ltr 'arrow.png');"
li
dir
'ltr'
My bullet is on the left!
li
li
dir
'rtl'
MY BULLET IS ON THE RIGHT!
li
ul
This should render something like:
⇒ My bullet is on the left!
!THGIR EHT NO SI TELLUB YM ⇐
In LTR list items, the image will be used as-is.
In the RTL list items, however,
it will be flipped in the inline direction,
so it still points into the content.
2.6.
Combining images: the
cross-fade()
notation
When transitioning between images,
CSS requires a way to explicitly refer to the intermediate image
that is a combination of the start and end images.
This is accomplished with the
cross-fade()
function,
which indicates the two images to be combined
and how far along in the transition the combination is.
Note:
Authors can also use the
cross-fade()
function for many simple image manipulations,
such as tinting an image with a solid color
or highlighting a particular area of the page by combining an image with a radial gradient.
The syntax for
cross-fade()
is defined as:
cross-fade
()
cross-fade




&&
100
The function represents an image generated by
combining one or more images.
The

represents how much of each image is retained
when it is blended with the other images.
The

must be between
0%
and
100%
inclusive;
any other value is invalid.
If any percentages are omitted,
all the specified percentages are summed together
and subtracted from
100%
the result is floored at
0%
then divided equally between all images with omitted percentages
at computed-value time.
While this is not reflected in the computed value,
when all the arguments’ percentages sum to greater than
100%
the sizing/painting details effectively rescale them so that they sum to exactly
100%
On the other hand,
when the sum is less than
100%
the sizing/painting details effectively act like there’s an additional
transparent
argument,
with its percentage set to the remaining value
necessary to make the sum equal
100%
If a

is provided,
it represents a solid-color image
with “automatic” dimensions
(it doesn’t participate in the sizing of the result image at all;
see details in the sizing details below).
Tests
cross-fade-basic.html
(live test)
(source)
cross-fade-computed-value.html
(live test)
(source)
cross-fade-legacy-crash.html
(live test)
(source)
cross-fade-legacy-2-crash.html
(live test)
(source)
cross-fade-natural-size.html
(live test)
(source)
cross-fade-premultiplied-alpha.html
(live test)
(source)
cross-fade-target-alpha.html
(live test)
(source)
2.6.1.
cross-fade()
Sizing
The dimensions of the image represented by a
cross-fade()
are a weighted average of dimensions of the

arguments to the function;
the

arguments have no effect.
They are calculated as follows:
To determine the
natural dimensions
of a cross-fade()
Normalize mix percentages
from the function’s arguments,
and let
args
and
leftover
be the result.
If
leftover
is 100%,
return no
natural dimensions
Let
images
be an empty list.
For each

argument
of the function’s arguments:
If
argument
is not an

or is an

with no natural dimensions,
continue
Let
item
be a
tuple
consisting of a width, a height, and a percentage.
Run the
object size negotiation
algorithm for the

as appropriate for the context in which the
cross-fade()
appears,
and set
item
’s width and height
to the width and height of the resulting
concrete object size
Set
item
’s percentage to the
argument
’s percentage.
If
images
is empty,
return no
natural dimensions
Return a
natural width
and
natural height
that are weighted averages of the width and height
of each item in
images
according to their corresponding percentages.
Note:
The percentages might sum to a value less than 100%,
so a naive weighted-averaging process might need to normalize them first.
2.6.2.
cross-fade()
Painting
The image represented by a
cross-fade()
is a weighted average of the input arguments to the function,
calculated as follows:
To determine the
appearance of a cross-fade()
Normalize mix percentages
from the function’s arguments,
and let
args
and
leftover
be the result.
Let
images
be an empty list.
Let
size
be a
tuple
of width and height,
initialized to the result of finding the
concrete object size
of the
cross-fade()
function
(using the
natural dimensions of a cross-fade()
).
For each
argument
of the
cross-fade()
function:
Let
item
be a
tuple
consisting of an image and a percentage.
If
argument
has an

rescale it to
size
’s width and height
and set
item
’s image to the result.
Otherwise,
argument
has a

set
item
’s image to a solid-color image of the

with
size
’s dimensions.
Set
item
’s percentage to the
argument
’s percentage.
If
leftover
is greater than
0%
append a
tuple
to
images
consisting of a solid-color transparent-black image
with
size
’s dimensions,
and a percentage equal to
leftover
Let
final image
be an image
with
size
’s dimensions,
and every pixel being the weighted linear average of the corresponding pixels of
each
item
’s image in
images
weighted according to the
item
’s percentage.
(Average both the color channels and the alpha channel of the pixels.)
For the purpose of this calculation,
each pixel’s color must be in pre-multiplied sRGB.
Details on the above operation
This is applying an N-way Porter-Duff
dissolve
operation to the source images.
Wikipedia defines
dissolve
as a stochastic operation,
with the result pixels independently randomly chosen from the source images’ corresponding pixels
according to their source images’ weights,
but as pixels shrink to infinitely small,
this converges to doing color-averaging in pre-multiplied color space.
In particular, this means that `cross-fade(white 50%, transparent 50%)`
will produce a partially-transparent solid white image.
(Rather than a partially-transparent gray,
which is what you’d get if you averaged the opaque white and transparent black pixels
in non-premultiplied space.)
As converting to pre-multiplied does entail some loss of precision,
and graphics libraries may or may not support this operation natively,
as per usual any method can be used so long as it achieves the specified effect.
For example, one can instead rebalance the percentages
according to the alphas of each pixel,
then do the color-channel averages in non-premultiplied space.
E.g., to render
cross-fade(rgb(255 0 0 / 1) 40%, rgb(0 255 0 / .5) 20%, rgb(0 0 255 / 0) 40%)
rebalancing the percentages according to the 1 / .5 / 0 alphas
would produce 40% / 10% / 0%
(which renormalizes to 80% / 20% / 0%),
at which point you can average the raw color channel values
and end up with an
rgb(204 51 0 / .5)
image.
(Note that the alpha channel is still averaged using the original percentages,
not the rebalanced ones.)
Return
final image
2.6.3.
Simplifying Complex
cross-fade()
Per WG resolution,
define a notion of "equality" for images,
and combine "same" images at computed-value time,
summing their percentages.
Per WG resolution,
simplify directly-nested
cross-fade()
at computed-value time
by just distributing the percentage and flattening;
cross-fade(A 10%, cross-fade(B 30%, C 70%) 90%)
becomes
cross-fade(A 10%, B 27%, C 63%)
2.7.
Using Elements as Images: the
element()
notation
The
element()
function allows an author to use an element in the document as an image.
As the referenced element changes appearance,
the image changes as well.
This can be used, for example,
to create live previews of the next/previous slide in a slideshow,
or to reference a canvas element for a fancy generated gradient or even an animated background.
Note:
The
element()
function only reproduces the
appearance
of the referenced element,
not the actual content and its structure.
Authors should only use this for decorative purposes,
and must not use
element()
to reproduce an element with significant content across the page.
Instead, just insert multiple copies of the element into the document.
The syntax for
element()
is:
element
()
element

where

is an ID selector
[SELECT]
Do we need to be able to refer to elements in external documents
(such as SVG paint servers)?
Or is it enough to just use url() for this?
This name conflicts with a somewhat similar function in GCPM.
This needs to be resolved somehow.
Want the ability to do "reflections" of an element,
either as a background-image on the element or in a pseudo-element.
This needs to be specially-handled to avoid triggering the cycle-detection.
When we have overflow:paged,
how can we address a single page in the view?
The
element()
function references the element matched by its argument.
The ID is first looked up in the
elementSources
map,
as described in that section.
If it’s not found,
it’s then matched against the document.
If multiple elements are matched,
the function references the first such element.
The image represented by the
element()
function can vary based on whether the element is visible in the document:
an
element that is rendered
is not a descendant of a replaced element,
and generates a
stacking context
The function represents an image with its
natural size
equal to the
decorated bounding box
of the referenced element:
for an element rendered using a CSS rendering model,
the
decorated bounding box
is the smallest axis-aligned rectangle
that contains the
border image areas
of all the fragments of the principal box
for an element rendered using the SVG rendering model,
the decorated bounding box is defined by SVG
Note:
Because images clip anything outside their bounds by default,
this means that decorations that extend outside the
decorated bounding box
like box shadows,
may be clipped.
The image is constructed by rendering the referenced element and its descendants
(at the same size that they would be in the document)
over an infinite
transparent
canvas,
positioned so that the edges of the
decorated bounding box
are flush with the edges of the image.
Requiring some degree of stacking context on the element appears to be required for an efficient implementation.
Do we need a full stacking context, or just a pseudo-stacking context?
Should it need to be a stacking context normally,
or can we just render it as a stacking context when rendering it to element()?
If the referenced element has a transform applied to it or an ancestor,
the transform must be ignored when rendering the element as an image.
[CSS3-TRANSFORMS]
If the referenced element is broken across pages,
the element is displayed as if the page content areas were joined flush in the pagination direction,
with pages' edges corresponding to the initial containing block’s start edge aligned.
Elements broken across lines or columns are just rendered with their
decorated bounding box
Implementations may either re-use existing bitmap data generated for the referenced element
or regenerate the display of the element to maximize quality at the image’s size
(for example, if the implementation detects that the referenced element is an SVG fragment);
in the latter case, the layout of the referenced element in the image must not be changed by the regeneration process.
That is, the image must look identical to the referenced element,
modulo rasterization quality.
As a somewhat silly example, a
element can be reused as a background elsewhere in the document:
style
src
color
white
background
lime
width
300
px
height
40
px
position
relative
dst
color
black
background
element
#src
);
padding
20
px
margin
20
px
style
id
'src'
I'm an ordinary element!
id
'dst'
I'm using the previous element as my background!
an
element that is not rendered
, but which provides a
paint source
The function represents an image with the
natural dimensions
and appearance of the
paint source
The host language defines the size and appearance of paint sources.
For example, the
element()
function can reference an SVG

element in an HTML document:

svg
defs
pattern
id
'pattern1'
path
'...'
pattern
defs
svg
style
"background: element(#pattern1)"
I'm using the pattern as a background!
If the pattern is changed or animated,
my background will be updated too!
HTML also defines that a handful of elements,
such as
canvas
img
, and
video
provide a paint source.
This means that CSS can, for example,
reference a canvas that’s being drawn into,
but not displayed in the page:

script
var
canvas
document
querySelector
'#animated-bullet'
);
canvas
width
20
canvas
height
20
drawAnimation
canvas
);
script
canvas
id
'animated-bullet'
style
'display:none'
>canvas
ul
style
"list-style-image: element(#animated-bullet);"
li
I'm using the canvas as a bullet!
li
li
So am I!
li
li
As the canvas is changed over time with Javascript,
we'll all update our bullet image with it!
li
ul
anything else
The function represents an
invalid image
For example, all of the following
element()
uses will result in a transparent background:

id
'one'
style
"display:none; position: relative;"
one
iframe
src
"http://example.com"
id
'two'
style
"position: relative;"
I'm fallback content!
iframe
ul
li
style
"background: element(#one);"
A display:none element isn't rendered, and a P element
doesn't provide a paint source.
li
li
style
"background: element(#two);"
The descendants of a replaced element like an IFRAME
can't be used in element() either.
li
li
style
"background: element(#three);"
There's no element with an id of "three", so this also
gets rendered as a transparent image.
li
ul
An element is
not rendered
if it does not have an associated box.
This can happen, for example,
if the element or an ancestor is
display:none
Host languages may define additional ways in which an element can be considered not rendered;
for example, in SVG,
any descendant of a

element is considered to be not rendered.
The
element()
function can be put to many uses.
For example, it can be used to show a preview of the previous or next slide in a slideshow:

script
function
navigateSlides
()
var
currentSlide
...;
document
querySelector
'#prev-slide'
).
id
''
document
querySelector
'#next-slide'
).
id
''
currentSlide
previousElementSibling
id
'prev-slide'
currentSlide
nextElementSibling
id
'next-slide'
script
style
slide
/* Need to be a stacking context to be element()-able. */
position
relative
prev-preview
next-preview
position
fixed
...
prev-preview
background
element
#prev
-slide
);
next-preview
background
element
#next
-slide
);
style
id
'prev-preview'
Previous Slide
id
'next-preview'
Next Slide
section
class
'slide'
...
section
section
class
'slide current-slide'
...
section
...
In this example, the
navigateSlides
function updates the ids of the next and previous slides,
which are then displayed in small floating boxes alongside the slides.
Since you can’t interact with the slides through the
element()
function (it’s just an image),
you could even use
click
handlers on the preview boxes to help navigate through the page.
2.7.1.
Paint Sources
Host languages may define that some elements provide a
paint source
Paint sources have an intrinsic appearance and can obtain a
concrete object size
without having to do layout or rendering,
and so may be used as images even when they’re
not rendered
In HTML, the
img
video
, and
canvas
elements provide paint sources.
In SVG, any element that provides a
paint server
provides a paint source.
Note: In SVG1.1,
the


and

elements
provide paint sources.
They are drawn as described in the spec,
with the coordinate systems defined as follows:
objectBoundingBox
The coordinate system has its origin at the top left corner of the rectangle defined by the
concrete object size
that it’s being drawn into,
and the same width and height as the
concrete object size
A single
user coordinate
is the width and height of the
concrete object size
userSpaceOnUse
The coordinate system has its origin at the top left corner of the rectangle defined by the
concrete object size
that it’s being drawn into,
and the same width and height as the
concrete object size
User coordinates
are sized equivalently to the CSS
px
unit.
Note:
It is expected that a future version of this module will define ways to refer to paint sources in external documents,
or ones that are created solely by script and never inserted into a document at all.
2.7.2.
Using Out-Of-Document Sources: the
ElementSources
interface
The
element()
function normally selects elements within a document,
but elements that provide a
paint source
don’t necessarily need to be in-document.
For example, an HTML
canvas
element can be created, maintained, and drawn into entirely in script,
with no need for it to be inserted into the document directly.
All that’s needed is a way to refer to the element,
as an ID selector cannot select elements outside of the document.
The
elementSources
Map object provides this.
partial
namespace
CSS
SameObject
readonly
attribute
any
elementSources
};
Tests
idlharness.html
(live test)
(source)
Any entries in the
elementSources
map with a string key
and a value that is an object providing a
paint source
are made available to the
element()
function.
Whenever
element()
uses an

the ID’s value (without the leading
character)
is first looked up in the
elementSources
map:
If it’s found,
and the object associated with it provides a
paint source
the
element()
function represents that paint source.
If it’s found,
but the object associated with it
doesn’t
provide a
paint source
the
element()
function represent an
invalid image
If the ID isn’t found in the map at all,
it’s then looked for in the document as normal.
This reuse of the ID selector matches Moz behavior.
I’m trying to avoid slapping a

right in the beginning of the grammar,
as that eats too much syntax-space.
Another possibility, though, is to start the value with a language-defined keyword
followed by

like
element(external fancy)
or something.
Naming suggestions welcome.
For example, fancy animating backgrounds can be done with an external canvas:
script
var
bg
document
createElement
'canvas'
);
bg
height
200
bg
width
1000
drawFancyBackground
bg
);
CSS
elementSources
set
'fancy'
bg
);
script
style
h1
background-image
element
#fancy
);
style
As the "fancy" canvas is drawn into and animated,
the backgrounds of all the H1 elements will automatically update in tandem.
Note that the
elementSources
map is consulted
before
the document
to match the ID selector,
so even if there’s an element in the document that would match
#fancy
the backgrounds will still predictably come from the
elementSources
value instead.
2.7.3.
Cycle Detection
The
element()
function can produce nonsensical circular relationships,
such as an element using itself as its own background.
These relationships can be easily and reliably detected and resolved, however,
by keeping track of a dependency graph and using common cycle-detection algorithms.
The dependency graph consists of edges such that:
every element depends on its children
for any element A with a property using the
element()
function pointing to an element B,
A depends on B
if a host language defines a way for elements to refer to the rendering of other elements,
the referencing element depends on the referenced element.
For example, in SVG,

element depends on the element it referenced.
If the graph contains a cycle,
any
element()
functions participating in the cycle are
invalid images
3.
Gradients
A gradient is an image that smoothly fades from one color to another.
These are commonly used for subtle shading in background images, buttons, and many other things.
The
gradient functions
described in this section allow an author to specify such an image in a terse syntax,
so that the UA can generate the image automatically when rendering the page.
The syntax of a

is:

linear-gradient
()
repeating-linear-gradient
()
radial-gradient
()
repeating-radial-gradient
()
conic-gradient
()
repeating-conic-gradient
()
As with the other

types defined in this specification,
gradients can be used in any property that accepts images.
For example:
background
linear-gradient
white
gray
);
list-style-image
radial-gradient
circle
#006
#00a
90
#0000af
100
white
100
A gradient is drawn into a box with the dimensions of the
concrete object size
referred to as the
gradient box
However, the gradient itself has no
natural dimensions
Tests
gradients-with-border.html
(live test)
(source)
For example, if you use a gradient as a background,
by default the gradient will draw into a
gradient box
the size of the element’s padding box.
If
background-size
is explicitly set to a value such as
100px 200px
then the
gradient box
will be 100px wide and 200px tall.
Similarly, for a gradient used as a
list-style-image
the box would be a 1em square,
which is the
default object size
for that property.
Gradients are specified by defining the
starting point
and
ending point
of a
gradient line
(which, depending on the type of gradient,
may be technically a line, or a ray, or a spiral),
and then specifying colors at points along this line.
The colors are smoothly blended to fill in the rest of the line,
and then each type of gradient defines how to use the color of the
gradient line
to produce the actual gradient.
3.1.
Linear Gradients: the
linear-gradient()
notation
This level adds a

argument
to
linear-gradient()
and
repeating-linear-gradient()
indicating the color space and path to use
when interpolating colors on the gradient line.
See
CSS Color 4
§  13. Color Interpolation



to

||



left
right
||
top
bottom
Tests
color-stop-currentcolor.html
(live test)
(source)
gradient-border-box.html
(live test)
(source)
gradient-button.html
(live test)
(source)
gradient-content-box.html
(live test)
(source)
linear-gradient-1.html
(live test)
(source)
linear-gradient-2.html
(live test)
(source)
linear-gradient-body-sibling-index.html
(live test)
(source)
linear-gradient-calc-em-units.html
(live test)
(source)
linear-gradient-non-square.html
(live test)
(source)
linear-gradient-sibling-index.html
(live test)
(source)
multiple-position-color-stop-linear-2.html
(live test)
(source)
multiple-position-color-stop-linear.html
(live test)
(source)
normalization-linear-2.html
(live test)
(source)
normalization-linear-degenerate.html
(live test)
(source)
normalization-linear.html
(live test)
(source)
tiled-gradients.html
(live test)
(source)
color-stops-parsing.html
(live test)
(source)
display-p3-linear-gradient.html
(live test)
(source)
linear-gradient-relative-currentcolor-stop.html
(live test)
(source)
gradient-single-stop-001.html
(live test)
(source)
gradient-single-stop-002.html
(live test)
(source)
gradient-single-stop-003.html
(live test)
(source)
gradient-single-stop-004.html
(live test)
(source)
gradient-single-stop-005.html
(live test)
(source)
gradient-single-stop-006.html
(live test)
(source)
gradient-single-stop-007.html
(live test)
(source)
gradient-single-stop-008.html
(live test)
(source)
gradient-single-stop-longer-hue-hsl-002.html
(live test)
(source)
gradient-single-stop-longer-hue-hsl.html
(live test)
(source)
gradient-single-stop-longer-hue-oklch.html
(live test)
(source)
gradient-single-stop-none-interpolation.html
(live test)
(source)
gradient-interpolation-method-computed.html
(live test)
(source)
gradient-interpolation-method-invalid.html
(live test)
(source)
gradient-interpolation-method-valid.html
(live test)
(source)
gradient-position-invalid.html
(live test)
(source)
gradient-position-valid.html
(live test)
(source)
gradient-position-computed.html
(live test)
(source)
3.1.1.
Effects of color space on interpolation: examples
This section is non-normative.
The effect of colorspace on interpolation can be significant.
In this example, a linear gradient between the same pair of colors
#f01 and #081 is drawn in three different colorspaces.
The middle gradient uses gamma-encoded sRGB,
which was the only choice in CSS Images 3;
the result is clearly too dark at the midpoint.
The upper gradient uses CIE Lab,
giving a more perceptually uniform result;
while the lower gradient uses Oklab,
which here gives almost the same result as CIE Lab.
linear-gradient
in lab to right
#F01
#081
linear-gradient
in srgb to right
#F01
#081
linear-gradient
in Oklab to right
#F01
#081
In this example, a linear gradient between the same pair of colors
white and #01E is drawn in three different colorspaces.
The middle gradient uses gamma-encoded sRGB,
the result is again too dark at the midpoint,
is a little desaturated, and has a slight purplish cast.
The upper gradient uses CIE Lab,
which avoids the too-dark midpoint
but has a significant purple cast;
while the lower gradient uses Oklab,
giving a more perceptually uniform result
with no purple cast at all.
linear-gradient
in lab to right
white
#01E
linear-gradient
in srgb to right
white
#01E
linear-gradient
in Oklab to right
white
#01E
In this example, a linear gradient between the same pair of colors
#44C and #795 is drawn in three different colorspaces.
This demonstrates that
the hue non-linearity of CIE Lab
affects all bulueish colors,
not just the gradient from saturated primary blue to white.
The middle gradient uses gamma-encoded sRGB,
the result is again too dark at the midpoint,
and has a slight purplish cast.
The upper gradient uses CIE Lab,
which avoids the too-dark midpoint
but has a significant purple cast;
while the lower gradient uses Oklab,
again giving a more perceptually uniform result
with no purple cast at all.
linear-gradient
in lab to right
#44C
#795
linear-gradient
in srgb to right
#44C
#795
linear-gradient
in Oklab to right
#44C
#795
Choosing a polar, rather than rectangular, colorspace
for gradient interpolation
avoids desaturation
if the hues of the color stops are far apart.
Interpolating in a polar colorspaces
is inherently chroma-preserving,
although it is easy for the intermediate colors to fall out of gamut;
they will then be gamut mapped
to bring them back into gamut.
In this example, a linear gradient between the same pair of colors
#A37 and #595 is drawn in five different colorspaces,
two of them polar.
From top to bottom:
CIE LCH, CIE Lab, sRGB, Oklab, Oklch.
The rectangular spaces have a greyish midpoint,
while the intermediate colors in the polar spaces
follow a curved, chroma-preserving path.
linear-gradient
in lch to right
#A37
#595
linear-gradient
in lab to right
#A37
#595
linear-gradient
in srgb to right
#A37
#595
linear-gradient
in Oklab to right
#A37
#595
linear-gradient
in oklch to right
#A37
#595
3.2.
Radial Gradients: the
radial-gradient()
notation
3.2.1.
Adding

This level adds a

argument
to
radial-gradient()
and
repeating-radial-gradient()
indicating the color space and path to use
when interpolating colors on the gradient line.
See
CSS Color 4
§  13. Color Interpolation


||

at

||


Tests
empty-radial-gradient-crash.html
(live test)
(source)
infinite-radial-gradient-refcrash.html
(live test)
(source)
multiple-position-color-stop-radial-2.html
(live test)
(source)
multiple-position-color-stop-radial.html
(live test)
(source)
normalization-radial-2.html
(live test)
(source)
normalization-radial-3.html
(live test)
(source)
normalization-radial-4.html
(live test)
(source)
normalization-radial-degenerate.html
(live test)
(source)
normalization-radial.html
(live test)
(source)
radial-gradient-container-relative-units-001.html
(live test)
(source)
radial-gradient-container-relative-units-002.html
(live test)
(source)
radial-gradient-container-relative-units-003.html
(live test)
(source)
radial-gradient-container-relative-units-004.html
(live test)
(source)
radial-gradient-transition-hint-crash.html
(live test)
(source)
tiled-radial-gradients.html
(live test)
(source)
color-stops-parsing.html
(live test)
(source)
gradient-interpolation-method-computed.html
(live test)
(source)
gradient-interpolation-method-invalid.html
(live test)
(source)
gradient-interpolation-method-valid.html
(live test)
(source)
gradient-position-invalid.html
(live test)
(source)
gradient-position-valid.html
(live test)
(source)
In this example, a radial gradient between the same pair of colors
color(display-p3 0.918 0.2 0.161) and #081 is drawn in three different colorspaces.
Notice that the color stops do not all need to be in the same colorspace.
The middle gradient uses gamma-encoded sRGB,
the result is clearly too dark at the midpoint.
The upper gradient uses CIE Lab,
giving a more perceptually uniform result;
while the lower gradient uses Oklab,
which here gives almost the same result as CIE Lab.
radial-gradient
in lab farthest-side at left bottom
color
display-p3
0.918
0.2
0.161
),
#081
radial-gradient
in srgb farthest-side at left bottom
color
display-p3
0.918
0.2
0.161
),
#081
radial-gradient
in Oklab farthest-side at left bottom
color
display-p3
0.918
0.2
0.161
),
#081
3.2.2.
Expanding

This level extends the

options
to include the additions from the
circle()
and
ellipse()

values:


Two-component values remain invalid when specifying
circle
as the

and otherwise indicate the horizontal (first) and vertical (second) radii
of the ellipse.
For
circle

value is resolved against
the “scaled diagonal” of the
gradient box
’s width and height:
sqrt
width² + height²
sqrt
3.3.
Conic Gradients: the
conic-gradient()
notation
A conic gradient starts by specifying the center of a circle,
similar to radial gradients,
except that conic gradient color-stops are placed
around
the circumference of the circle,
rather than on a line emerging from the center,
causing the color to smoothly transition as you spin around the center,
rather than as you progress outward from the center.
A conic gradient is specified by indicating a rotation angle, the center of the gradient,
and then specifying a list of color-stops.
Unlike linear and radial gradients,
whose color-stops are placed by specifying a

the color-stops of a conic gradient are specified with an

Rays are then drawn emerging from the center and pointing in all directions,
with the color of each ray equal to the color of the gradient-line where they intersect it.
Note:
These gradients are called "conic" or "conical"
because, if the color stops are chosen to be significantly lighter on one side than the other,
it produces a pattern that looks like a cone observed from above.
They are also known as "angle" gradients in some contexts,
since they are produced by varying the rotation angle of a ray.
This example visually illustrates how
conic-gradient(at 25% 30%, white, black 60%)
would be drawn. Note that since color stop positions always resolve to angles, the only effect of the
at 25% 30%
is a 2D translation of the gradient, i.e. it does not affect how the gradient is drawn.
3.3.1.
conic-gradient()
Syntax
The syntax for a conic gradient is:
conic-gradient
()
conic-gradient


from


at

||


The arguments are defined as follows:


The entire gradient is rotated by this angle.
If omitted, defaults to
0deg
The unit identifier may be omitted if the

is zero.

Determines the
gradient center
of the gradient.
The

value type (which is also used for
background-position
is defined in
[CSS-VALUES-3]
and is resolved using the center-point as the object area
and the
gradient box
as the positioning area.
If this argument is omitted, it defaults to
center
Usually in conic gradients the sharp transition at 0deg is undesirable, which is typically avoided by making sure the first and last color stops are the same color. Perhaps it would be useful to have a keyword for automatically achieving this.
Would a radius (inner & outer) for clipping the gradient be useful? If so, we could also support lengths in color stop positions, since we now have a specific radius.
Are elliptical conic gradients useful? Do graphics libraries support them?
Tests
conic-gradient-001.html
(live test)
(source)
conic-gradient-angle-negative.html
(live test)
(source)
conic-gradient-angle.html
(live test)
(source)
conic-gradient-center.html
(live test)
(source)
repeating-conic-gradient.html
(live test)
(source)
tiled-conic-gradients.html
(live test)
(source)
multiple-position-color-stop-conic-2.html
(live test)
(source)
multiple-position-color-stop-conic.html
(live test)
(source)
normalization-conic-2.html
(live test)
(source)
normalization-conic-degenerate.html
(live test)
(source)
normalization-conic.html
(live test)
(source)
out-of-range-color-stop-conic.html
(live test)
(source)
tiled-conic-gradients.html
(live test)
(source)
color-stops-parsing.html
(live test)
(source)
gradient-interpolation-method-computed.html
(live test)
(source)
gradient-interpolation-method-invalid.html
(live test)
(source)
gradient-interpolation-method-valid.html
(live test)
(source)
gradient-position-invalid.html
(live test)
(source)
gradient-position-valid.html
(live test)
(source)
3.3.2.
Placing Color Stops
Color stops are placed on a
gradient line
that curves around the
gradient center
in a circle,
with both the 0% and 100% locations at 0deg.
Just like linear gradients,
0deg points to the top of the page,
and increasing angles correspond to clockwise movement around the circle.
Note:
It may be more helpful to think of the gradient line as forming a spiral,
where only the segment from 0deg to 360deg is rendered.
This avoids any confusion about "overlap" when you have angles outside of the rendered region.
A color-stop can be placed at a location before 0% or after 100%;
though these regions are never directly consulted for rendering,
color stops placed there can affect the color of color-stops within the rendered region
through interpolation or repetition (see
repeating gradients
).
For example,
conic-gradient(red -50%, yellow 150%)
produces a conic gradient
that starts with a reddish-orange color at 0deg (specifically, #f50),
and transitions to an orangish-yellow color at 360deg (specifically, #fa0).
The color of the gradient at any point is determined by first finding the unique ray
anchored at the center of the gradient that passes through the given point.
The point’s color is then the color of the
gradient line
at the location where this ray intersects it.
3.3.3.
Conic Gradient Examples
All of the following
conic-gradient()
examples are presumed to be applied to a box that is 300px wide and 200px tall, unless otherwise specified.
Below are various ways of specifying the same basic conic gradient:
background
conic-gradient
#f06
gold
);
background
conic-gradient
at
50
50
#f06
gold
);
background
conic-gradient
from
deg
#f06
gold
);
background
conic-gradient
from
deg
at center
#f06
gold
);
background
conic-gradient
#f06
gold
100
);
background
conic-gradient
#f06
deg
gold
turn
);
Below are various ways of specifying the same basic conic gradient.
This demonstrates how even though color stops with angles outside [0deg, 360deg) are not directly painted,
they can still affect the color of the painted part of the gradient.
background
conic-gradient
white
-50
black
150
);
background
conic-gradient
white
-180
deg
black
540
deg
);
background
conic-gradient
hsl
75
),
hsl
25
));
Below are two different ways of specifying the same rotated conic gradient, one with a rotation angle and one without:
background
conic-gradient
from
45
deg
white
black
white
);
background
conic-gradient
hsl
75
),
white
45
deg
black
225
deg
hsl
75
));
Note that offsetting every color stop by the rotation angle instead would not work and produces an entirely different gradient:
background
conic-gradient
white
45
deg
black
225
deg
white
405
deg
);
A conic gradient with a radial gradient overlaid on it, to draw a hue & saturation wheel:
background
radial-gradient
closest-side
gray
transparent
),
conic-gradient
red
magenta
blue
aqua
lime
yellow
red
);
border-radius
50
width
200
px
height
200
px
You can also achieve the same effect using "longer" hue interpolation. This is more concise and makes it easy to switch to other color spaces.
background
radial-gradient
closest-side
gray
transparent
),
conic-gradient
in hsl longer hue
red
100
);
transform
scaleX
-1
);
border-radius
50
width
200
px
height
200
px
A conic gradient used to draw a simple pie chart.
The
0deg
color stop positions will be fixed up to be equal to the position of the color stop before them.
This will produce infinitesimal (invisible) transitions between the color stops with different colors,
effectively producing solid color segments.
background
conic-gradient
yellowgreen
40
gold
deg
75
#f06
deg
);
border-radius
50
width
200
px
height
200
px
3.4.
Repeating Gradients: the
repeating-linear-gradient()
repeating-radial-gradient()
, and
repeating-conic-gradient()
notations
In addition to
linear-gradient()
radial-gradient()
, and
conic-gradient()
this specification defines
repeating-linear-gradient()
repeating-radial-gradient()
and
repeating-conic-gradient()
values.
These notations take the same values
and are interpreted the same
as their respective non-repeating siblings defined previously.
repeating-conic-gradient
()
repeating-conic-gradient

repeating-linear-gradient
()
repeating-linear-gradient

repeating-radial-gradient
()
repeating-radial-gradient

Tests
gradient-content-box.html
(live test)
(source)
color-stops-parsing.html
(live test)
(source)
repeating-gradient-hsl-and-oklch.html
(live test)
(source)
Basic repeating conic gradient:
background
repeating-conic-gradient
gold
#f06
20
deg
);
Repeating color stops with abrupt transitions creates a starburst-type background:
background
repeating-conic-gradient
hsla
100
.2
deg
15
deg
hsla
100
deg
30
deg
#0ac
Here repeating color stops with abrupt transitions are used to create a checkerboard:
background
repeating-conic-gradient
black
deg
25
white
deg
50
);
background-size
60
px
60
px
The same checkerboard can be created via non-repeating conic gradients:
background
conic-gradient
black
25
white
deg
50
black
deg
75
white
deg
);
background-size
60
px
60
px
3.5.
Defining Gradient Color
The colors in gradients are specified using
color stops
(a

and a corresponding position on the
gradient line
and
color transition hints
(a position between two
color stops
representing the halfway point in the color transition)
which are placed on the
gradient line
defining the color at every point of the line.
(Each
gradient function
defines the shape and length of the
gradient line
along with its
starting point
and
ending point
see above.)
Colors throughout the gradient field are then determined
by tying them to specific points along the
gradient line
as specified by the gradient function.
UAs may “dither” gradient colors slightly
(randomly alternate individual pixels with nearby colors on the gradient line)
to effect a smoother gradient.
3.5.1.
Color Stop Lists
Color stops
and
transition hints
are specified
in a
color stop list
which is a list of one or more
color stops
interleaved with optional
transition hints



























Tests
color-stops-parsing.html
(live test)
(source)
gradient-single-stop-001.html
(live test)
(source)
gradient-single-stop-002.html
(live test)
(source)
gradient-single-stop-003.html
(live test)
(source)
gradient-single-stop-004.html
(live test)
(source)
gradient-single-stop-005.html
(live test)
(source)
gradient-single-stop-006.html
(live test)
(source)
gradient-single-stop-007.html
(live test)
(source)
gradient-single-stop-008.html
(live test)
(source)
gradient-single-stop-longer-hue-hsl-002.html
(live test)
(source)
gradient-single-stop-longer-hue-hsl.html
(live test)
(source)
gradient-single-stop-longer-hue-oklch.html
(live test)
(source)
gradient-single-stop-none-interpolation.html
(live test)
(source)
Note that

and

are exactly identical in structure,
they just differ on whether they accept

s or

for specifying the position of the stops and hints.
Visualized with a railroad diagram,
both of them follow this pattern:
color stop
with two positions is equivalent
to specifying two
color stops
with the same color,
one for each position.
Note:
Usually, this results in a solid-color "stripe"
between the two positions,
but using a
longer

will instead create a "rainbow" between the two positions.
Percentages are resolved against the length of the
gradient line
between the
starting point
and
ending point
with 0% being at the starting point
and 100% being at the ending point.
Lengths are measured along the
gradient line
from the
starting point
in the direction of the
ending point
Color stop
and
transition hint
positions
are usually placed between
the
starting point
and
ending point
but that’s not required:
the gradient line extends infinitely in both directions,
and positions can be specified anywhere
on the
gradient line
When the position of a
color stop
is omitted,
it is automatically assigned a position.
The first or last
color stop
in the
color stop list
is assigned
the
gradient line’s
starting point
or
ending point
(respectively).
Otherwise,
it’s assigned the position halfway between the two surrounding stops.
If multiple stops in a row lack a position,
they space themselves out equally
between the surrounding positioned stops.
See
§ 3.5.3 Color Stop “Fixup”
for details.
3.5.2.
Coloring the Gradient Line
At each
color stop
position,
the
gradient line
is the color of the
color stop
Before the first
color stop
the
gradient line
is the color of the first
color stop
and after the last
color stop
the
gradient line
is the color of the last
color stop
Between each pair of
color stops
the
gradient line’s
color is interpolated between the colors of the two
color stops
with the interpolation taking place in the specified color space,
with missing components handled as defined in
CSS Color 4
§ 13.2 Interpolating with Missing Components
hue interpolation as defined in
CSS Color 4
§ 13.4 Hue Interpolation
, and
using premultiplied alpha, as defined in
CSS Color 4
§ 13.3 Interpolating with Alpha
If no

is specified in the gradient function,
the color space used for gradient interpolation
is the default interpolation color space, Oklab, as defined in
[css-color-4]
Note:
The

only affects the colors
between
stops.
The color before the first and after the last stop
is equal to the first/last stop,
regardless
of the interpolation method.
Tests
gradients-with-transparent.html
(live test)
(source)
gradient-analogous-missing-components-001.html
(live test)
(source)
gradient-analogous-missing-components-002.html
(live test)
(source)
gradient-analogous-missing-components-003.html
(live test)
(source)
gradient-analogous-missing-components-004.html
(live test)
(source)
css-color-4-colors-default-to-oklab-gradient.html
(live test)
(source)
gradient-decreasing-hue-hsl.html
(live test)
(source)
gradient-decreasing-hue-lch.html
(live test)
(source)
gradient-eval-predefined-color-spaces.html
(live test)
(source)
gradient-eval-001.html
(live test)
(source)
gradient-eval-002.html
(live test)
(source)
gradient-eval-003.html
(live test)
(source)
gradient-eval-004.html
(live test)
(source)
gradient-eval-005.html
(live test)
(source)
gradient-eval-006.html
(live test)
(source)
gradient-eval-007.html
(live test)
(source)
gradient-eval-008.html
(live test)
(source)
gradient-eval-009.html
(live test)
(source)
gradient-eval-010.html (visual test)
(source)
gradient-none-interpolation.html
(live test)
(source)
gradient-to-transparent.html
(live test)
(source)
legacy-color-gradient.html
(live test)
(source)
oklab-gradient.html
(live test)
(source)
srgb-gradient.html
(live test)
(source)
srgb-linear-gradient.html
(live test)
(source)
xyz-gradient.html
(live test)
(source)
color-scheme-dependent-color-stops.html
(live test)
(source)
gradient-hue-direction.html
(live test)
(source)
gradient-increasing-hue-hsl.html
(live test)
(source)
gradient-increasing-hue-lch.html
(live test)
(source)
gradient-infinity-001.html
(live test)
(source)
gradient-infinity-002.html
(live test)
(source)
gradient-infinity-003.html
(live test)
(source)
gradient-longer-hue-hsl-001.html
(live test)
(source)
gradient-longer-hue-hsl-002.html
(live test)
(source)
gradient-longer-hue-hsl-003.html
(live test)
(source)
gradient-longer-hue-hsl-004.html
(live test)
(source)
gradient-longer-hue-hsl-005.html
(live test)
(source)
gradient-longer-hue-hsl-006.html
(live test)
(source)
gradient-longer-hue-hsl-007.html
(live test)
(source)
gradient-longer-hue-hsl-008.html
(live test)
(source)
gradient-longer-hue-hsl-009.html
(live test)
(source)
gradient-longer-hue-hsl-010.html
(live test)
(source)
gradient-longer-hue-hsl-011.html
(live test)
(source)
gradient-longer-hue-hsl-012.html
(live test)
(source)
gradient-longer-hue-hsl-013.html
(live test)
(source)
gradient-longer-hue-lch-001.html
(live test)
(source)
gradient-longer-hue-lch-002.html
(live test)
(source)
gradient-longer-hue-lch-003.html
(live test)
(source)
gradient-longer-hue-lch-004.html
(live test)
(source)
gradient-longer-hue-lch-005.html
(live test)
(source)
gradient-longer-hue-lch-006.html
(live test)
(source)
gradient-longer-hue-lch-007.html
(live test)
(source)
gradient-longer-hue-lch-008.html
(live test)
(source)
gradient-longer-hue-lch-009.html
(live test)
(source)
gradient-longer-hue-lch-010.html
(live test)
(source)
gradient-longer-hue-lch-011.html
(live test)
(source)
gradient-longer-hue-lch-012.html
(live test)
(source)
gradient-powerless-hue-hsl.html
(live test)
(source)
gradient-powerless-hue-hwb.html
(live test)
(source)
gradient-powerless-hue-lch.html
(live test)
(source)
gradient-powerless-hue-oklch.html
(live test)
(source)
For example, given the following gradient definition:
linear-gradient
in oklch
red
#888
green
the conversion of the neutral #888 to oklch
gives a missing hue component:
oklch(0.6268 0 none)
and thus, in the first gradient segment,
the hue is taken from red,
which is
oklch(0.628 0.2577 29.234)
while in the second segment
it is taken from green,
which is
oklch(0.5198 0.1769 142.5)
By default,
this interpolation is linear—​at 25%, 50%, or 75% of the distance between two
color stops
the color is a 25%, 50%, or 75% blend of the colors of the two stops.
However, if a
transition hint
was provided between two
color stops
the interpolation is non-linear,
and controlled by the hint:
Determine the location of the
transition hint
as a percentage of the distance between the two
color stops
denoted as a number between 0 and 1,
where 0 indicates the hint is placed right on the first
color stop
and 1 indicates the hint is placed right on the second
color stop
Let this percentage be
For any given point between the two color stops,
determine the point’s location as a percentage of the distance between the two
color stops
in the same way as the previous step.
Let this percentage be
Let
, the color weighting at that point,
be equal to
log
.5
The color at that point is then a linear blend between the colors of the two
color stops
blending
of the first stop and
of the second stop.
Note:
The
transition hint
specifies where the “halfway color”—​the 50% blend between the colors of the two surrounding color stops—​should be placed.
When the hint is exactly halfway between the two surrounding color stops,
the above interpolation algorithm
happens to produce the ordinary linear interpolation.
If the hint is placed anywhere else,
it produces a smooth exponential curve
between the surrounding color stops,
with the “halfway color” occurring exactly where the hint specifies.
Here an example of a linear gradient without
transition hint
(top) compared to one with a transition hint between the red and blue
color stops
(bottom).
Top - Without transition hint (falling back to the default halfway transition hint):
background
linear-gradient
to right
red
blue
100
);
Bottom - With transition hint:
background
linear-gradient
to right
red
25
blue
100
);
If multiple
color stops
have the same position,
they produce an infinitesimal transition from the one specified first in the list
to the one specified last.
In effect, the color suddenly changes at that position rather than smoothly transitioning.
3.5.3.
Color Stop “Fixup”
When resolving the
used
positions of each
color stop
the following steps must be applied
in order
If the first
color stop
does not have a position,
set its position to 0%.
If the last
color stop
does not have a position,
set its position to 100%.
If a
color stop
or
transition hint
has a position
that is less than the specified position
of any
color stop
or
transition hint
before it in the list,
set its position to be equal to the largest specified position
of any
color stop
or
transition hint
before it.
If any
color stop
still does not have a position,
then, for each run of adjacent
color stops
without positions,
set their positions so that they are evenly spaced
between the preceding and following
color stops
with positions.
After applying these rules,
all
color stops
and
transition hints
will have a definite position and color
and they will be in ascending order.
Tests
gradient-move-stops.html
(live test)
(source)
gradient-nan-crash.html
(live test)
(source)
gradient-refcrash.html
(live test)
(source)
Note:
It is recommended that authors exercise caution
when mixing different types of units,
such as px, em, or %,
as this can cause a
color stop
to unintentionally try to move before an earlier one.
For example,
the rule
background-image: linear-gradient(yellow 100px, blue 50%)
wouldn’t trigger any fix-up while the background area is at least
200px
tall.
If it was
150px
tall, however,
the blue
color stop’s
position would be equivalent to
75px
which precedes the yellow
color stop
and would be corrected to a position of
100px
Additionally, since the relative ordering of such color stops
cannot be determined without performing layout,
they will not interpolate smoothly in
animations
or
transitions
Below are several pairs of gradients.
The latter of each pair is a manually “fixed-up” version of the former,
obtained by applying the above rules.
For each pair, both gradients will render identically.
The numbers in each arrow specify which fixup steps are invoked in the transformation.
linear-gradient
red
white
20
blue
=>
linear-gradient
red
white
20
blue
100
linear-gradient
red
40
white
black
blue
=>
linear-gradient
red
40
white
60
black
80
blue
100
linear-gradient
red
-50
white
blue
=>
linear-gradient
red
-50
white
25
blue
100
linear-gradient
red
-50
px
white
blue
=>
linear-gradient
red
-50
px
white
calc
-25
px
50
),
blue
100
linear-gradient
red
20
px
white
px
blue
40
px
=>
linear-gradient
red
20
px
white
20
px
blue
40
px
linear-gradient
red
white
-50
black
150
blue
=>
linear-gradient
red
white
black
150
blue
150
linear-gradient
red
80
px
white
px
black
blue
100
px
=>
linear-gradient
red
80
px
white
80
px
black
90
px
blue
100
px
4.
1D Image Values: the

type and
stripes()
notation
While

values represent a 2-dimensional (2D) image,
and

can be thought of as a 0-dimensional (0D) image
(unvarying in either axis),
some contexts require a
1-dimensional (1D) image
which specifies colors along an abstract, directionless, single-axis
paint line
The

type represents such
1D images
including the
stripes()
functional notation
=
stripes
()
stripes
()
stripes



&&


The
stripes()
function defines a
1D image
as a comma-separated list of colored stripes,
each placed end-to-end on the
paint line
in the order given.
Each

entry defines a solid-color stripe
with the specified

and thickness.
If the thickness is omitted,
it defaults to
1fr
Thickness values are interpreted as follows:

Percentage thicknesses are relative to the
total width
Only values between
0%
and
100%
(inclusive)
are valid.

Negative length values are invalid.


is evaluated as a fraction of the
total width
relative to the total sum of

entries in the function,
after subtracting the thickness of any non-

entries
(flooring the subtraction result at zero).
If the sum of

values is less than
1fr
the result of the subtraction is multiplied by the sum’s value
before being distributed.
The
total width
refers to the length of the
paint line
It is defined by the context in which the
stripes()
function is used.
If the sum of the stripes is smaller than the
total width
the
paint line
is
transparent black
for its remaining length,
as if a final
transparent
argument were given.
If the sum is larger,
any stripes or portions beyond the
total width
are truncated.
For example,
stripes(red 1fr, green 2fr, blue 100px)
with a
total width
of
400px
will result in a 100px red stripe and 200px green stripe,
giving red 1 share and green 2 shares of the 300px remaining
after subtracting blue’s 100px from the 400px total.
On the other hand,
stripes(red .1fr, green .2fr, blue 100px)
with a
total width
of
400px
will instead give a 30px red stripe and 60px green stripe,
followed by 100px of blue and then 210px of transparent.
The 300px of leftover space is multiplied by .3,
the value of the sum of the

values,
to obtain only 90px,
which is then distributed in the 1:2 ratio
dictated by the

values.
(This is similar to how
flex layout
deals with small

sums on a line,
and ensures smoothly continuous behavior
as the

values approach zero.)
The
computed value
of this function is
an ordered list of stripes,
each given as a
computed color
and a thickness represented either a

value
or a computed

value.
5.
Sizing Images and Objects in CSS
5.1.
Sizing Objects: the
object-fit
property
Name:
object-fit
Value:
fill
none
[contain
cover]
||
scale-down
Initial:
fill
Applies to:
replaced elements
Inherited:
no
Percentages:
n/a
Computed value:
specified keyword(s)
Canonical order:
per grammar
Animation type:
discrete
The
object-fit
property specifies how the contents of a replaced element
should be fitted to the box established by its used height and width.
fill
The replaced content is sized to fill the element’s content box:
the object’s
concrete object size
is the element’s used width and height.
none
The replaced content is not resized to fit inside the element’s content box:
determine the object’s
concrete object size
using the
default sizing algorithm
with no specified size,
and a
default object size
equal to the replaced element’s used width and height.
contain
The replaced content is sized to maintain its aspect ratio
while fitting within the element’s content box:
its
concrete object size
is resolved as a
contain constraint
against the element’s used width and height.
If the
scale-down
flag is used, size the content as if
none
or
contain
were specified,
whichever would result in a smaller
concrete object size
Note:
Both
none
and
contain
respect the content’s
natural aspect ratio
so the concept of "smaller" is well-defined.
cover
The replaced content is sized to maintain its aspect ratio
while filling the element’s entire content box:
its
concrete object size
is resolved as a
cover constraint
against the element’s used width and height.
If the
scale-down
flag is used, size the content as if
none
or
cover
were specified,
whichever would result in a smaller
concrete object size
Note:
Both
none
and
cover
respect the content’s
natural aspect ratio
so the concept of "smaller" is well-defined.
scale-down
Equivalent to
contain scale-down
Tests
inheritance.html
(live test)
(source)
object-fit-contain-png-001c.html
(live test)
(source)
object-fit-contain-png-001e.html
(live test)
(source)
object-fit-contain-png-001i.html
(live test)
(source)
object-fit-contain-png-001o.html
(live test)
(source)
object-fit-contain-png-001p.html
(live test)
(source)
object-fit-contain-png-002c.html
(live test)
(source)
object-fit-contain-png-002e.html
(live test)
(source)
object-fit-contain-png-002i.html
(live test)
(source)
object-fit-contain-png-002o.html
(live test)
(source)
object-fit-contain-png-002p.html
(live test)
(source)
object-fit-contain-svg-001e.html
(live test)
(source)
object-fit-contain-svg-001i.html
(live test)
(source)
object-fit-contain-svg-001o.html
(live test)
(source)
object-fit-contain-svg-001p.html
(live test)
(source)
object-fit-contain-svg-002e.html
(live test)
(source)
object-fit-contain-svg-002i.html
(live test)
(source)
object-fit-contain-svg-002o.html
(live test)
(source)
object-fit-contain-svg-002p.html
(live test)
(source)
object-fit-contain-svg-003e.html
(live test)
(source)
object-fit-contain-svg-003i.html
(live test)
(source)
object-fit-contain-svg-003o.html
(live test)
(source)
object-fit-contain-svg-003p.html
(live test)
(source)
object-fit-contain-svg-004e.html
(live test)
(source)
object-fit-contain-svg-004i.html
(live test)
(source)
object-fit-contain-svg-004o.html
(live test)
(source)
object-fit-contain-svg-004p.html
(live test)
(source)
object-fit-contain-svg-005e.html
(live test)
(source)
object-fit-contain-svg-005i.html
(live test)
(source)
object-fit-contain-svg-005o.html
(live test)
(source)
object-fit-contain-svg-005p.html
(live test)
(source)
object-fit-contain-svg-006e.html
(live test)
(source)
object-fit-contain-svg-006i.html
(live test)
(source)
object-fit-contain-svg-006o.html
(live test)
(source)
object-fit-contain-svg-006p.html
(live test)
(source)
object-fit-cover-png-001c.html
(live test)
(source)
object-fit-cover-png-001e.html
(live test)
(source)
object-fit-cover-png-001i.html
(live test)
(source)
object-fit-cover-png-001o.html
(live test)
(source)
object-fit-cover-png-001p.html
(live test)
(source)
object-fit-cover-png-002c.html
(live test)
(source)
object-fit-cover-png-002e.html
(live test)
(source)
object-fit-cover-png-002i.html
(live test)
(source)
object-fit-cover-png-002o.html
(live test)
(source)
object-fit-cover-png-002p.html
(live test)
(source)
object-fit-cover-svg-001e.html
(live test)
(source)
object-fit-cover-svg-001i.html
(live test)
(source)
object-fit-cover-svg-001o.html
(live test)
(source)
object-fit-cover-svg-001p.html
(live test)
(source)
object-fit-cover-svg-002e.html
(live test)
(source)
object-fit-cover-svg-002i.html
(live test)
(source)
object-fit-cover-svg-002o.html
(live test)
(source)
object-fit-cover-svg-002p.html
(live test)
(source)
object-fit-cover-svg-003e.html
(live test)
(source)
object-fit-cover-svg-003i.html
(live test)
(source)
object-fit-cover-svg-003o.html
(live test)
(source)
object-fit-cover-svg-003p.html
(live test)
(source)
object-fit-cover-svg-004e.html
(live test)
(source)
object-fit-cover-svg-004i.html
(live test)
(source)
object-fit-cover-svg-004o.html
(live test)
(source)
object-fit-cover-svg-004p.html
(live test)
(source)
object-fit-cover-svg-005e.html
(live test)
(source)
object-fit-cover-svg-005i.html
(live test)
(source)
object-fit-cover-svg-005o.html
(live test)
(source)
object-fit-cover-svg-005p.html
(live test)
(source)
object-fit-cover-svg-006e.html
(live test)
(source)
object-fit-cover-svg-006i.html
(live test)
(source)
object-fit-cover-svg-006o.html
(live test)
(source)
object-fit-cover-svg-006p.html
(live test)
(source)
object-fit-dyn-aspect-ratio-001.html
(live test)
(source)
object-fit-dyn-aspect-ratio-002.html
(live test)
(source)
object-fit-fill-png-001c.html
(live test)
(source)
object-fit-fill-png-001e.html
(live test)
(source)
object-fit-fill-png-001i.html
(live test)
(source)
object-fit-fill-png-001o.html
(live test)
(source)
object-fit-fill-png-001p.html
(live test)
(source)
object-fit-fill-png-002c.html
(live test)
(source)
object-fit-fill-png-002e.html
(live test)
(source)
object-fit-fill-png-002i.html
(live test)
(source)
object-fit-fill-png-002o.html
(live test)
(source)
object-fit-fill-png-002p.html
(live test)
(source)
object-fit-fill-svg-001e.html
(live test)
(source)
object-fit-fill-svg-001i.html
(live test)
(source)
object-fit-fill-svg-001o.html
(live test)
(source)
object-fit-fill-svg-001p.html
(live test)
(source)
object-fit-fill-svg-002e.html
(live test)
(source)
object-fit-fill-svg-002i.html
(live test)
(source)
object-fit-fill-svg-002o.html
(live test)
(source)
object-fit-fill-svg-002p.html
(live test)
(source)
object-fit-fill-svg-003e.html
(live test)
(source)
object-fit-fill-svg-003i.html
(live test)
(source)
object-fit-fill-svg-003o.html
(live test)
(source)
object-fit-fill-svg-003p.html
(live test)
(source)
object-fit-fill-svg-004e.html
(live test)
(source)
object-fit-fill-svg-004i.html
(live test)
(source)
object-fit-fill-svg-004o.html
(live test)
(source)
object-fit-fill-svg-004p.html
(live test)
(source)
object-fit-fill-svg-005e.html
(live test)
(source)
object-fit-fill-svg-005i.html
(live test)
(source)
object-fit-fill-svg-005o.html
(live test)
(source)
object-fit-fill-svg-005p.html
(live test)
(source)
object-fit-fill-svg-006e.html
(live test)
(source)
object-fit-fill-svg-006i.html
(live test)
(source)
object-fit-fill-svg-006o.html
(live test)
(source)
object-fit-fill-svg-006p.html
(live test)
(source)
object-fit-none-png-001c.html
(live test)
(source)
object-fit-none-png-001e.html
(live test)
(source)
object-fit-none-png-001i.html
(live test)
(source)
object-fit-none-png-001o.html
(live test)
(source)
object-fit-none-png-001p.html
(live test)
(source)
object-fit-none-png-002c.html
(live test)
(source)
object-fit-none-png-002e.html
(live test)
(source)
object-fit-none-png-002i.html
(live test)
(source)
object-fit-none-png-002o.html
(live test)
(source)
object-fit-none-png-002p.html
(live test)
(source)
object-fit-none-svg-001e.html
(live test)
(source)
object-fit-none-svg-001i.html
(live test)
(source)
object-fit-none-svg-001o.html
(live test)
(source)
object-fit-none-svg-001p.html
(live test)
(source)
object-fit-none-svg-002e.html
(live test)
(source)
object-fit-none-svg-002i.html
(live test)
(source)
object-fit-none-svg-002o.html
(live test)
(source)
object-fit-none-svg-002p.html
(live test)
(source)
object-fit-none-svg-003e.html
(live test)
(source)
object-fit-none-svg-003i.html
(live test)
(source)
object-fit-none-svg-003o.html
(live test)
(source)
object-fit-none-svg-003p.html
(live test)
(source)
object-fit-none-svg-004e.html
(live test)
(source)
object-fit-none-svg-004i.html
(live test)
(source)
object-fit-none-svg-004o.html
(live test)
(source)
object-fit-none-svg-004p.html
(live test)
(source)
object-fit-none-svg-005e.html
(live test)
(source)
object-fit-none-svg-005i.html
(live test)
(source)
object-fit-none-svg-005o.html
(live test)
(source)
object-fit-none-svg-005p.html
(live test)
(source)
object-fit-none-svg-006e.html
(live test)
(source)
object-fit-none-svg-006i.html
(live test)
(source)
object-fit-none-svg-006o.html
(live test)
(source)
object-fit-none-svg-006p.html
(live test)
(source)
object-fit-scale-down-png-001c.html
(live test)
(source)
object-fit-scale-down-png-001e.html
(live test)
(source)
object-fit-scale-down-png-001i.html
(live test)
(source)
object-fit-scale-down-png-001o.html
(live test)
(source)
object-fit-scale-down-png-001p.html
(live test)
(source)
object-fit-scale-down-png-002c.html
(live test)
(source)
object-fit-scale-down-png-002e.html
(live test)
(source)
object-fit-scale-down-png-002i.html
(live test)
(source)
object-fit-scale-down-png-002o.html
(live test)
(source)
object-fit-scale-down-png-002p.html
(live test)
(source)
object-fit-scale-down-svg-001e.html
(live test)
(source)
object-fit-scale-down-svg-001i.html
(live test)
(source)
object-fit-scale-down-svg-001o.html
(live test)
(source)
object-fit-scale-down-svg-001p.html
(live test)
(source)
object-fit-scale-down-svg-002e.html
(live test)
(source)
object-fit-scale-down-svg-002i.html
(live test)
(source)
object-fit-scale-down-svg-002o.html
(live test)
(source)
object-fit-scale-down-svg-002p.html
(live test)
(source)
object-fit-scale-down-svg-003e.html
(live test)
(source)
object-fit-scale-down-svg-003i.html
(live test)
(source)
object-fit-scale-down-svg-003o.html
(live test)
(source)
object-fit-scale-down-svg-003p.html
(live test)
(source)
object-fit-scale-down-svg-004e.html
(live test)
(source)
object-fit-scale-down-svg-004i.html
(live test)
(source)
object-fit-scale-down-svg-004o.html
(live test)
(source)
object-fit-scale-down-svg-004p.html
(live test)
(source)
object-fit-scale-down-svg-005e.html
(live test)
(source)
object-fit-scale-down-svg-005i.html
(live test)
(source)
object-fit-scale-down-svg-005o.html
(live test)
(source)
object-fit-scale-down-svg-005p.html
(live test)
(source)
object-fit-scale-down-svg-006e.html
(live test)
(source)
object-fit-scale-down-svg-006i.html
(live test)
(source)
object-fit-scale-down-svg-006o.html
(live test)
(source)
object-fit-scale-down-svg-006p.html
(live test)
(source)
object-fit-computed.html
(live test)
(source)
object-fit-invalid.html
(live test)
(source)
object-fit-valid.html
(live test)
(source)
If the content does not completely fill the replaced element’s content box,
the unfilled space shows the replaced element’s background.
Since replaced elements always clip their contents to the content box,
the content will never overflow.
See the
object-position
property for positioning the object with respect to the content box.
An example showing how four of the values of
object-fit
cause the replaced element (blue figure)
to be scaled to fit its height/width box (shown with a green background),
using the initial value for
object-position
In this case,
scale-down
and
scale-down contain
would look identical to
contain
and
scale-down cover
would look identical to
none
Note:
The
object-fit
property has similar semantics to
the
fit
attribute in
[SMIL10]
and the

parameter
on the
preserveAspectRatio
attribute
in
[SVG11]
Note:
Per the
object size negotiation
algorithm,
the
concrete object size
(or, in this case, the size of the content)
does not directly scale the object itself -
it is merely passed to the object as information about the size of the visible canvas.
How to then draw into that size is up to the image format.
In particular, raster images always scale to the given size,
while SVG uses the given size as the size of the "SVG Viewport"
(a term defined by SVG)
and then uses the values of several attributes on the root

element to determine how to draw itself.
6.
Image Processing
6.1.
Overriding Image Resolutions: the
image-resolution
property
The
image resolution
is defined as
the number of image pixels per unit length,
e.g., pixels per inch.
Some image formats can record information about the resolution of images.
This information can be helpful when determining the actual size of the image in the formatting process.
However, the information can also be wrong,
in which case it should be ignored.
By default, CSS assumes a resolution of one image pixel per CSS
px
unit;
however, the
image-resolution
property allows using some other resolution.
Name:
image-resolution
Value:
[ from-image
||

&&
snap
Initial:
1dppx
Applies to:
all elements
Inherited:
yes
Percentages:
n/a
Computed value:
specified keyword(s) and/or

(possibly adjusted for
snap
, see below)
Canonical order:
per grammar
Animation type:
discrete
The
image-set()
notation can alter the
natural resolution
of an image,
which ideally would be automatically honored without having to set this property.
How should we best address this?
Change the initial value to
auto
, meaning "1dppx, unless CSS says otherwise"?
Say that image-resolution has no effect on images whose resolution was set by something else in CSS?
Or somehow wordsmithing
image-set()
in some way such that it always produces
1dppx
images somehow?
The
image-resolution
property specifies the
preferred resolution
of all raster images used in or on the element.
It affects both content images
(e.g. replaced elements and generated content)
and decorative images
(such as
background-image
).
The
preferred resolution
of an image is used to determine the image’s
natural dimensions
Values have the following meanings:

Specifies the
preferred resolution
explicitly.
A "dot" in this case corresponds to a single image pixel.
from-image
The image’s
preferred resolution
is taken as that specified by the image format
(the
natural resolution
).
If the image does not specify its own resolution,
the explicitly specified resolution is used (if given),
else it defaults to
1dppx
Note:
CSS Images 3
§ 2.1.2 Image Metadata
imposes some restrictions on what metadata can be used.
snap
If the "snap" keyword is provided,
the computed

(if any)
is the specified resolution rounded to the nearest value
that would map one image pixel to an integer number of device pixels.
If the resolution is taken from the image,
then the used
natural resolution
is the image’s native resolution similarly adjusted.
As vector formats such as SVG do not have a
natural resolution
this property has no effect on vector images.
Printers tend to have substantially higher resolution than computer monitors;
due to this, an image that looks fine on the screen may look pixelated when printed out.
The
image-resolution
property can be used to embed a high-resolution image into the document
and maintain an appropriate size,
ensuring attractive display both on screen and on paper:
img.high-res
image-resolution
300
dpi
With this set, an image meant to be 5 inches wide at 300dpi
will actually display as 5in wide;
without this set,
the image would display as approximately 15.6in wide
since the image is 15000 image pixels across,
and by default CSS displays 96 image pixels per inch.
Some image formats can encode the image resolution into the image data.
This rule specifies that the UA should use the image resolution found in the image itself,
falling back to 1 image pixel per CSS
px
unit.
img
image-resolution
from-image
These rules both specify that the UA should use the image resolution found in the image itself,
but if the image has no resolution,
the resolution is set to
300dpi
instead of the default
1dppx
img
image-resolution
from-image
300
dpi
img
image-resolution
300
dpi
from-image
Using this rule, the image resolution is set to 300dpi.
(The resolution in the image, if any, is ignored.)
img
image-resolution
300
dpi
This rule, on the other hand,
if used when the screen’s resolution is 96dpi,
would instead render the image at 288dpi
(so that 3 image pixels map to 1 device pixel):
img
image-resolution
300
dpi
snap
The
snap
keyword can also be used when the resolution is taken from the image:
img
image-resolution
snap from-image
An image declaring itself as 300dpi will,
in the situation above,
display at 288dpi
(3 image pixels per device pixel)
whereas an image declaring 72dpi will render at 96dpi
(1 image pixel per device pixel).
7.
Interpolation
This section describes how to interpolate between new value types defined in this specification,
for use with modules such as CSS Transitions and CSS Animations.
If an algorithm below simply states that two values should be "interpolated" or "transitioned" without further details,
then the value should be interpolated as described by the Transitions spec.
Otherwise, the algorithm may reference a variable
in its detailed description of the interpolation.
This is a number which starts at 0% and goes to 100%,
and is set to a value that represents the progress through the transition,
based on the duration of the transition,
the elapsed time,
and the timing function in use.
For example, with a linear timing function and a 1s duration,
after .3s
is equal to 30%.
7.1.
Interpolating

All images can be interpolated,
though some special types of images
(like some gradients)
have their own special interpolation rules.
In general terms,
images are interpolated by scaling them to the size of the
start image
and cross-fading the two while they transition to the size of the
end image
In specific terms,
at each point in the interpolation
the image is equal to
cross-fade
100
start image
end image
Special-case interpolating to/from no image,
like "background-image: url(foo);" to "background-image: none;".
7.2.
Interpolating cross-fade()
The three components of
cross-fade()
are interpolated independently.
Note this may result in nested
cross-fade()
notations.
7.3.
Interpolating

This section needs review and improvement.
In particular, I believe the handling of linear-gradient() is incomplete -
I think we want to specifically interpolate the "length" of the gradient line
(the distance between 0% and 100%)
between the starting and ending positions explicitly,
so it doesn’t grow and then shrink over a single animation.
Gradient images can be interpolated directly in CSS transitions and animations,
smoothly animating from one gradient to another.
There are only a few restrictions on what gradients are allowed to be interpolated:
Both the starting and ending gradient must be expressed with the same function.
(For example, you can transition from a
linear-gradient()
to a
linear-gradient()
but not from a
linear-gradient()
to a
radial-gradient()
or a
repeating-linear-gradient()
.)
Both the starting and ending gradient must have the same number of

s.
For this purpose, all repeating gradients are considered to have infinite color stops,
and thus all repeating gradients match in this respect.
Neither gradient uses a combination of

and

color stops.
If the two gradients satisfy all of those constraints,
they must be interpolated as described below.
If they fail the third one only,
they must be abruptly transitioned at 50%
(unless otherwise specified by a future specification).
If they fail either of the first two constraints,
they must be interpolated using
cross-fade()
as for generic images.
Note:
The abrupt transition at 50% is so that content will not rely on cross-fading,
and smarter interpolation rules can be added for this case in the future.
Convert both the start and end gradients to their explicit forms:
For linear gradients:
If the direction is specified as an

it is already in its explicit form.
Otherwise,
change its direction to an

in [
0deg
360deg
that would produce an equivalent rendering.
If both the start and end gradients had their direction specified with keywords,
and the absolute difference between the angles their directions mapped to is greater than 180deg,
add 360deg to the direction of the gradient with the smaller angle.
This ensures that a transition from, for example,
"to left" (270deg) to "to top" (0deg)
rotates the gradient a quarter-turn clockwise,
as expected,
rather than rotating three-quarters of a turn counter-clockwise.
For radial gradients:
If the size is specified as two

s or

s,
it is already in its explicit form.
Otherwise, the size must be changed to a pair of

that would produce an equivalent ending-shape.
If the

was specified as
circle
change it to
ellipse
Interpolate each component and color-stop of the gradients independently.
For linear gradients,
the only component is the angle.
For radial gradients,
the components are the horizontal and vertical position of the center
and the horizontal and vertical axis lengths.
To interpolate a color-stop,
first match each color-stop in the start gradient
to the corresponding color-stop at the same index in the end gradient.
For repeating gradients,
the first specified color-stop in the start and end gradients
are considered to be at the same index,
and all other color-stops following and preceding are indexed appropriately,
repeating and shifting each gradient’s list of color-stops as needed.
Then, for each pair of color-stops,
interpolate the position and color independently.
7.4.
Interpolating
stripes()
Similar to gradients,
two
stripes()
can be interpolated,
allowing for smooth animations from one image to another.
There is only one restriction on what
stripes()
are allowed to be interpolated.
Both the starting and ending image must have the same number of

s.
If the two images satisfy this constraint,
they must be interpolated as described below.
If they fail the constraint,
they must be interpolated using
cross-fade()
as for generic images.
Interpolate each component and stripe of the images independently.
To interpolate a stripe,
first match each stripe in the start image
to the corresponding stripe at the same index in the end image.
Then, for each pair of stripes,
interpolate the thickness
and color independently.

values are interpolated as

s using the following formula:
max
100
- sum-of-percents - sum-of-fixed
* flex value /
max
sum-of-flexes
where
sum-of-percents
is the sum of all

s in the
stripes()
function,
sum-of-fixed
is the sum of all fixed

s in the function,
and
sum-of-flexes
is the sum of all

values.
8.
Serialization
This section describes the serialization of all new properties and value types introduced in this specification,
for the purpose of interfacing with the CSS Object Model
[CSSOM]
To serialize any function defined in this module,
serialize it per its individual grammar,
in the order its grammar is written in,
omitting components when possible without changing the meaning,
joining space-separated tokens with a single space,
and following each serialized comma with a single space.
For
cross-fade()
always serialize the

For example, a gradient specified as:
Linear-Gradient
to bottom
red
yellow
black
100
px
must serialize as:
linear-gradient
rgb
255
),
rgb
255
255
),
rgb
100
px
Appendix A: Deprecated Features and Aliases
Implementations must accept
-webkit-image-set()
as a parse-time alias of
image-set()
(It’s a valid value, with identical arguments to
image-set()
and is turned into
image-set()
during parsing.)
9.
Privacy Considerations
Note:
No change from
[css-images-3]
10.
Security Considerations
Note:
No change from
[css-images-3]
11.
Changes
Changes Since the
30 September 2025
Working Draft
(none)
Changes Since the
17 February 2023
Working Draft
Cleaned up the use of fetching external URLs for style resources
Issue 12065
Issue 12068
Issue 12086
Issue 12147
Made cross-fade() accept 1+ arguments
Issue 11530
Allowed for angular color stop/hint
Explicitly allowed for gradient rotation
Fixed note about double positions making a stripe.
Added note about color before/after the stop lists.
Issue 11381
Separated the first and last stop fixing into separate steps,
so it’s clearer what happens with a single stop
Issue 10092
Allow just one color stop
Issue 10092
Made cross-fade() have same order as color-mix()
Issue 9405
Added example images for the stripes() function
PR 9749
Added

values to
radial-gradient(circle)
and dual

values to
radial-gradient(ellipse)
to make
radial-gradient()
consistent with
the
circle()
and
ellipse()

s.
Issue 824
Added example of missing hues when interpolating with neutrals
Issue 4928
Explicitly linked to CSS Color 4 hue interpolation, and handling of missing components
Issue 4928
Allowed omitting resolution/type in image-set()
Applied fix from
PR #8021
to gradient definitions in CSS Images 4
Issue 9147
Made explicit what the default interpolation color space is.
Issue 7947
Fixed duplicate repeating gradient definitions
Issue 8797
Added basic syntax of repeating gradient types
Issue 8775
Fixed interpolation of stripes() with different types
Issue 8614
Added url request modifiers to enable request parameters
PR 8222
Specified that image-set() is an invalid image if you remove all the options.
Issue 8266
Changes Since the
13 April 2017
Working Draft
Major editorial rewrite of
§ 3.5 Defining Gradient Color
Added new

data type and
stripes()
function.
Issue 2532
Added

to all gradient functions.
(Issues
6094
6667
Added new
object-view-box
property.
Issue 7058
Pulled definition of
image-set()
from
[css-images-3]
and:
Added
type()
to
image-set()
Issue 656
Added the
-webkit-image-set()
compatibility alias.
Issue 6285
Pulled definition of
cross-fade()
from
[css-images-3]
and:
Clarified that
cross-fade()
takes 1+ arguments.
Updated to allow mixing colors as well as images.
Defined sizing and painting of the new function arguments in detail.
Fixed incorrect definition of
cross-fade()
image blending.
Add issue about computation planned simplification and comparison.
Issue 2852
Minutes
Changeset
Pulled
interpolation
and
serialization
of images from
[css-images-3]
Defined that image metadata placed after the image data should be ignored, see
CSS Images 3
§ 2.1.2 Image Metadata
Issue 4929
Defined image loading.
Issue 1984
Copied definition of
loading image
from
[css-images-3]
Integrated loading and error handling into
image()
behavior.
Explicitly allow UA to render the old image while a new image loads in to replace another.
Properly defined
§ 2.3 Fetching External Images
Issue 562
Pull Request 6715
Updated
CSS
interface to a namespace.
Issue 437
Allowed unitless zero to represent

values in
conic-gradient()
Issue 1162
Changes
Allowed
scale-down
to be combined with other values in
object-fit
Issue 1578
Added missing

to

data type.
issue 5170
Fixed
elementSources
IDL definition.
Fixed grammar error requiring color stop positions to be mandatory.
Issue 1334
Updated property definition tables to:
Align “Computed Value” and “Animation Type” lines across modules, tighten wording, and correct errors.
Use the new
CSS bracketed range notation
where appropriate.
Drop “Media” lines.
Renamed “intrinsic dimensions” to
natural dimensions
to avoid confusion with
intrinsic sizes
Issue 4961
Copied over definition of computed

from
[css-images-3]
Issue 4042
Explicitly allowed dithering in gradients.
Issue 4793
Assorted markup fixes, corrections to property syntaxes, inline issues, spelling corrections, example fixes and improvements, and minor editorial refinements.
Shortened module title.
Changes Since the
11 September 2012 Working Draft
Added
color interpolation hints
Added the
two location syntax
for gradient color stops
Added start angles to
conic gradients
The position(s) of a color stop can now come before the color
Text that is identical to
[css-images-3]
has been replaced with a reference to
[css-images-3]
Added the
-webkit-image-set()
alias.
Changes Since Level 3
Added the
image()
notation (deferred from Level 3)
Added the
image-resolution
property (deferred from Level 3)
Added the
element()
notation (deferred from Level 3)
Added
conic gradients
Added to all gradient functions
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
"advisement"
, like
this:
UAs MUST provide an accessible alternative.
Tests
Tests relating to the content of this specification
may be documented in “Tests” blocks like this one.
Any such block is non-normative.
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
1D image
, in § 4
1-dimensional image
, in § 4
|
, in § 3.3.1

, in § 3.5.1

, in § 3.5.1

, in § 3.5.1
appearance of a cross-fade()
, in § 2.6.2

, in § 2.6

, in § 3.5.1
color stop
, in § 3.5

, in § 3.5.1

, in § 3.5.1

, in § 3.5.1
color stop list
, in § 3.5.1

, in § 4
color transition hint
, in § 3.5
computed
, in § 2
conic-gradient()
, in § 3.3.1

, in § 3.3.1
contain
, in § 5.1
cover
, in § 5.1
cross-fade()
, in § 2.6
decorated bounding box
, in § 2.7
element()
, in § 2.7
element-not-rendered
, in § 2.7
elementSources
, in § 2.7.2
ending point
, in § 3
fetch an external image for a stylesheet
, in § 2.3
fill
, in § 5.1

, in § 4
from-image
, in § 6.1

, in § 3
gradient box
, in § 3
gradient center
, in § 3.3.1
gradient function
, in § 3
gradient line
, in § 3

, in § 2
image()
, in § 2.5

, in § 4
image resolution
, in § 6.1
image-resolution
, in § 6.1
image-set()
, in § 2.4

, in § 2.4

, in § 2.5

, in § 2.5
invalid image
, in § 2

, in § 4

, in § 3.5.1

, in § 3.5.1

, in § 3.1
loading image
, in § 2
natural dimensions of a cross-fade()
, in § 2.6.1
natural resolution
, in § 6.1
none
, in § 5.1
object-fit
, in § 5.1
one-dimensional image
, in § 4
paint line
, in § 4
paint source
, in § 2.7.1

, in § 4

, in § 3.3.1
preferred resolution
, in § 6.1

, in § 3.2.1
repeating-conic-gradient()
, in § 3.4
repeating-linear-gradient()
, in § 3.4
repeating-radial-gradient()
, in § 3.4

, in § 6.1
scale-down
, in § 5.1

, in § 3.1
snap
, in § 6.1
starting point
, in § 3
stripes()
, in § 4
transition hint
, in § 3.5
type()
, in § 2.4
valid image
, in § 2
-webkit-image-set()
, in § Unnumbered section
Terms defined by reference
[CSS-BACKGROUNDS-3]
defines the following terms:
background-color
background-image
background-position
background-size
center
[CSS-CASCADE-5]
defines the following terms:
computed value
specified value
used value
[CSS-COLOR-4]
defines the following terms:

computed color
transparent
transparent black
[CSS-COLOR-5]
defines the following terms:

[CSS-FLEXBOX-1]
defines the following terms:
flex layout
[CSS-GRID-2]
defines the following terms:

[CSS-IMAGES-3]
defines the following terms:



circle
concrete object size
contain constraint
cover constraint
default object size
default sizing algorithm
ellipse
linear-gradient()
natural aspect ratio
natural dimension
natural height
natural size
natural width
object size negotiation
object-position
radial-gradient()
[CSS-IMAGES-5]
defines the following terms:
object-view-box
[CSS-LISTS-3]
defines the following terms:
list-style-image
list-style-type
none
[CSS-SHAPES-1]
defines the following terms:

circle()
ellipse()
[CSS-SIZING-3]
defines the following terms:
intrinsic size
[CSS-UI-4]
defines the following terms:
cursor
[CSS-VALUES-4]
defines the following terms:
&&










CSS bracketed range notation
CSS-wide keywords
fetch a style resource
functional notation
px
url()
{A,B}
||
[CSS-VALUES-5]
defines the following terms:

normalize mix percentages
[CSS2]
defines the following terms:
stacking context
[CSSOM]
defines the following terms:
CSS
CSS declaration block
[FETCH]
defines the following terms:
response
[HTML]
defines the following terms:
canvas
img
picture
video
[INFRA]
defines the following terms:
continue
for each
tuple
[MIMESNIFF]
defines the following terms:
valid MIME type string
[SELECTORS-4]
defines the following terms:

[WEBIDL]
defines the following terms:
SameObject
any
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-COLOR-4]
Tab Atkins Jr.; Chris Lilley; Lea Verou.
CSS Color Module Level 4
. URL:
[CSS-COLOR-5]
Chris Lilley; Una Kravets; Lea Verou.
CSS Color Module Level 5
. URL:
[CSS-GRID-2]
Tab Atkins Jr.; et al.
CSS Grid Layout Module Level 2
. URL:
[CSS-IMAGES-3]
Tab Atkins Jr.; Elika Etemad; Lea Verou.
CSS Images Module Level 3
. URL:
[CSS-IMAGES-5]
CSS Images Module Level 5
. Editor's Draft. URL:
[CSS-LISTS-3]
Elika Etemad; Tab Atkins Jr..
CSS Lists and Counters Module Level 3
. URL:
[CSS-SHAPES-1]
Alan Stearns; Rossen Atanassov; Noam Rosenthal.
CSS Shapes Module Level 1
. URL:
[CSS-SIZING-3]
Tab Atkins Jr.; Elika Etemad.
CSS Box Sizing Module Level 3
. URL:
[CSS-UI-4]
Tab Atkins Jr.; Florian Rivoal.
CSS Basic User Interface Module Level 4
. URL:
[CSS-VALUES-3]
Tab Atkins Jr.; Elika Etemad.
CSS Values and Units Module Level 3
. URL:
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad.
CSS Values and Units Module Level 4
. URL:
[CSS-VALUES-5]
Tab Atkins Jr.; Elika Etemad; Miriam Suzanne.
CSS Values and Units Module Level 5
. URL:
[CSS2]
Bert Bos; et al.
Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification
. URL:
[CSS3-TRANSFORMS]
Simon Fraser; et al.
CSS Transforms Module Level 1
. URL:
[CSSOM]
Daniel Glazman; Emilio Cobos Álvarez.
CSS Object Model (CSSOM)
. URL:
[FETCH]
Anne van Kesteren.
Fetch 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:
[MEDIA-FRAGS]
Raphaël Troncy; et al.
Media Fragments URI 1.0 (basic)
. 25 September 2012. REC. URL:
[MIMESNIFF]
Gordon P. Hemsley.
MIME Sniffing Standard
. Living Standard. URL:
[PNG]
Chris Lilley; et al.
Portable Network Graphics (PNG) Specification (Third Edition)
. URL:
[RFC2119]
S. Bradner.
Key words for use in RFCs to Indicate Requirement Levels
. March 1997. Best Current Practice. URL:
[SELECT]
Tantek Çelik; et al.
Selectors Level 3
. URL:
[SELECTORS-4]
Elika Etemad; Tab Atkins Jr..
Selectors Level 4
. URL:
[SVG-INTEGRATION]
Cameron McCormack; Doug Schepers; Dirk Schulze.
SVG Integration
. URL:
[SVG11]
Erik Dahlström; et al.
Scalable Vector Graphics (SVG) 1.1 (Second Edition)
. 16 August 2011. REC. URL:
[WEBIDL]
Edgar Chen; Timothy Gu.
Web IDL Standard
. Living Standard. URL:
Non-Normative References
[CSS-FLEXBOX-1]
Elika Etemad; Tab Atkins Jr.; Rossen Atanassov.
CSS Flexible Box Layout Module Level 1
. URL:
[SMIL10]
Philipp Hoschka.
Synchronized Multimedia Integration Language (SMIL) 1.0 Specification
. URL:
Property Index
Name
Value
Initial
Applies to
Inh.
%ages
Anim­ation type
Canonical order
Com­puted value
image-resolution
[ from-image || ] && snap?
1dppx
all elements
yes
n/a
discrete
per grammar
specified keyword(s) and/or (possibly adjusted for snap, see below)
object-fit
fill | none | [contain | cover] || scale-down
fill
replaced elements
no
n/a
discrete
per grammar
specified keyword(s)
IDL Index
partial
namespace
CSS
SameObject
readonly
attribute
any
elementSources
};
Issues Index
This solution assumes that resolution is a proxy for filesize,
and therefore doesn’t appropriately handle multi-resolution sets of vector images,
or mixing vector images with raster ones (e.g. for icons).
For example, use a vector for high-res,
pixel-optimized bitmap for low-res,
and same vector again for low-bandwidth (because it’s much smaller, even though it’s higher resolution).
We should add "w" and "h" dimensions as a possibility
to match the functionality of HTML’s
picture
Per WG resolution,
define a notion of "equality" for images,
and combine "same" images at computed-value time,
summing their percentages.
Per WG resolution,
simplify directly-nested
cross-fade()
at computed-value time
by just distributing the percentage and flattening;
cross-fade(A 10%, cross-fade(B 30%, C 70%) 90%)
becomes
cross-fade(A 10%, B 27%, C 63%)
Do we need to be able to refer to elements in external documents
(such as SVG paint servers)?
Or is it enough to just use url() for this?
This name conflicts with a somewhat similar function in GCPM.
This needs to be resolved somehow.
Want the ability to do "reflections" of an element,
either as a background-image on the element or in a pseudo-element.
This needs to be specially-handled to avoid triggering the cycle-detection.
When we have overflow:paged,
how can we address a single page in the view?
Requiring some degree of stacking context on the element appears to be required for an efficient implementation.
Do we need a full stacking context, or just a pseudo-stacking context?
Should it need to be a stacking context normally,
or can we just render it as a stacking context when rendering it to element()?
This reuse of the ID selector matches Moz behavior.
I’m trying to avoid slapping a

right in the beginning of the grammar,
as that eats too much syntax-space.
Another possibility, though, is to start the value with a language-defined keyword
followed by

like
element(external fancy)
or something.
Naming suggestions welcome.
Usually in conic gradients the sharp transition at 0deg is undesirable, which is typically avoided by making sure the first and last color stops are the same color. Perhaps it would be useful to have a keyword for automatically achieving this.
Would a radius (inner & outer) for clipping the gradient be useful? If so, we could also support lengths in color stop positions, since we now have a specific radius.
Are elliptical conic gradients useful? Do graphics libraries support them?
The
image-set()
notation can alter the
natural resolution
of an image,
which ideally would be automatically honored without having to set this property.
How should we best address this?
Change the initial value to
auto
, meaning "1dppx, unless CSS says otherwise"?
Say that image-resolution has no effect on images whose resolution was set by something else in CSS?
Or somehow wordsmithing
image-set()
in some way such that it always produces
1dppx
images somehow?
Special-case interpolating to/from no image,
like "background-image: url(foo);" to "background-image: none;".
This section needs review and improvement.
In particular, I believe the handling of linear-gradient() is incomplete -
I think we want to specifically interpolate the "length" of the gradient line
(the distance between 0% and 100%)
between the starting and ending positions explicitly,
so it doesn’t grow and then shrink over a single animation.
MDN
element()
In no current engines.
Firefox
None
Safari
None
Chrome
None
Opera
Edge
None
Edge (Legacy)
IE
None
Firefox for Android
iOS Safari
Chrome for Android
Android WebView
Samsung Internet
Opera Mobile
element
In no current engines.
Firefox
Safari
None
Chrome
None
Opera
Edge
None
Edge (Legacy)
IE
None
Firefox for Android
iOS Safari
Chrome for Android
Android WebView
Samsung Internet
Opera Mobile
MDN
gradient
In all current engines.
Firefox
3.6+
Safari
4+
Chrome
1+
Opera
11+
Edge
79+
Edge (Legacy)
12+
IE
10+
Firefox for Android
iOS Safari
Chrome for Android
Android WebView
37+
Samsung Internet
Opera Mobile
gradient
In only one current engine.
Firefox
None
Safari
None
Chrome
26+
Opera
Edge
79+
Edge (Legacy)
12+
IE
None
Firefox for Android
iOS Safari
Chrome for Android
Android WebView
Samsung Internet
Opera Mobile
gradient
In all current engines.
Firefox
3.6+
Safari
7+
Chrome
26+
Opera
12.1+
Edge
79+
Edge (Legacy)
12+
IE
None
Firefox for Android
iOS Safari
Chrome for Android
Android WebView
37+
Samsung Internet
Opera Mobile
12.1+
MDN
image-set()
In all current engines.
Firefox
88+
Safari
14+
Chrome
113+
Opera
Edge
113+
Edge (Legacy)
IE
None
Firefox for Android
iOS Safari
Chrome for Android
Android WebView
Samsung Internet
Opera Mobile
image/image-set
In only one current engine.
Firefox
None
Safari
None
Chrome
113+
Opera
Edge
113+
Edge (Legacy)
IE
None
Firefox for Android
iOS Safari
Chrome for Android
Android WebView
Samsung Internet
Opera Mobile
image/image-set
In all current engines.
Firefox
88+
Safari
14+
Chrome
113+
Opera
Edge
113+
Edge (Legacy)
IE
None
Firefox for Android
iOS Safari
Chrome for Android
Android WebView
Samsung Internet
Opera Mobile
MDN
cross-fade
In only one current engine.
Firefox
None
Safari
10+
Chrome
None
Opera
Edge
None
Edge (Legacy)
IE
None
Firefox for Android
iOS Safari
9.3+
Chrome for Android
Android WebView
Samsung Internet
Opera Mobile
MDN
gradient/conic-gradient
In all current engines.
Firefox
83+
Safari
12.1+
Chrome
69+
Opera
Edge
79+
Edge (Legacy)
IE
None
Firefox for Android
iOS Safari
Chrome for Android
Android WebView
Samsung Internet
Opera Mobile
MDN
gradient/linear-gradient
In all current engines.
Firefox
16+
Safari
7+
Chrome
26+
Opera
12.1+
Edge
79+
Edge (Legacy)
12+
IE
10+
Firefox for Android
iOS Safari
Chrome for Android
Android WebView
37+
Samsung Internet
Opera Mobile
12.1+
MDN
gradient/repeating-conic-gradient
In all current engines.
Firefox
83+
Safari
12.1+
Chrome
69+
Opera
Edge
79+
Edge (Legacy)
IE
None
Firefox for Android
iOS Safari
Chrome for Android
Android WebView
Samsung Internet
Opera Mobile
MDN
image/image
In no current engines.
Firefox
None
Safari
None
Chrome
None
Opera
Edge
None
Edge (Legacy)
IE
None
Firefox for Android
None
iOS Safari
Chrome for Android
Android WebView
Samsung Internet
Opera Mobile
CanIUse
Support:
Android Browser
None
Baidu Browser
None
Blackberry Browser
None
Chrome
None
Chrome for Android
None
Edge
None
Firefox
None
Firefox for Android
None
IE
None
IE Mobile
None
KaiOS Browser
None
Opera
None
Opera Mini
None
Opera Mobile
None
QQ Browser
None
Safari
10+
Safari on iOS
10.0+
Samsung Internet
None
UC Browser for Android
None
Source:
caniuse.com
as of 2026-04-22
CanIUse
Support:
Android Browser
None
Baidu Browser
None
Blackberry Browser
None
Chrome
None
Chrome for Android
None
Edge
None
Firefox
None
Firefox for Android
None
IE
None
IE Mobile
None
KaiOS Browser
None
Opera
None
Opera Mini
None
Opera Mobile
None
QQ Browser
None
Safari
None
Safari on iOS
None
Samsung Internet
None
UC Browser for Android
None
Source:
caniuse.com
as of 2026-04-22