@@ -76,39 +76,36 @@ Functional Notation Definitions</h3>
76
76
See [[css-values-4#component-functions]] .
77
77
78
78
<h4 id=component-function-commas>
79
- Commas and Semicolons in Functions </h4>
79
+ Commas in Function Arguments </h4>
80
80
81
81
[=Functional notation=] often uses commas
82
82
to separate parts of its internal grammar.
83
83
However, some functions
84
84
(such as ''mix()'' )
85
85
allow values that, themselves,
86
86
can contain commas.
87
+ These values
88
+ (currently <<whole-value>> , <<declaration-value>> , and <<any-value>> )
89
+ are <dfn export>comma-containing productions</dfn> .
87
90
88
91
To accommodate these sorts of grammars unambiguously,
89
- commas in functional grammars are <em> implicitly upgradeable</em> to semicolons in Level 5;
90
- that is,
91
- commas in a [=functional notation=] 's grammar
92
- can instead be represented as <<semicolon-token>> s.
93
- This is all-or-nothing:
94
- either every comma in the [=functional notation=] must be written as a semicolon,
95
- or none of them must be.
96
-
97
- When a [=functional notation=] is parsed,
98
- initially commas (<css> ,</css> ) and comma-multipliers (<css> #</css> )
99
- in the grammar match only <<comma-token>> s in the value,
100
- and any [=comma-containing productions=] are not allowed to contain <<comma-token>> s
101
- (the productions must be interpreted as ending before the comma).
102
- If a <<semicolon-token>> is encountered while parsing the [=functional notation=] ,
103
- the contents must be <em> re-interpreted</em> ,
104
- with commas and comma-multipliers in the grammar matching only <<semicolon-token>> s in the value,
105
- and [=comma-containing productions=] being allowed to contain <<comma-token>> s.
106
-
107
- Commas contained in productions defined as <dfn>comma-containing productions</dfn>
108
- (such as <<any-value>> or <<whole-value>> )
109
- are not implicitly upgradeable.
110
- Even when a [=functional notation=] is being re-interpreted with semicolons,
111
- these productions end when a <<semicolon-token>> is encountered.
92
+ the [=comma-containing productions=] can be optionally wrapped in curly braces {}.
93
+ These braces are syntactic, not part of the actual value.
94
+ Specifically:
95
+
96
+ * A [=comma-containing production=] can either start with a "{" token, or not.
97
+ * If it does not start with a "{" token,
98
+ then it cannot contain commas or {} blocks,
99
+ in addition to whatever specific restrictions it defines for itself.
100
+ (The production stops parsing at that point,
101
+ so the comma or {} block is matched by the next grammar term instead;
102
+ probably the function's own argument-separating comma.)
103
+ * If it does start with a "{" token,
104
+ then the production matches just the {} block that the "{" token opens.
105
+ It represents the <em> contents</em> of that block,
106
+ and applies whatever specific restrictions it defines for itself
107
+ to those contents,
108
+ ignoring the {} block wrapper.
112
109
113
110
<div class="example">
114
111
For example, the grammar of the ''random-item()'' function is:
@@ -123,56 +120,80 @@ Commas and Semicolons in Functions</h4>
123
120
like:
124
121
125
122
<pre>
126
- list-style: random-item(--x, disc, circle, square);
127
- </pre>
128
-
129
- It is <em> allowed</em> , however,
130
- to "upgrade" the commas to semicolons,
131
- like:
132
-
133
- <pre>
134
- list-style: random-item(--x; disc; circle; square);
135
- </pre>
136
-
137
- Both of the above mean the exact same thing.
138
- However, mixing commas and semicolons does not work;
139
- the following can produce an invalid value after substitution:
140
-
141
- <pre>
142
- list-style: random-item(--x; disc, circle; square);
123
+ font-family: random-item(--x, serif, sans-serif, monospace);
143
124
</pre>
144
125
145
- because it represents choosing between two values
146
- (<css> disc, circle</css> and <css> square</css> )
147
- and <css> disc, circle</css> is not a valid 'list-style' value.
148
-
149
126
However, sometimes the values you want to choose between
150
127
need to include commas.
151
- For example, in 'font-family' :
128
+ When this is the case,
129
+ wrapping the values in {}
130
+ allows their commas to be distinguished
131
+ from the function's argument-separating commas:
152
132
153
133
<pre>
154
- font-family: random-item(--x; Times, serif; Arial, sans-serif; Courier, monospace);
134
+ font-family: random-item(--x, { Times, serif}, { Arial, sans-serif}, { Courier, monospace} );
155
135
</pre>
156
136
157
137
This randomly chooses one of three font-family lists:
158
138
either ''Times, serif'' , or ''Arial, sans-serif'' , or ''Courier, monospace'' .
159
- But if only single fonts were needed for each choice,
160
- commas <em> could</em> have been used to separate them:
139
+
140
+ This is not all-or-nothing;
141
+ you can use {} around <em> some</em> arguments that need it,
142
+ while leaving others bare when they don't need it.
143
+ You are also allowed to use {} around a value when it's not strictly required.
144
+ For example:
161
145
162
146
<pre>
163
- font-family: random-item(--x, serif, sans-serif, monospace);
147
+ font-family: random-item(--x, {Times, serif} , sans-serif, { monospace} );
164
148
</pre>
165
149
150
+ This represents choosing between three font-family lists:
151
+ either ''Times, serif'' , or ''sans-serif'' , or ''monospace'' .
152
+
153
+ However, this {}-wrapping is <em> only</em> allowed for some function arguments--
154
+ those defined as [=comma-containing productions=] .
155
+ It's not valid for any other productions;
156
+ if you use {} around other function arguments,
157
+ it'll just fail to match the function's grammar
158
+ and become invalid.
159
+ For example, the following is <strong> invalid</strong> :
160
+
161
+ <pre>
162
+ background-image: linear-gradient(to left, {red}, magenta);
163
+ </pre>
166
164
</div>
167
165
168
- [=Functional notations=] are serialized with commas (rather than semicolons) whenever possible.
166
+ Note: Because {} wrappers are allowed even when not explicitly required,
167
+ they can be used defensively around values
168
+ when the author isn't sure if they'll end up containing commas or not,
169
+ due to [=arbitrary-substitution functions=] like ''var()'' .
170
+ For example, ''font-family: random-item(--x, {var(--list1)}, monospace)''
171
+ will work correctly
172
+ regardless of whether the ''--list1'' custom property
173
+ contains a comma-separated list or not.
174
+
175
+ [=Functional notations=] are serialized without {} wrappers whenever possible.
169
176
170
177
The following generic productions are [=comma-containing productions=] :
171
178
172
179
* <<any-value>>
173
180
* <<whole-value>>
174
181
* <<declaration-value>>
175
182
183
+ For legacy compat reasons,
184
+ the <<declaration-value>> defined the fallback value for ''var()''
185
+ is a <dfn export>non-strict comma-containing production</dfn> .
186
+ It ignores the rules restricting what it can contain
187
+ when it does not start with a "{" token:
188
+ it is allowed to contain commas and {} blocks.
189
+ It still follows the standard [=comma-containing production=] rules
190
+ when it <em> does</em> start with a "{" token, however:
191
+ the fallback is just the contents of the {} block,
192
+ and doesn't include the {} wrapper itself.
193
+
194
+ Other contexts <em> may</em> define that they use [=non-strict comma-containing productions=] ,
195
+ but it <em> should</em> be avoided unless necessary.
196
+
176
197
<h2 id="level-4-extensions">
177
198
Extensions to Level 4 Value Types</h3>
178
199
0 commit comments