Title: CSS Values and Units Module Level 5
Group: CSSWG
Shortname: css-values
Level: 5
Status: ED
Work Status: Exploring
ED: https://drafts.csswg.org/css-values-5/
TR: https://www.w3.org/TR/css-values-5/
Editor: Tab Atkins, Google, http://xanthir.com/contact/, w3cid 42199
Editor: Elika J. Etemad / fantasai, Apple, http://fantasai.inkedblade.net/contact, w3cid 35400
Editor: Miriam E. Suzanne, Invited Expert, http://miriamsuzanne.com/contact, w3cid 117151
Abstract: This CSS module describes the common values and units that CSS properties accept and the syntax used for describing them in CSS property definitions.
Ignored Terms: , containing block, property, 
Ignored Vars: Cn+1, n
Inline Github Issues: no
Default Highlight: css
Status Text: This spec is in the early exploration phase. Feedback is welcome, and and major breaking changes are expected.
Include MDN Panels: yes

Introduction

ISSUE: This is a diff spec against CSS Values and Units Level 4.

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.

Textual Data Types

See [[css-values-4#textual-values]].

Value Definition Syntax

See [[css-values-4#value-defs]]. Additionally,
  1. 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=].

Functional Notation Definitions

See [[css-values-4#component-functions]].

Commas in Function Arguments

[=Functional notation=] often uses commas to separate parts of its internal grammar. However, some functions (such as ''mix()'') allow values that, themselves, can contain commas. These values (currently <>, <>, and <>) are comma-containing productions. To accommodate these sorts of grammars unambiguously, the [=comma-containing productions=] can be optionally wrapped in curly braces {}. These braces are syntactic, not part of the actual value. Specifically: * A [=comma-containing production=] can either start with a "{" token, or not. * If it does not start with a "{" token, then it cannot contain commas or {} blocks, in addition to whatever specific restrictions it defines for itself. (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.) * If it does start with a "{" token, then the production matches just the {} block that the "{" token opens. It represents the contents of that block, and applies whatever specific restrictions it defines for itself to those contents, ignoring the {} block wrapper.
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 [=comma-containing 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 [=comma-containing productions=]: * <> * <> * <> For legacy compat reasons, the <> defined the fallback value for ''var()'' is a non-strict comma-containing 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 [=comma-containing 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 comma-containing productions=], but it should be avoided unless necessary.

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. <boolean[ <test> ]>, 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: <boolean-expr[ <test> ]> = not <boolean-expr-group> | <boolean-expr-group> [ [ and <boolean-expr-group> ]* | [ or <boolean-expr-group> ]* ] <boolean-expr-group> = <test> | ( <boolean-expr[ <test> ]> ) | <general-enclosed> 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 [[#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: <container-query> = <boolean-expr[ <cq-test> ]> <cq-test> = (<size-query>) | style( <style-query> ) | scroll-state( <scroll-state-query> ) <size-query> = <boolean-expr[ ( <size-feature> ) ]> | <size-feature> <style-query> = <boolean-expr[ ( <style-feature> ) ]> | <style-feature> <scroll-state-query> = <boolean-expr[ ( <scroll-state-feature> ) ]> | <scroll-state-feature>
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 <test> term in a <> should be defined to match <>.

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
	<> = '|'
	<> = [ '#' | '+' ]

	<> = <>
A <> consists of either a <> between <> (angle brackets), which maps to one of the [=supported syntax component names=], or an <>, which represents any [=keyword=]. Additionally, a <> may contain a [[css-properties-values-api-1#multipliers|multiplier]], which indicates a [=list=] of values. Note: This means that <length> and length are two different types: the former describes a <>, whereas the latter describes a [=keyword=] length. Multiple <>s may be [[css-properties-values-api-1#combinator|combined]] with a | <>, causing the syntax components to be matched against a value in the specified order.
<percentage> | <number> | auto The above, when parsed as a <>, would accept <> values, <> values, as well as the keyword auto.
red | <color> The [=syntax definition=] resulting from the above <>, when used as a grammar for [=parse|parsing=], would match an input red as an [=identifier=], but would match an input blue as a <>.
The * <> represents the [=universal syntax definition=]. The <transform-list> production is a convenience form equivalent to <transform-function>+. Note that <transform-list> 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 <transform-list>. A <> is a <> whose value successfully [=CSS/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.

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 [=CSS/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 [=CSS/component values=] |values|, a <> value |syntax|, and optionally an element |el| for context, perform the following steps. It returns either CSS values, or the [=guaranteed-invalid value=]. 1. [=Parse a list of component values=] from |values|, and let |raw parse| be the result. 2. If |el| was given, [=substitute arbitrary substitution functions=] in |raw parse|, and set |raw parse| to that result. 3. [=CSS/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. 4. If |parsed result| is failure, return the [=guaranteed-invalid value=]. 5. 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). 6. 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.

Extensions to Level 4 Value Types

See CSS Values and Units Level 4.

Resource Locators: the <> type

See [[css-values-4#urls]].

Request URL Modifiers

<>s are <>s that affect the <>’s resource [=/request=] by applying associated [=URL request modifier steps=]. See [[css-values-4#url-processing]]. This specification defines the following <>s:
		<> = <> | <> | <>
		<> = crossorigin(anonymous | use-credentials)
		<> = integrity(<>)
		<> = referrerpolicy(no-referrer | no-referrer-when-downgrade | same-origin | origin | strict-origin | origin-when-cross-origin | strict-origin-when-cross-origin | unsafe-url)
	
<> = crossorigin(anonymous | use-credentials)
The [=URL request modifier steps=] for this modifier given [=/request=] |req| are: 1. Set |req|'s [=request/mode=] to "cors". 2. If the given value is ''use-credentials'', set |req|'s [=request/credentials mode=] to "include". 3. Otherwise, set |req|'s [=request/credentials mode=] to "same-origin".
<> = integrity(<>)
The [=URL request modifier steps=] for this modifier given [=/request=] |req| are to set [=/request=]'s [=request/integrity metadata=] to the given <>.
<> = referrerpolicy(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 [=request/referrer policy=] to the {{ReferrerPolicy}} that matches the given value.
To apply request modifiers from URL value given a [=/request=] |req| and a <> |url|, call the [=URL request modifier steps=] for |url|'s <>s in sequence given |req|.

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 ]{2}
	]
	<> = [
	  [ [ left | right | x-start | x-end ] <> ] &&
	  [ [ top | bottom | y-start | y-end ] <> ]
	|
	  [ [ block-start | block-end ] <> ] &&
	  [ [ inline-start | inline-end ] <> ]
	|
	  [ [ start | end ] <> ]{2}
	]
	
If only one value is specified (<>), the second value is assumed to be ''center''. If two values are given (<>), a <> 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 10px top 15px;   /* 10px, 15px */
			background-position: left      top     ;   /*  0px,  0px */
			background-position:      10px     15px;   /* 10px, 15px */
			background-position: left          15px;   /*  0px, 15px */
			background-position:      10px 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 3em bottom 10px
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=].
<>
A <> 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=]. A <> for the horizontal offset is relative to (width of [=alignment container=] - width of [=alignment subject=]). A <> 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 image position within element
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 [=y-axis|y=]/[=x-axis|x=] 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 axis|block=]/[=inline axis|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. ISSUE(9690): 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.

Parsing <>

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 <>.

Serializing <>

When serializing the [=specified value=] of a <>:
If only one component is specified:
* The implied center keyword is added, and a 2-component value is serialized.
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 <>s representing offsets from the left and top edges, in that order.

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 <>. [=value addition|Addition=] of <> is likewise defined as the independent [=value addition|addition=] each component (x, y) normalized as an offset from the top left corner as a <>.

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 result of ''progress()'' is a <> [=made consistent=] with the [=consistent type=] of its arguments, resolved by calculating a progress function as follows: : If the [=progress start value=] and [=progress end value=] are different values :: ([=progress value=] - [=progress start value=]) / ([=progress end value=] - [=progress start value=]). : If the [=progress start value=] and [=progress end value=] are the same value :: 0, -∞, or +∞, depending on whether [=progress value=] is equal to, less than, or greater than the shared value.
The syntax of ''progress()'' is defined as follows:
		<> = 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. ISSUE: Do we need a ''percent-progress()'' notation, or do enough places auto-convert that it's not necessary? ISSUE(11825): Should progress() functions clamp to 0-100%? Note: The ''progress()'' function is essentially syntactic sugar for a particular pattern of ''calc()'' notations.

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: * ''calc-mix()'', for mixing <>, <>, <>, <