1.
Introduction
This is a diff spec against
CSS Values and Units Level 4
1.1.
Module Interactions
This module extends
[CSS-VALUES-4]
which replaces and extends the data type definitions in
[CSS21]
sections
1.4.2.1
4.3
and
A.2
2.
Textual Data Types
See
CSS Values 4
§ 4 Textual Data Types
3.
Value Definition Syntax
See
CSS Values 4
§ 2 Value Definition Syntax
Additionally,
Boolean combinations of a conditional notation.
These are written using the
notation,
and represent recursive expressions of boolean logic
using keywords and parentheses,
applied to the grammar specified in brackets,
e.g.
to express
media queries
3.1.
Functional Notation Definitions
See
CSS Values 4
§ 2.6 Functional Notation Definitions
3.1.1.
Commas in Function Arguments
Functional notation
often uses commas
to separate parts of its internal grammar,
and occasionally other syntax
(such as
or
in
if()
).
However, some functions
(such as
mix()
allow values that, themselves,
could contain these argument-separating tokens.
These values
(currently
, and
are
free-form productions
To accommodate these sorts of grammars unambiguously,
the
free-form productions
can be optionally wrapped in curly braces {}.
These braces are syntactic, not part of the actual value,
and only serve to explicitly indicate the bounds of the production.
free-form production
can either
(after optional whitespace)
start with a
<{-token>
, or not:
If it does not start with a "{" token
The production does not match any top-level commas or {} blocks.
(The production stops parsing at that point,
so the comma or {} block is matched by the next grammar term instead;
probably the function’s own argument-separating comma.)
Individual usages of the production can define additional tokens
that are similarly restricted from matching at the top-level.
If it does start with a "{" token
The production matches just the {} block that the "{" token opens.
It represents the
contents
of that block,
ignoring the {} block wrapper itself.
Note:
General restrictions defined for a particular
free-form production
like
not matching
s,
apply regardless of whether it’s {}-wrapped or not.
For example, the grammar of the
random-item()
function is:
random-item
The
indicates comma-separated repetitions,
so randomly choosing between three keywords
would be written as normal for functions,
like:
font-family
random-item
--x
serif
sans-serif
monospace
);
However, sometimes the values you want to choose between
need to include commas.
When this is the case,
wrapping the values in {}
allows their commas to be distinguished
from the function’s argument-separating commas:
font-family
random-item
--x
Times
serif
},
Arial
sans-serif
},
Courier
monospace
});
This randomly chooses one of three font-family lists:
either
Times, serif
, or
Arial, sans-serif
, or
Courier, monospace
This is not all-or-nothing;
you can use {} around
some
arguments that need it,
while leaving others bare when they don’t need it.
You are also allowed to use {} around a value when it’s not strictly required.
For example:
font-family
random-item
--x
Times
serif
},
sans-serif
monospace
});
This represents choosing between three font-family lists:
either
Times, serif
, or
sans-serif
, or
monospace
However, this {}-wrapping is
only
allowed for some function arguments—those defined as
free-form productions
It’s not valid for any other productions;
if you use {} around other function arguments,
it’ll just fail to match the function’s grammar
and become invalid.
For example, the following is
invalid
background-image
linear-gradient
to left
red
},
magenta
);
Note:
Because {} wrappers are allowed even when not explicitly required,
they can be used defensively around values
when the author isn’t sure if they’ll end up containing commas or not,
due to
arbitrary substitution functions
like
var()
For example,
font-family: random-item(--x, {var(--list1)}, monospace)
will work correctly
regardless of whether the
--list1
custom property
contains a comma-separated list or not.
Functional notations
are serialized without {} wrappers whenever possible.
The following generic productions are
free-form productions
For legacy compat reasons,
the
defined for the fallback value of
var()
is a
non-strict free-form production
It ignores the rules restricting what it can contain
when it does not start with a "{" token:
it is allowed to contain commas and {} blocks.
It still follows the standard
free-form production
rules
when it
does
start with a "{" token, however:
the fallback is just the contents of the {} block,
and doesn’t include the {} wrapper itself.
Other contexts
may
define that they use
non-strict free-form productions
but it
should
be avoided unless necessary.
3.2.
Boolean Expression Multiplier
Several contexts
(such as
@media
@supports
if()
, ...)
specify conditions,
and allow combining those conditions with boolean logic (and/or/not/grouping).
Because they use the same non-trivial recursive syntax structure,
the special
production represents this pattern generically.
The
notation wraps another value type in the square brackets within it,
e.g.
and represents that value type alone as well as
boolean combinations
using the
not
and
, and
or
keywords
and grouping parenthesis.
It is formally equivalent to:
> = not
and
or
The
production represents a true, false, or unknown value.
Its value is resolved using 3-value Kleene logic,
with top-level unknown values
(those not directly nested inside the grammar of another
resolving to false unless otherwise specified;
see
Appendix B: Boolean Logic
for details.
For example, the
@container
rule allows a wide variety of tests:
including size queries, style queries, and scroll-state queries.
All of these are arbitrarily combinable with boolean logic.
Using
, the grammar for an
@container
query
could be written as:
style
scroll-state
The
branch of the logic allows for future compatibility—unless otherwise specified new expressions in an older UA
will be parsed and considered “unknown”,
rather than invalidating the production.
For consistency with that allowance,
the
term in a
should be defined to match
3.3.
Specifying CSS Syntax in CSS: the
type
Some features in CSS,
such as the
attr()
function
or
registered custom properties
allow you to specify how
another
value is meant to be parsed.
This is declared via the
production,
which resembles a limited form of the CSS
value definition syntax
used in specifications to define CSS features,
and which represents a
syntax definition
= '*'
'<' transform-list '>'
= '<'
'>'
= angle
color
custom-ident
image
integer
length
length-percentage
number
percentage
resolution
string
time
url
transform-function
= '|'
= [ '#'
'+' ]
consists of either
between <> (angle brackets),
which maps to one of the
supported syntax component names
or an
, which represents any
keyword
Additionally,
may contain a
multiplier
which indicates a
list
of values.
Note:
This means that
and
length
are two different types:
the former describes a
whereas the latter describes a
keyword
length
Multiple
s may be
combined
with a
causing the syntax components to be matched
against a value
in the specified order.
The above, when parsed as a
would accept
values,
values,
as well as the keyword
auto
The
represents the
universal syntax definition
The
production
is a convenience form equivalent to
Note that
may not
be followed by a
Whitespace
is not allowed
between the angle bracket
s (
and the
they enclose,
nor is
whitespace
allowed to precede a
Note:
The
whitespace
restrictions also apply to
is a
whose value successfully
parses
as a
and represents the same value as that
would.
Note:
mostly exists for historical purposes;
before
was defined,
the
@property
rule used a
for this purpose.
3.3.1.
Parsing as
The purpose of a
is usually to specify how to parse another value
(such as the value of a
registered custom property
or an attribute value in
attr()
).
However, the generic
parse something according to a CSS grammar
algorithm
returns an unspecified internal structure,
since parse results might be ambiguous
and need further massaging.
To avoid these issues and get a well-defined result,
use
parse with a
To
parse with a
given a
string
or
list
or
component values
values
value
syntax
and optionally an element
el
for context,
perform the following steps.
It returns either CSS values,
or the
guaranteed-invalid value
Parse a list of component values
from
values
and let
raw parse
be the result.
If
el
was given,
substitute arbitrary substitution functions
in
raw parse
and set
raw parse
to that result.
parse
values
according to
syntax
with a
value treated as
and let
parsed result
be the result.
If
syntax
used a
combinator,
let
parsed result
be the parse result from the first matching clause.
If
parsed result
is failure,
return the
guaranteed-invalid value
Assert:
parsed result
is now a well-defined list of one or more CSS values,
since each branch of a
defines an unambiguous parse result
(or the
syntax is unambiguous on its own).
Return
parsed result
Note:
This algorithm does not resolved the parsed values
into
computed values
the context in which the value is used will usually do that already,
but if not,
the invoking algorithm will need to handle that on its own.
4.
Extensions to Level 4 Value Types
See
CSS Values and Units Level 4
4.1.
Resource Locators: the
type
See
CSS Values 4
§ 4.5 Resource Locators: the
4.1.1.
Request URL Modifiers
s are
that affect the
’s resource
request
by applying associated
URL request modifier steps
See
CSS Values 4
§ 4.5.4 URL Processing Model
This specification defines the following
s:
cross-origin
anonymous
use-credentials
integrity
referrer-policy
no-referrer
no-referrer-when-downgrade
same-origin
origin
strict-origin
origin-when-cross-origin
strict-origin-when-cross-origin
unsafe-url
cross-origin
anonymous
use-credentials
The
URL request modifier steps
for this modifier given
request
req
are:
Set
req
’s
mode
to "cors".
If the given value is
use-credentials
set
req
’s
credentials mode
to "include".
Otherwise, set
req
’s
credentials mode
to "same-origin".
integrity
The
URL request modifier steps
for this modifier given
request
req
are to set
request
’s
integrity metadata
to the given
referrer-policy
no-referrer
no-referrer-when-downgrade
same-origin
origin
strict-origin
origin-when-cross-origin
strict-origin-when-cross-origin
unsafe-url
The
URL request modifier steps
for this modifier given
request
req
are to set
request
’s
referrer policy
to the
ReferrerPolicy
that matches the given value.
4.2.
2D Positioning: the
type
The
value specifies the position
of an
alignment subject
(e.g. a background image)
inside an
alignment container
(e.g. its
background positioning area
as a pair of offsets between the specified edges
(defaulting to the left and top).
Its syntax is:
left
center
right
top
bottom
x-start
x-end
y-start
y-end
block-start
block-end
inline-start
inline-end
left
center
right
x-start
x-end
&&
top
center
bottom
y-start
y-end
left
center
right
x-start
x-end
top
center
bottom
y-start
y-end
block-start
center
block-end
&&
inline-start
center
inline-end
start
center
end
left
right
x-start
x-end
&&
top
bottom
y-start
y-end
block-start
block-end
&&
inline-start
inline-end
start
end
If only one value is specified (
),
the second value is assumed to be
center
If two values are given (
),
as the first value represents
the horizontal position as the offset between
the left edges of the
alignment subject
and
alignment container
and a
as the second value represents
the vertical position as an offset between their top edges.
If both keywords are one of
start
or
end
the first one represents the
block axis
and the second the
inline axis
Note:
A pair of axis-specific keywords can be reordered,
while a combination of keyword and length or percentage cannot.
So
center left
or
inline-start block-end
is valid,
while
50% left
is not.
start
and
end
aren’t axis-specific,
so
start end
and
end start
represent two different positions.
If four values are given (
then each
represents an offset between
the edges specified by the preceding keyword.
For example,
background-position: bottom 10px right 20px
represents a
10px
vertical offset up from the bottom edge
and a
20px
horizontal offset leftward from the right edge.
Positive values represent an offset
inward
from the edge of the
alignment container
Negative values represent an offset
outward
from the edge of the
alignment container
The following declarations give the stated (horizontal, vertical)
offsets from the top left corner:
background-position
left
10
px
top
15
px
/* 10px, 15px */
background-position: left top
/* 0px, 0px */
background-position:
10
px
15
px
/* 10px, 15px */
background-position: left
15
px
/* 0px, 15px */
background-position:
10
px
top
/* 10px, 0px */
s can also be relative to other corners than the top left.
For example, the following puts the background image
10px from the bottom and 3em from the right:
background-position
right
em
bottom
10
px
The
computed value
of a
is
a pair of offsets (horizontal and vertical),
each given as a computed
value,
representing the distance between the left edges and top edges (respectively)
of the
alignment subject
and
alignment container
value specifies the size of the offset
between the specified edges of the
alignment subject
and
alignment container
For example, for
background-position: 2cm 1cm
the top left corner of the background image is placed
2cm to the right and 1cm below
the top left corner of the
background positioning area
for the horizontal offset is relative to
width of
alignment container
width of
alignment subject
).
for the vertical offset is relative to
height of
alignment container
height of
alignment subject
).
For example, with a value pair of
0% 0%
the upper left corner of the
alignment subject
is aligned with
the upper left corner of the
alignment container
A value pair of
100% 100%
places
the lower right corner of the
alignment subject
in the lower right corner of the
alignment container
With a value pair of
75% 50%
the point 75% across and 50% down the
alignment subject
is to be placed at the point 75% across and 50% down the
alignment container
Diagram of the meaning of
background-position: 75% 50%
top
right
bottom
left
Offsets the top/left/right/bottom edges (respectively)
of the
alignment subject
and
alignment container
by the specified amount (defaulting to
0%
in the corresponding axis.
y-start
y-end
x-start
x-end
Computes the same as the physical edge keyword
corresponding to the
start
end
side
in the
axis.
block-start
block-end
inline-start
inline-end
Computes the same as the physical edge keyword
corresponding to the
start
end
side
in the
block
inline
axis.
center
Computes to a
50%
offset in the corresponding axis.
Unless otherwise specified, the
flow-relative
keywords are resolved
according to the
writing mode
of the element on which the value is specified.
Note:
The
background-position
property also accepts a three-value syntax.
This has been disallowed generically because it creates parsing ambiguities
when combined with other length or percentage components in a property value.
Need to define how this syntax would expand to the longhands of
background-position
if e.g.
var()
is used for some (or all) of the components.
[Issue #9690]
When specified in a grammar alongside other keywords,
s, or
s,
is
greedily
parsed;
it consumes as many components as possible.
For example,
transform-origin
defines a 3D position
as (effectively)
A value such as
left 50px
will be parsed as a 2-value
with an omitted z-component;
on the other hand,
a value such as
top 50px
will be parsed as a single-value
followed by a
When serializing the
specified value
of a
If only one component is specified:
If two components are specified:
Keywords are serialized as keywords.
s are serialized as
s.
Components are serialized horizontal first, then vertical.
If four components are specified:
Keywords and offsets are both serialized.
Components are serialized horizontal first, then vertical;
alternatively
block-axis
first, then
inline-axis
Note:
values are never serialized as a single value,
even when a single value would produce the same behavior,
to avoid causing parsing ambiguities in some grammars
where a
is placed next to a
such as
transform-origin
The
computed value
of a
is serialized as a pair of
representing offsets from the left and top edges, in that order.
4.2.3.
Combination of
Interpolation
of
is defined as
the independent interpolation of each component (x, y)
normalized as an offset from the top left corner
as a
Addition
of
is likewise defined as
the independent
addition
each component (x, y)
normalized as an offset from the top left corner
as a
5.
Interpolation Progress Calculations: the
progress()
notation
The
progress()
functional notation
represents the proportional distance
of a given value (the
progress value
from one value (the
progress start value
to another value (the
progress end value
),
each represented as a
calculation
It is a
math function
and can be input into other calculations
such as a
math function
or a
mix notation
The syntax of
progress()
is defined as follows:
progress
()
progress
where the first, second, and third
values represent
the
progress value
progress start value
, and
progress end value
respectively.
The argument
calculations
can resolve to any
, or
but must have a
consistent type
or else the function is invalid.
Do we need a
percent-progress()
notation,
or do enough places auto-convert that it’s not necessary?
Should progress() functions clamp to 0-100%?
[Issue #11825]
Note:
The
progress()
function is essentially syntactic sugar
for a particular pattern of
calc()
notations.
6.
Weighted Average Notations: the *-mix() family
Several
mix notations
in CSS
allow representing the weighted average of a set of values.
These
functional notations
follow the syntactic pattern:
mix
()
mix
options
value
&&
where the
options
can provide type-specific mixing options,
and each
value
and optional
pair in the argument list
is a
mix item
representing
an input to the mix and its weight in the average.
The
mix notations
in CSS include:
6.1.
Normalizing Mix Percentages
If the sum of the mix percentages are greater than 100%,
they are scaled down;
if it is less, any remaining percentage is distributed to values whose
is omitted,
or else assigned to a “none” type value as defined by the specific
mix notation
To
normalize mix percentages
given
list
of
mix items
items
(a value and optional percentage, each between 0% and 100% if specified)
an optional
force normalization
flag
(defaulting to false),
returning a list of
mix items
with normalized percentages
and a “leftover” percentage:
Let
specified sum
be the sum of the percentages specified in
items
(clamped to 100%),
or 0% if the percentages are omitted for all items.
For each omitted percentage in
items
set it to
100
specified sum
number of omitted percentages
Let
total
be the sum of the percentages of all the items.
If
total
is greater than 100%,
or if
total
is greater than 0% and the
force normalization
flag is true,
multiply every percentage in
items
by
100
total
If
total
is less than 100%,
let
leftover
be
100
total
Otherwise, let
leftover
be 0%.
Return
items
and
leftover
Note:
At the end of this algorithm, every percentage is set,
and the sum of all percentages is either 0%
(if they were all specified as 0% to begin with)
or 100%.
The
leftover
value will be applied to the usage-specific “none” type value
mixed into the final result.
6.2.
Mix Resolution
The
used value
of a valid
mix notation
is
the weighted average of its arguments,
as specified by the specific notation.
The
computed value
is the
used value
if it is possible to calculate.
Otherwise,
it is the
mix notation
itself,
with its arguments computed individually.
6.3.
Weighted Average of Numeric and Dimensional Values: the
calc-mix()
notation
The
calc-mix()
mix notation
represents a weighted average of numeric or dimensional value.
Like
calc()
, it is a
math function
with the following syntactic form:
calc-mix
()
calc-mix
The
arguments can resolve
to any
, or
but must have a
consistent type
or else the function is invalid.
The result’s type will be the
consistent type
made consistent
with the type of the
values.
The
used value
of a valid
calc-mix()
is
the result of producing a weighted average of its
values,
with the weight of each item given by its corresponding
after
normalizing these mix percentages
(Any “leftover” mix percentage is applied to a consistently-typed zero value,
and thus effectively discarded.)
The
computed value
of a valid
calc-mix()
is
its
used value
if all of the
and
values in it
can be resolved,
and is a
calc-mix()
notation
with each of its
and
values computed individually
otherwise.
6.4.
Weighted Average of Transform Values: the
transform-mix()
notation
The
transform-mix()
mix notation
represents a weighted average of
with the following syntactic form:
transform-mix
()
transform-mix
&&
The
used value
of a valid
transform-mix()
is
the result of producing a weighted average of its
values,
with the weight of each item given by its corresponding
after
normalizing these mix percentages
Any “leftover” mix percentage is applied to an
identity transform
appended to the list.
The weighting can be calculated by
interpolating each
using its
weight as the interpolation progress
from the
identity transform
towards the
See
CSS Transforms 1
§ 9 Interpolation of Transforms
If every
weight can be fully resolved,
and the
s can be interpolated
without used-value-time information,
then the
computed value
is the
used value
it is otherwise the
transform-mix()
notation itself
with its arguments each computed according to their type.
transform-mix()
is, itself, a
7.
Interpolation Mapping Notations: the *-interpolate() family
Several
interpolation notations
in CSS
allow representing an interpolated value
corresponding to a certain amount of
interpolation progress
along a defined scale or mapping function
(the
interpolation map
).
The
functional notations
follow the syntactic pattern:
interpolate
()
interpolate
progress
&&
global-options
stop
between-options
stop
Where:
For example,
the following changes the background color of an element
depending on the width of the viewport:
background
color-interpolate
100
vw
in lch
200
px
: palegoldenrod
800
px
: palegreen
2000
px
: powderblue
);
In the following example,
the font size interpolates from a smaller size on small screens
to a larger size on large screens,
easing along the interpolation curve.
The author is storing the progress scale in a custom property
to be able to re-use it across multiple
font-size
declarations
throughout the document.
html
--font-scale
progress
100
vw
200
px
2000
px
ease-in-out
font-size
calc-interpolate
var
--font-scale
),
16
px
70
20
px
100
24
px
);
h1
font-size
calc-interpolate
var
--font-scale
),
1.2
rem
40
rem
100
rem
);
If anyone has better examples to punch in here let us know...
The
interpolation notations
in CSS include:
and finally the generic
interpolate()
notation,
which can represent the interpolation of any property’s values
(but only the property’s entire value, not individual components).
The
interpolate()
notation also has a variant that takes a set of keyframes.
It does this by referring to an
@keyframes
rule,
and pulling the corresponding property declaration out of that.
It would be nice to allow the other mix notations to take keyframe also,
but how would we represent a set of keyframes for a
component value
(rather than a full property value)?
Do we have enough use-cases to motivate adding
palette-interpolate()
palette-mix()
already handles transitions.
7.1.
Global Syntax of the *-interpolate() family
The generic syntax of the
interpolation notations
is as follows:
interpolate-function
()
interpolate-function
&&
by
&&
&&
||
These represent the
interpolation progress
and
interpolation map
as described below.
7.1.1.
Specifying the Interpolation Progress
The
value type represents
the
interpolation progress
in an
interpolation notation
Its syntax is:
'animation-timeline'
where:
Represents the
interpolation progress
as a percentage,
with
0%
computing to zero and
100%
computing to 1.
Represents the
interpolation progress
as a number directly.
Note:
This allows the use of the
progress()
notations
and other
math functions
that output a
Represents the
interpolation progress
as a dimension,
which is converted to a number as specified in
§ 7.2 Validation and Normalization
Note:
Using a
value as
requires at least some of the stops in the
interpolation map
to also use
positions of the same type.
See
§ 7.2 Validation and Normalization
<'animation-timeline'>
Represents the
interpolation progress
as the progress of the specified
animation timeline
The values
none
and
auto
are invalid.
[CSS-ANIMATIONS-2]
[WEB-ANIMATIONS-2]
Note:
Progress values below
0%
and above
100%
are unconventional, and potentially awkward, but valid.
For example, most
easing functions
, though they will accept any input,
are defined in consideration of progress defined between the [0,1] (i.e. [0%,100%]) range.
7.1.1.1.
Easing Interpolation Progress: the
by
argument
The
interpolation progress
given by
may be optionally modified
by the
specified after the
by
keyword.
It applies the specified
easing function
to the “timeline” of progress as a whole
by modifying the
interpolation progress
before it’s applied to the
interpolation map
analogous to
animation-timing-function
If omitted, defaults to
linear
7.1.2.
Defining the Interpolation Map
Similar to the
gradient functions
the
interpolation notations
define an
interpolation map
using a stop list,
associating
input positions
with
output values
Each
interpolation stop
represents, essentially,
a keyframe of the
interpolation map
values between
interpolation stops
are interpolated between these adjacent keyframes
in accordance with the
and
arguments applying between those keyframes.
The
interpolation map
values are defined as follows:
{1,2} :
Represents an
interpolation stop
associating the specified
input position
(s) with the specified
output values
As with the
gradient functions
if two
s are specified,
it is treated the same as two stops with the same
Note:
is not given a grammar here,
as the specific functions specify what their outputs are.
, however, is linked to
see
§ 7.2.1 Type Checking
When appearing in the first argument,
specifies the “default”
easing function
to be used between each stop.
When appearing between stops,
specifies the
easing function
to be used between the two surrounding stops,
overriding any default provided by a global
argument.
(It is analogous to
animation-timing-function
.)
If omitted, defaults to
linear
The
input progress value
to this
easing function
is the
segment interpolation progress
—how far the
interpolation progress
is
between the
input positions
of the nearest stops preceding and following it.
US