forked from w3c/css-houdini-drafts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathOverview.bs
370 lines (294 loc) · 14.5 KB
/
Overview.bs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
<pre class='metadata'>
Title: CSS Properties and Values API Level 1
Status: ED
Group: houdini
ED: https://drafts.css-houdini.org/css-properties-values-api-1/
Previous Version: http://www.w3.org/TR/2016/WD-css-properties-values-api-1-20160607/
Shortname: css-properties-values-api
Level: 1
Abstract: This CSS module defines an API for registering new CSS properties. Properties registered using this API are provided with a parse syntax that defines a type, inheritance behaviour, and an initial value.
Editor: Tab Atkins, jackalmage@gmail.com
Editor: Shane Stephens, shanestephens@google.com
Editor: Daniel Glazman, daniel.glazman@disruptive-innovations.com
Editor: Alan Stearns, stearns@adobe.com
Editor: Elliot Sprehn, esprehn@chromium.org
Editor: Greg Whitworth, gwhit@microsoft.com
Ignored Terms: boolean, Animatable, Map, Context, isolated worker, SyntaxError,
Ignored Terms: InvalidModificationError, NotFoundError, StylePropertyMapReadOnly,
Ignored Terms: worklet global scope
Ignored Terms: throw, NotSupportedError, isconstructor, get, iscallable,
Ignored Terms: construct, name map of inputs
Ignored Vars: arguments, methodPropertyKey, inputStyleMap, workletGlobalScope
Ignored Terms: WorkletGlobalContext
Repository: w3c/css-houdini-drafts
</pre>
<pre class='biblio'>
{
"css-paint-api": {
"title": "CSS Painting API"
},
"css-layout-api": {
"title": "CSS Layout API"
}
}
</pre>
<pre class='link-defaults'>
spec:css-transforms-1; type:type; text:<transform-function>
spec:cssom-1; type:interface; text:CSS
</pre>
Introduction {#intro}
=====================
CSS defines a comprehensive set of properties that can be manipulated in order
to modify the layout, paint, or behaviour of a web document. However, web authors
frequently wish to extend this set with additional properties.
[[css-variables]] provides primitive means for defining user-controlled properties,
however these properties always take token lists as values, must always inherit, and
can only impact document layout or paint by being re-incorporated into the value
of other properties via a var() reference.
This specification extends [[css-variables]], allowing the registration of properties
that have a value type, an initial value, and a defined inheritance behaviour.
This specification is complementary to [[css-paint-api]] and [[css-layout-api]], which
allow custom properties to directly impact paint and layout behaviours respectively.
Registering custom properties {#registering-custom-properties}
==============================================================
<pre class='idl'>
dictionary PropertyDescriptor {
required DOMString name;
DOMString syntax = "*";
boolean inherits = false;
DOMString initialValue;
};
partial interface CSS {
static void registerProperty(PropertyDescriptor descriptor);
static void unregisterProperty(DOMString name);
};
</pre>
The {{PropertyDescriptor}} dictionary {#the-propertydescriptor-dictionary}
--------------------------------------------------------------------------
A <dfn>PropertyDescriptor</dfn> dictionary represents author-specified configuration
options for a custom property. {{PropertyDescriptor}} dictionaries contain the
following members:
: <dfn dict-member for=PropertyDescriptor>name</dfn>
:: The name of the custom property being defined.
: <dfn dict-member for=PropertyDescriptor>syntax</dfn>
:: A string representing how this custom property is parsed.
: <dfn dict-member for=PropertyDescriptor>inherits</dfn>
:: True if this custom property should inherit down the DOM tree; False otherwise.
: <dfn dict-member for=PropertyDescriptor>initialValue</dfn>
:: The initial value of this custom property.
The {{registerProperty()}} function {#the-registerproperty-function}
--------------------------------------------------------------------
The <dfn method for=CSS>registerProperty(PropertyDescriptor descriptor)</dfn> method
registers a custom property according the to configuration options provided in
<code>descriptor</code>.
Attempting to register properties with a {{PropertyDescriptor/name}} that doesn't
correspond to the <<custom-property-name>> production must cause {{registerProperty()}}
to throw a {{SyntaxError}}.
The list of types supported in the {{PropertyDescriptor/syntax}} member are listed
in <a section href="#supported-syntax-strings"></a>. Currently, only simple
type references are supported. Attempting to register properties with a
{{PropertyDescriptor/syntax}} that is not supported must cause {{registerProperty()}}
to throw a {{SyntaxError}}.
Note: for example, the syntax string could be "<length>" or "<number>".
Note: in future levels we anticipate supporting more sophisticated parse strings, e.g.
"<length> || <number>"
Attempting to call {{registerProperty()}} with an {{PropertyDescriptor/initialValue}} that is
not parseable using the provided {{PropertyDescriptor/syntax}} must cause it to
throw a {{SyntaxError}}. If no {{PropertyDescriptor/initialValue}} is provided and the
{{PropertyDescriptor/syntax}} is '*', then a special initial value is used. This initial
value must be considered parseable by {{registerProperty()}} but invalid at computed
value time. Initial values that are not computationally idempotent must also cause
{{registerProperty()}} to throw a {{SyntaxError}}.
<div class='example'>
For example, "3cm" is a computationally idempotent length, and hence valid as an initial value.
However, "3em" is not (depending on the environment, 3em could compute to
multiple different values). Additionally, "var(--foo)" is not computationally idempotent.
</div>
Issue: define computational idempotency.
Issue(121): Is computational idempotency the right thing to do here? We could also just
resolve any relative values once (against all the other initial values) and use
that. OR! We could allow specified values and just fix our engines...
When a custom property is registered with a given type, the process via which specified
values for that property are turned into computed values is defined
fully by the type selected, as described in
<a section href="#calculation-of-computed-values"></a>.
If {{registerProperty()}} is called with a descriptor name that matches an already registered property,
then an {{InvalidModificationError}} is thrown and the re-registration fails.
Properties can be unregistered using
<dfn method for=CSS>unregisterProperty(DOMString name)</dfn>.
If this function is called with a name that doesn't match an existing property
then a {{NotFoundError}} is thrown.
Successful calls to both {{registerProperty()}} and {{unregisterProperty()}}
change the set of registered properties. When the set of registered properties
changes, previously syntactically invalid property values can become valid and vice versa.
This can change the set of <a>declared values</a> which requires the <a>cascade</a> to
be recomputed.
<div class='example'>
By default, all custom property declarations that can be parsed as a sequence of tokens
are valid. Hence, the result of this stylesheet:
<pre class='lang-css'>
.thing {
--my-color: green;
--my-color: url("not-a-color");
color: var(--my-color);
}
</pre>
is to set the color property of elements of class "thing" to "inherit".
The second --my-color declaration overrides the first at parse time (both are valid),
and the var reference in the color property is found to be invalid at computation time
(because <code>url("not-a-color")</code> is not a color). At computation time the only
available fallback is the default value, which in the case of color is "inherit".
if we call:
<pre class='lang-javascript'>
registerProperty({
name: "--my-color",
syntax: "<color>"
});
</pre>
then the second --my-color declaration becomes syntactically invalid, which means that
the cascade uses the first declaration. The color therefore switches to green.
</div>
Supported syntax strings {#supported-syntax-strings}
----------------------------------------------------
The following syntax strings are supported:
: "<length>"
:: Any valid <<length>> value
: "<number>"
:: <<number>> values
: "<percentage>"
:: Any valid <<percentage>> value
: "<length-percentage>"
:: Any valid <<length>> or <<percentage>> value, any valid <<calc()>>
expression combining <<length>> and <<percentage>> components.
: "<color>"
:: Any valid <<color>> value
: "<image>"
:: Any valid <<image>> value
: "<url>"
:: Any valid <<url>> value
: "<integer>"
:: Any valid <<integer>> value
: "<angle>"
:: Any valid <<angle>> value
: "<time>"
:: Any valid <<time>> value
: "<resolution>"
:: Any valid <<resolution>> value
: "<transform-function>"
:: Any valid <<transform-function>> value
: "<custom-ident>"
:: Any valid <<custom-ident>> value
: Any string, the contents of which matches the <<ident>> production
:: That identifier
: Any one of the preceding strings, followed by '+'
:: A list of values of the type specified by the string
: Any combination of the preceding, separated by '|'
:: Any value that matches one of the items in the combination, matched in specified order.
: "*"
:: Any valid token stream
Note: [[css3-values]] maintains a distinction between properties that accept
only a length, and properties that accept both a length and a percentage,
however the distinction doesn't currently cleanly line up with the productions.
Accordingly, this specification introduces the length-percentage production
for the purpose of cleanly specifying this distinction.
Regardless of the syntax specified, all custom properties will accept
<a>CSS-wide keywords</a> as well as ''revert'', and process these values
appropriately.
Note: This does not apply to the {{PropertyDescriptor/initialValue}} member
of the {{PropertyDescriptor}} dictionary.
<div class='example'>
For example, the following are all valid syntax strings.
: <code>"<length>"</code>
:: accepts length values
: <code>"<length> | <percentage>"</code>
:: accepts lengths, percentages, percentage calc expressions, and length calc
expressions, but not calc expressions containing a combination of length
and percentage values.
: <code>"<length-percentage>"</code>
:: accepts all values that <code>"<length> | <percentage>"</code> would
accept, as well as calc expressions containing a combination of both length
and percentage values.
: <code>"big | bigger | BIGGER"</code>
:: accepts the ident "big", or the ident "bigger", or the ident "BIGGER".
: <code>"<length>+"</code>
:: accepts a list of length values.
</div>
Calculation of Computed Values {#calculation-of-computed-values}
----------------------------------------------------------------
The syntax of a custom property fully determines how computed values are
generated from specified values for that property.
The <a>CSS-wide keywords</a> and ''revert'' generate computed values as
described in [[!css3-values]] and [[!css-cascade-4]] respectively. Otherwise:
For <length> values, the computed value is the absolute length expressed in pixels.
For <length-percentage> values, the computed value is one of the following:
* if the specified value contains only length units, the computed value is the absolute length
expressed in pixels.
* if the specified value contains only percentages, the computed value is a
simple percentage.
* otherwise, the computed value is a calc expression containing an absolute
length expressed in pixels, and a percentage value.
For <custom-ident>, ident, <color>, <image>, <url>, <integer>,
<angle>, <time>, <resolution>, <transform-function> or "*" values, the
computed value is identical to the specified value.
For <number> and <percentage> values which are not calc expressions, the
computed value is identical to the specified value. Calc expressions that are
<number> and <percentage> values get reduced during computation to simple
numbers and percentages respectively.
For values specified by a syntax string that include "|" clauses, the computed
value is given by applying the calculation rules for the first clause that
matches to the specified value.
For list values, the computed value is a list of the computed values of the
primitives in the list.
Behavior of Custom Properties {#behavior-of-custom-properties}
==============================================================
Animation Behavior of Custom Properties {#animation-behavior-of-custom-properties}
----------------------------------------------------------------------------------
Note: As defined by [[css3-animations]] and [[css3-transitions]], it is possible to
specify animations and transitions that reference custom properties.
When referenced by animations and transitions, custom properties interpolate
in a manner defined by their types.
If the start and end of an interpolation have matching types, then they
will interpolate as specified in [[!css3-animations]].
Otherwise, the interpolation falls back to the default 50% flip described in
[[!css3-animations]].
Issue: Intermediate interpolated results of animations on custom properties must
be able to generate a token stream representing their value. We should ensure that
this is standard across implementations to avoid interop issues.
Conditional Rules {#conditional-rules}
--------------------------------------
''@supports'' rules and the {{CSS/supports(conditionText)}} method behave as specified
in [[!css-variables]].
Note: In other words, for the purpose of determining whether a value is
supported by a given custom property, the type registered for the custom property is
ignored and any value consisting of at least one token is considered valid.
Issue(118): should @supports pay attention to type when considering custom properties?
Examples {#examples}
====================
Example 1: Using custom properties to add animation behavior {#example-1}
-------------------------------------------------------------------------
<pre class='lang-markup'>
<script>
CSS.registerProperty({
name: "--stop-color",
syntax: "<color>",
inherits: false,
initialValue: "rgba(0,0,0,0)"
});
</script>
<style>
.button {
--stop-color: red;
background: linear-gradient(var(--stop-color), black);
transition: --stop-color 1s;
}
.button:hover {
--stop-color: green;
}
</style>
</pre>
Security Considerations {#security-considerations}
==================================================
There are no known security issues introduced by these features.
Privacy Considerations {#privacy-considerations}
==================================================
There are no known privacy issues introduced by these features.