-
Notifications
You must be signed in to change notification settings - Fork 635
/
Overview.bs
1944 lines (1549 loc) · 71.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
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<pre class='metadata'>
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: <spacing-limit>, containing block, property
Ignored Vars: Cn+1, n
Inline Github Issues: no
Default Highlight: css
</pre>
<pre class='link-defaults'>
spec: css-values-4; type: dfn; text: determine the type of a calculation
spec: selectors-4; type: dfn; text: selector
</pre>
<style>
code, small { white-space: nowrap }
pre.value { font: inherit; white-space: pre-wrap; margin: 0; padding: 0; }
#propvalues td { text-align: right; }
#propvalues td + td { text-align: left; }
dt + dt::before { content: ", "; }
dl:not(.switch) dt { display: inline; }
td > small { display: block; }
</style>
<h2 id="intro">
Introduction</h2>
ISSUE: <strong>This is a diff spec against <a href="https://www.w3.org/TR/css-values-4/">CSS Values and Units Level 4</a>.</strong>
<h3 id="placement">
Module Interactions</h3>
This module extends [[CSS-VALUES-4]]
which replaces and extends the data type definitions in [[!CSS21]] sections
<a href="https://www.w3.org/TR/CSS21/about.html#value-defs">1.4.2.1</a>,
<a href="https://www.w3.org/TR/CSS21/syndata.html#values">4.3</a>,
and <a href="https://www.w3.org/TR/CSS21/aural.html#aural-intro">A.2</a>.
<h2 id="textual-values">
Textual Data Types</h2>
See [[css-values-4#textual-values]].
<!-- Big Text: syntax
███▌ █ ▐▌ █ █▌ █████▌ ███▌ █ █
█▌ █▌ ▐▌ █ █▌ █▌ █▌ ▐█ ▐█ █ █
█▌ █ ▐▌ ██▌ █▌ █▌ █▌ █▌ █ █
███▌ ▐▌█ █▌▐█ █▌ █▌ █▌ █▌ █
█▌ █▌ █▌ ██▌ █▌ █████▌ █ █
█▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █ █
███▌ █▌ █▌ ▐▌ █▌ █▌ █▌ █ █
-->
<h2 id=value-defs>
Value Definition Syntax</h2>
See [[css-values-4#value-defs]].
<h3 id=component-functions>
Functional Notation Definitions</h3>
See [[css-values-4#component-functions]].
<h4 id=component-function-commas>
Commas and Semicolons in Functions</h4>
[=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.
To accommodate these sorts of grammars unambiguously,
commas in functional grammars are <em>implicitly upgradeable</em> to semicolons in Level 5;
that is,
commas in a [=functional notation=]'s grammar
can instead be represented as <<semicolon-token>>s.
This is all-or-nothing:
either every comma in the [=functional notation=] must be written as a semicolon,
or none of them must be.
When the [=functional notation=]’s arguments are parsed,
initially commas in the grammar match only <<comma-token>>s;
if a <<semicolon-token>> is encountered,
then the [=functional notation=] is re-interpreted
with all commas in the grammar replaced by <<semicolon-token>>s.
Commas contained in productions defined as <dfn>comma-containing productions</dfn>
(such as <<any-value>> or <<whole-value>>)
are not implicitly upgradeable.
Even when a [=functional notation=] is being re-interpreted with semicolons,
these productions end when a <<semicolon-token>> is encountered.
<div class="example">
The following examples are both equivalent declarations:
<pre>
list-style: toggle(disc, circle, square);
list-style: toggle(disc; circle; square);
</pre>
however, this is different (and invalid):
<pre>
list-style: toggle(disc, circle; square);
</pre>
because it represents toggling between two values
(<css>disc, circle</css> and <css>square</css>)
and <css>disc, circle</css> is not a valid 'list-style' value.
This ability is important,
because sometimes [=functional notation=] arguments need to include commas.
For example, in 'font-family':
<pre>
font-family: random-item(Times, serif; Arial, sans-serif; Courier, monospace);
</pre>
This randomly chooses one of three font-family lists:
either ''Times, serif'', or ''Arial, sans-serif'', or ''Courier, monospace''.
But if only single fonts were needed for each choice,
commas <em>could</em> have been used to separate them:
<pre>
font-family: random-item(serif, sans-serif, monospace);
</pre>
</div>
[=Functional notations=] are serialized with commas (rather than semicolons) whenever possible.
The following generic productions are [=comma-containing productions=]:
* <<any-value>>
* <<whole-value>>
* <<declaration-value>>
Issue: The functions defined in this spec with semicolons in their grammar
need fixing to just use commas, now.
<!-- Big Text: url
█▌ █▌ ████▌ █▌
█▌ █▌ █▌ █▌ █▌
█▌ █▌ █▌ █▌ █▌
█▌ █▌ ████▌ █▌
█▌ █▌ █▌▐█ █▌
█▌ █▌ █▌ ▐█ █▌
███▌ █▌ █▌ █████
-->
<h3 id="urls">
Resource Locators: the <<url>> type</h3>
See [[css-values-4#urls]].
<h4 id='request-url-modifiers'>
Request URL Modifiers</h4>
<dfn><<request-url-modifier>></dfn>s are <<url-modifier>>s
that affect the <<url>>’s resource [=/request=]
by applying associated [=URL request modifier steps=].
See [[css-values-4#url-processing]].
This specification defines the following <<request-url-modifier>>s:
<pre class=prod>
<<request-url-modifier>> = <<crossorigin-modifier>> | <<integrity-modifier>> | <<referrerpolicy-modifier>>
<<crossorigin-modifier>> = crossorigin(anonymous | use-credentials)
<<integrity-modifier>> = integrity(<<string>>)
<<referrerpolicy-modifier>> = referrerpolicy(no-referrer | no-referrer-when-downgrade | same-origin | origin | strict-origin | origin-when-cross-origin | strict-origin-when-cross-origin | unsafe-url)
</pre>
<dl dfn-for="<request-url-modifier>">
<dt><dfn><<crossorigin-modifier>></dfn> = <dfn function lt="crossorigin()">crossorigin</dfn>(<dfn value>anonymous</dfn> | <dfn value>use-credentials</dfn>)
<dd>
The [=URL request modifier steps=] for this modifier given [=/request=] |req| are:
1. Set [=/request=]'s [=request/mode=] to "cors".
2. If the given value is ''use-credentials'',
set [=/request=]'s [=request/credentials mode=] to "include".
<dt><dfn><<integrity-modifier>></dfn> = <dfn function lt="integrity()">integrity</dfn>(<<string>>)
<dd>
The [=URL request modifier steps=] for this modifier given [=/request=] |req|
are to set [=/request=]'s [=request/integrity metadata=]
to the given <<string>>.
<dt><dfn><<referrerpolicy-modifier>></dfn> = <dfn function lt="referrerpolicy()">referrerpolicy</dfn>(<dfn value>no-referrer</dfn> | <dfn value>no-referrer-when-downgrade</dfn> | <dfn value>same-origin</dfn> | <dfn value>origin</dfn> | <dfn value>strict-origin</dfn> | <dfn value>origin-when-cross-origin</dfn> | <dfn value>strict-origin-when-cross-origin</dfn> | <dfn value>unsafe-url</dfn>)
<dd>
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.
</dl>
<div algorithm>
To <dfn export>apply request modifiers from URL value</dfn>
given a [=/request=] |req|
and a <<url>> |url|,
call the [=request modifier steps=] for |url|'s <<request-url-modifier>>s in sequence
given |req|.
</div>
<!-- Big Text: interp
████ █ █▌ █████▌ █████▌ ████▌ ████▌
▐▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌
▐▌ ██▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌
▐▌ █▌▐█ █▌ █▌ ████ ████▌ ████▌
▐▌ █▌ ██▌ █▌ █▌ █▌▐█ █▌
▐▌ █▌ █▌ █▌ █▌ █▌ ▐█ █▌
████ █▌ ▐▌ █▌ █████▌ █▌ █▌ █▌
-->
<h2 id="progress">
Interpolation Progress Functional Notations</h2>
ISSUE(6245): This section is an exploratory draft, and not yet approved by the CSSWG.
The ''progress()'', ''media-progress()'', and ''container-progress()'' [=functional notations=]
represent the proportional distance
of a given value (the <dfn noxexport>progress value</dfn>)
from one value (the <dfn noexport>progress start value</dfn>)
to another value (the <dfn noexport>progress end value</dfn>).
They allow drawing a progress ratio from
[=math functions=], [=media features=], and [=container features=],
respectively,
following a common syntactic pattern:
<pre class=prod>
<var>progress-function</var>() = <var>progress-function</var>( <var>progress value</var> from <var>start value</var> to <var>end value</var> )
</pre>
The resulting ratio can then be input into other calculations,
such as a [=math function=]
or a [=mix notation=].
<h3 id="progress-func">
Calculated Progress Values: the ''progress()'' notation</h3>
The <dfn>progress()</dfn> functional notation
returns a <<number>> value
representing the position of one [=calculation=]
(the [=progress value=])
between two other [=calculations=]
(the [=progress start value=]
and [=progress end value=]).
The argument [=calculations=] can resolve to any <<number>>, <<dimension>>, or <<percentage>>,
but must have a [=consistent type=]
or else the function is invalid.
The result will be a <<number>>,
[=made consistent=] with the [=consistent type=] of the arguments.
The syntax of ''progress()'' is defined as follows:
<pre class=prod>
<dfn id=typedef-progress-fn><<progress()>></dfn> = progress(<<calc-sum>> from <<calc-sum>> to <<calc-sum>>)
</pre>
where the first, second, and third <<calc-sum>> values represent
the [=progress value=], [=progress start value=], and [=progress end value=],
respectively.
The value returned by a valid ''progress()'' notation is
(<var>progress value</var> - <var>start value</var>) / (<var>end value</var> - <var>start value</var>),
as a <<number>>.
ISSUE: Do we need a ''percent-progress()'' notation,
or do enough places auto-convert that it's not necessary?
Note: The ''progress()'' function is essentially syntactic sugar
for a particular pattern of ''calc()'' notations.
<h3 id="media-progress-func">
Media Query Progress Values: the ''media-progress()'' notation</h3>
Similar to the ''progress()'' notation,
the <dfn>media-progress()</dfn> functional notation
returns a <<number>> value
representing current value of the specified [=media query=]
[[!MEDIAQUERIES-4]]
as a [=progress value=]
between two explicit values of the [=media query=]
(as the [=progress start value=] and [=progress end value=]).
The syntax of ''media-progress()'' is defined as follows:
<pre class=prod>
<dfn><<media-progress()>></dfn> = media-progress(<<media-feature>> from <<calc-sum>> to <<calc-sum>>)
</pre>
The value returned by a valid ''media-progress()'' notation is
<var>progress value</var> / (<var>end value</var> - <var>start value</var>,
as a <<number>>.
The specified [=media query=] must be a valid “range” type query,
and its specified [=progress start value=] and [=progress end value=]
must be valid values for the specified [=media query=],
or else the function is invalid.
The two input [=calculations=]
but must have a [=consistent type=]
or else the function is invalid.
The result will be a <<number>>,
[=made consistent=] with the [=consistent type=] of the arguments.
<h3 id="container-progress-func">
Container Query Progress Values: the ''container-progress()'' notation</h3>
The <dfn>container-progress()</dfn> functional notation
is identical to the ''media-progress()'' functional notation,
except that it accepts [=container features=] [[!CSS-CONTAIN-3]]
in place of [=media features=].
The syntax of ''container-progress()'' is defined as follows:
<pre class=prod>
<dfn><<container-progress()>></dfn> = container-progress(<<size-feature>> [ of <<container-name>> ]? from <<calc-sum>> to <<calc-sum>>)
</pre>
where the optional <<container-name>> component specifies
the named containers to consider when selecting a container
to resolve against.
The two input [=calculations=]
but must have a [=consistent type=]
or else the function is invalid.
The result will be a <<number>>,
[=made consistent=] with the [=consistent type=] of the arguments.
If no appropriate containers are found,
''container-progress()'' resolves its <<size-feature>> query
against the [=small viewport size=].
<!-- Big Text: *-mix()
█ █ ████ █ █ ██ ██
█ █ ██ ██ ▐▌ █ █ █▌ ▐█
█ █ █▌█ █▐█ ▐▌ █ █ █▌ ▐█
███████ ████▌ █▌ █ ▐█ ▐▌ █ █▌ ▐█
█ █ █▌ ▐█ ▐▌ █ █ █▌ ▐█
█ █ █▌ ▐█ ▐▌ █ █ █▌ ▐█
█▌ ▐█ ████ █ █ ██ ██
-->
<h2 id="mixing">
Mixing and Interpolation Notations: the *-mix() family</h2>
ISSUE(6245): This section is an exploratory draft, and not yet approved by the CSSWG.
Several <dfn>mix notations</dfn> in CSS
allow representing the interpolation of two values,
the <dfn>mix start value</dfn> and the <dfn>mix end value</dfn>,
at a given point in progress between them (the <dfn>mix progress value</dfn>).
These [=functional notations=] follow the syntactic pattern:
<pre class=prod>
<var>mix-function</var>() = <var>mix-function</var>( <<progress>>, [=mix start value|start-value=], [=mix end value|end-value=] )
</pre>
The [=mix notations=] in CSS include:
* ''calc-mix()'',
for interpolating <<length>>, <<percentage>>, <<time>>,
and other dimensions representable in ''calc()'' expressions
* ''color-mix()'',
for interpolating two <<color>> values
* ''cross-fade()'',
for interpolating <<image>> values
* ''palette-mix()'',
for interpolating two 'font-palette' values
and finally the generic ''mix()'' notation,
which can represent the interpolation of any property's values
(but only the property's entire value, not individual components).
Note: The ''cross-fade()'' notation
also has an alternative syntax
that allows for mixing more than two values,
but does not allow for the more complex expressions of <<progress>>.
ISSUE: The ''mix()'' 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)?
<h3 id="progress-type">
Representing Interpolation Progress: the <<progress>> type</h2>
The <dfn><<progress>></dfn> value type represents
the [=mix progress value=] in a [=mix notation=],
and ultimately resolves to a percentage.
It can, however, draw that percentage value
from sources such as media queries and animation timelines,
and can also convert it through an [=easing function=]
before using it for interpolation.
Its syntax is defined as follows:
<pre class=prod>
<<progress>> = [ <<percentage>> | <<number>> | <<'animation-timeline'>> ]? && by <<easing-function>>
</pre>
where:
<dl dfn-type=value dfn-for="<progress>">
<dt><dfn><<percentage-token>></dfn>
<dd>
Computes to the equivalent <<number>>:
''0%'' becomes ''0'',
''100%'' becomes ''1'',
etc.
Note: This only allows literal percentages,
like ''15%'';
calculations like ''calc(100% / 7)'' will not work,
as they will instead attempt to use the normal rules
for resolving a percentage against another type
(such as <<length>>, in 'width').
Use expressions like ''calc(1 / 7)'' instead.
<dt><dfn><<number>></dfn>
<dd>
Represents the [=mix progress value=].
Note: This allows the use of the ''progress()'',
''media-progress()'',
and ''container-progress()'' notations.
<dt><dfn><<'animation-timeline'>></dfn>
<dd>
Represents the [=mix progress value=]
as the progress of the specified [[web-animations-1#timelines|animation timeline]].
The values ''animation-timeline/none'' and ''animation-timeline/auto'', however,
are invalid.
[[!CSS-ANIMATIONS-2]] [[!WEB-ANIMATIONS-2]]
<dt><dfn><<easing-function>></dfn>
<dd>
Converts the specified input [=mix progress value=]
into an output [=mix progress value=]
using the specified [=easing function=].
[[!CSS-EASING-1]]
</dl>
Note: Progress values below ''0'' and above ''1'' are valid;
they allow representing interpolation beyond the range
defined by the start and end values.
Note: While <<progress>> itself can be a <<percentage>>,
mapping directly to the equivalent <<number>>,
a function that <em>resolves</em> to a <<number>>,
like ''progress()'',
resolves <<percentage>>s using the normal rules for the context;
for example, in 'width', they would be resolved against a length.
The [=computed value=] of a <<progress>> value specified with <<percentage>> or <<number>>
is the computed <<number>> converted through the <<easing-function>> (if any).
The [=computed value=] of a <<progress>> value specified with <<'animation-timeline'>>
is the computed <<'animation-timeline'>> and <<easing-function>> (if any).
<h3 id="calc-mix">
Interpolated Numeric and Dimensional Values: the ''calc-mix()'' notation</h3>
The <dfn>calc-mix()</dfn> [=mix notation=]
represents an interpolated numeric or dimensional value.
Like ''calc()'', it is a [=math function=],
with the following syntactic form:
<pre class=prod>
<dfn><<calc-mix()>></dfn> = calc-mix( <<progress>>, <<calc-sum>>, <<calc-sum>> )
</pre>
The <<calc-sum>> arguments can resolve
to any <<number>>, <<dimension>>, or <<percentage>>,
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 <<progress>> value.
The [=used value=] of a valid ''calc-mix()'' is
the result of interpolating these two values
to the progress given by <<progress>>.
If the <<progress>> value can be computed to a <<number>>,
then the [=computed value=] is likewise
the result of interpolating the two [=computed values=]
to that <<progress>> value
(in other words, ''A * (1-progress) + B * progress'')
it is otherwise the ''calc-mix()'' notation itself
with its arguments each computed according to their type.
<h3 id="color-mix">
Interpolated Color Values: the ''color-mix()'' notation</h3>
This specification extends the ''color-mix()'' [=functional notation=]
as a [=mix notation=] accepting the following syntaxes:
<pre class=prod>
<<color-mix()>> =
color-mix( <<progress>> && <<color-interpolation-method>>?, <<color>>, <<color>> ) |
color-mix( <<color-interpolation-method>>, [<<color>> && <<percentage [0,100]>>?]#{2} )
</pre>
The used value of the first [=mix notation=] variant
is equivalent to assigning the <<progress>> value,
as a <<percentage>>,
to the <<percentage>> of the second <<color>> argument in the second variant.
<span class=note>That is, ''color-mix(progress, color1, color2)'' is equivalent to ''color-mix(color1, color2 progress)''.</span>
See [[css-color-5#color-mix]] for the normative definition of the second variant.
ISSUE: <<progress>> allows returning percentages outside 0-100%,
but ''color-mix()'' doesn't allows such values,
so need to define how that gets processed.
<h3 id="cross-fade">
Interpolated Image Values: the ''cross-fade()'' notation</h3>
This specification extends the ''cross-fade()'' [=functional notation=]
as a [=mix notation=] accepting the following syntaxes:
<pre class=prod>
<<cross-fade()>> =
cross-fade( <<progress>>, [ <<image>> | <<color>> ], [ <<image>> | <<color>> ] ) |
cross-fade( <<cf-image>># )
</pre>
The used value of the first [=mix notation=] variant
is equivalent to assigning the <<progress>> value
as the <<percentage>> of the second <<color>> argument in the second variant.
<span class=note>That is, ''cross-fade(progress, image1, image2)'' is equivalent to ''cross-fade(image1, image2 progress)''.</span>
See [[css-images-4#cross-fade-function]] for the normative definition of the second variant.
<h3 id="transform-mix">
Interpolated Transform Values: the ''transform-mix()'' notation</h3>
The <dfn>transform-mix()</dfn> [=mix notation=]
represents an interpolated <<transform-list>>,
with the following syntactic form:
<pre class=prod>
<dfn><<transform-mix()>></dfn> = transform-mix( <<progress>>, <<transform-list>>, <<transform-list>> )
</pre>
The [=used value=] of a valid ''transform-mix()'' is
the result of interpolating these two values
to the progress given by <<progress>>.
If the <<progress>> value can be computed to a <<percentage>>,
and the <<transform-list>>s can be interpolated
without used-value-time information,
then the [=computed value=] is likewise
the result of interpolating the two [=computed values=]
to that <<progress>> value;
it is otherwise the ''transform-mix()'' notation itself
with its arguments each computed according to their type.
''transform-mix()'' is, itself, a <<transform-function>>.
<h3 id="mix">
Interpolated Property Values: the ''mix()'' notation</h3>
[=Interpolation=] of any two property values can be represented
by the <dfn>mix()</dfn> [=mix notation=],
which supports two alternative syntax patterns:
<pre class="prod">
<dfn><<mix()>></dfn> =
mix( <<progress>> ';' <<whole-value>> ';' <<whole-value>> ) |
mix( <<progress>> && of <<'animation-name'>> )
</pre>
The first syntax alternative, like other [=mix notations=],
interpolates between the first <<whole-value>> (its [=mix start value=])
and the second <<whole-value>> (its [=mix end value=]).
The second uses the [=mix progress value=]
to interpolate the corresponding property declarations from a set of keyframes,
allowing for more complex interpolation curves.
Note: This [=functional notation=] uses semicolons to separate arguments
rather than the more typical comma
because the values themselves can contain commas.
For the standard [=mix notation=] variant,
if the two <<whole-value>>s being interpolated by ''mix()''
are [=interpolation|interpolable=]
as values for the property in which it is specified,
and the interpolated value can be represented without ''mix()'',
the [=computed value=] of ''mix()'' is
the result of interpolating these two values
to the progress given by <<progress>>.
Otherwise,
the [=computed value=] of ''mix()'' is
the ''mix()'' [=functional notation=] itself
with its <<progress>> value computed
and its <<whole-value>>s (if provided)
computed as values for this property.
<div class="example">
For example, most uses of ''mix()''
will resolve at computed-value time:
<pre>
color: mix(90%; red; blue);
/* via simple interpolation,
computes to: */
color: rgb(10% 0 90%);
color: mix(90%; currentcolor; black);
/* can't be fully resolved at computed-value time,
but still has a defined representation: */
color: color-mix(currentcolor 90%, black 10%);
float: mix(90%; left; right);
/* discretely animatable */
float: right;
</pre>
But a few cases don't have an intermediate representation:
<pre>
transform: mix(90%; translate(calc(1em + 50%)); rotate(30deg));
/* because functions don't match, it will interpolate
via matrix(). But translate(%) needs layout
information to turn into a matrix(), so the
interpolated value can't actually be represented.
Computes to: */
transform: mix(90%; translate(calc(16px + 50%)); rotate(30deg));
transform: mix(90% of ripple);
</pre>
</div>
The ''mix()'' notation is a <<whole-value>>.
Additionally,
if any of its <<whole-value>> arguments are [=not animatable=],
the notation is invalid.
<div class="example">
For example, the following declarations are invalid,
and will be ignored:
<pre>
/* Invalid start value */
color: mix(90% ; #invalid ; #F00);
/* Function is mixed with other values */
background: url(ocean) mix(10% ; blue ; yellow);
/* 'animation-*' is not animatable */
animation-delay: mix(0% ; 0s ; 2s);
</pre>
</div>
<!-- Big Text: subs
███▌ █▌ █▌ ████▌ ███▌
█▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌
█▌ █▌ █▌ █▌ █▌ █▌
███▌ █▌ █▌ █████ ███▌
█▌ █▌ █▌ █▌ █▌ █▌
█▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌
███▌ ███▌ ████▌ ███▌
-->
<h2 id="value-insert">
Miscellaneous Value Substituting Functions</h2>
<h3 id="whole-value" type lt="<whole-value>">
Representing An Entire Property Value: the <<whole-value>> type</h3>
Several functions defined in this specification
can only be used as the "whole value" of a property.
For example, ''background-position: toggle(50px 50px, center);'' is valid,
but ''background-position: toggle(50px, center) 50px;'' is not.
The <<whole-value>> production represents these values.
All properties implicitly accept a <<whole-value>>
as their entire value,
just as they accept the [=CSS-wide keywords=]
as their entire value.
When used as a component value of a function,
<<whole-value>> also represents any CSS value
normally valid as the whole value
of the property in which it is used
(including additional <<whole-value>> functions).
However, some functions may restrict
what a <<whole-value>> argument can include.
<h3 id="first-valid">
Selecting the First Supported Value: the ''first-valid()'' notation</h3>
CSS supports progressive enhancement with its forward-compatible parsing:
authors can declare the same property multiple times in a style rule,
using different values each time,
and a CSS UA will automatically use the last one that it understands
and throw out the rest.
This principle, together with the ''@supports'' rule,
allows authors to write stylesheets that work well
in old and new UAs simultaneously.
However, using ''var()''
(or similar substitution functions that resolve after parsing)
thwarts this functionality;
CSS UAs must assume any such property is valid at parse-time.
The <dfn>first-valid()</dfn> [=functional notation=]
inlines the fallback behavior
intrinsic to parsing declarations.
Unlike most notations,
it can accept any valid or invalid syntax in its arguments,
and represents the first value among its arguments
that is supported (parsed as valid) by the UA
as the whole value of the property it's used in.
<pre class=prod>
<dfn><first-valid()></dfn> = first-valid( <<declaration-value>> [ ';' <<declaration-value>> ]* )
</pre>
If none of the arguments represent a valid value for the property,
the property is [=invalid at computed-value time=].
''first-valid()'' is a <<whole-value>>.
Issue: Should this have a different name?
We didn't quite decide on it during the resolution to add this.
<!-- Big Text: toggle()
█████▌ ███▌ ███▌ ███▌ █▌ █████▌ ██ ██
█▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ ▐█
█▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ ▐█
█▌ █▌ █▌ █▌ ██▌ █▌ ██▌ █▌ ████ █▌ ▐█
█▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ ▐█
█▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ █▌ ▐█
█▌ ███▌ ███▌ ███▌ █████ █████▌ ██ ██
-->
<h3 id="toggle-notation">
Toggling Between Values: ''toggle()''</h3>
The <dfn>toggle()</dfn> expression allows descendant elements
to cycle over a list of values instead of inheriting the same value.
<div class='example'>
The following example makes <code><em></code> elements italic in general,
but makes them normal if they're inside something that's italic:
<pre>em { font-style: toggle(italic; normal); }</pre>
</div>
<div class='example'>
The following example cycles markers for nested lists,
so that a top level list has ''list-style-type/disc''-shaped markers,
but nested lists use ''list-style-type/circle'', then ''list-style-type/square'', then ''list-style-type/box'',
and then repeat through the list of marker shapes,
starting again (for the 5th list deep) with ''list-style-type/disc''.
<pre>ul { list-style-type: toggle(disc; circle; square; box); }</pre>
</div>
The syntax of the ''toggle()'' expression is:
<pre class=prod>
<dfn><<toggle()>></dfn> = toggle( <<whole-value>> [ ';' <<whole-value>> ]+ )
</pre>
Note: This [=functional notation=] uses semicolons to separate arguments
rather than the more typical comma
because the values themselves can contain commas.
The ''toggle()'' notation is a <<whole-value>>.
However, it is not allowed to be nested,
nor may it contain ''attr()'' or ''calc()'' notations;
declarations containing such constructs are invalid.
<div class="example">
The following ''toggle()'' examples are all invalid:
<pre>
background-position: 10px toggle(50px, 100px);
/* toggle() must be the sole value of the property */
list-style-type: toggle(disc, 50px);
/* ''50px'' isn't a valid value of 'list-style-type' */
</pre>
</div>
To determine the computed value of ''toggle()'',
first evaluate each argument as if it were the sole value of the property in which ''toggle()'' is placed
to determine the computed value that each represents,
called <var>C<sub>n</sub></var> for the <var>n</var>-th argument to ''toggle()''.
Then, compare the property's <a>inherited value</a>
with each <var>C<sub>n</sub></var>.
For the earliest <var>C<sub>n</sub></var> that matches the <a>inherited value</a>,
the computed value of ''toggle()'' is <var>C<sub>n+1</sub></var>.
If the match was the last argument in the list,
or there was no match,
the computed value of ''toggle()'' is the computed value that the first argument represents.
Note: This means that repeating values in a ''toggle()'' short-circuits the list.
For example ''toggle(1em; 2em; 1em; 4em)'' will be equivalent to ''toggle(1em; 2em)''.
<!-- Issue: Should this short-circuiting affect the computed value? -->
Note: That ''toggle()'' explicitly looks at the computed value of the parent,
so it works even on non-inherited properties.
This is similar to the ''inherit'' keyword,
which works even on non-inherited properties.
Note: That the <a href="https://www.w3.org/TR/CSS21/cascade.html#computed-value">computed value</a> of a property is an abstract set of values,
not a particular serialization [[!CSS21]],
so comparison between computed values should always be unambiguous and have the expected result.
For example,
a Level 2 <l spec=css22>'background-position'</l> computed value
is just two offsets, each represented as an absolute length or a percentage,
so the declarations ''background-position: top center'' and ''background-position: 50% 0%''
produce identical computed values.
If the "Computed Value" line of a property definition seems to define something ambiguous or overly strict,
please <a href="#sotd">provide feedback</a> so we can fix it.
If ''toggle()'' is used on a <a>shorthand property</a>,
it sets each of its longhands to a ''toggle()'' value
with arguments corresponding to what the longhand would have received
had each of the original ''toggle()'' arguments been the sole value of the <a>shorthand</a>.
<div class="example">
For example, the following shorthand declaration:
<pre>margin: toggle(1px 2px, 4px, 1px 5px 4px);</pre>
is equivalent to the following longhand declarations:
<pre>
margin-top: toggle(1px; 4px; 1px);
margin-right: toggle(2px; 4px; 5px);
margin-bottom: toggle(1px; 4px; 4px);
margin-left: toggle(2px; 4px; 5px);
</pre>
Note that, since ''1px'' appears twice in the top margin and ''4px'' appears twice in bottom margin,
they will cycle between only two values
while the left and right margins cycle through three.
In other words, the declarations above will yield the same computed values
as the longhand declarations below:
<pre>
margin-top: toggle(1px; 4px);
margin-right: toggle(2px; 4px; 5px);
margin-bottom: toggle(1px; 4px);
margin-left: toggle(2px; 4px; 5px);
</pre>
which may not be what was intended.
</div>
<!-- Big Text: attr()
███▌ █████▌ █████▌ ████▌ ██ ██
▐█ ▐█ █▌ █▌ █▌ █▌ █▌ ▐█
█▌ █▌ █▌ █▌ █▌ █▌ █▌ ▐█
█▌ █▌ █▌ █▌ ████▌ █▌ ▐█
█████▌ █▌ █▌ █▌▐█ █▌ ▐█
█▌ █▌ █▌ █▌ █▌ ▐█ █▌ ▐█
█▌ █▌ █▌ █▌ █▌ █▌ ██ ██
-->
<h3 id="attr-notation">
Attribute References: the ''attr()'' function</h3>
<!--
Ian's proposal:
http://lists.w3.org/Archives/Member/w3c-css-wg/2002OctDec/0141.html
-->
The <dfn>attr()</dfn> function substitutes the value of an <l spec=dom>[=attribute=]</l> on an <l spec=dom>[=/element=]</l>
into a property,
similar to how the ''var()'' function
substitutes a [=custom property=] value into a function.
<pre class=prod>
attr() = attr( <<attr-name>> <<attr-type>>? , <<declaration-value>>?)
<dfn><attr-name></dfn> = [ <<ident-token>> '|' ]? <<ident-token>>
<dfn><attr-type></dfn> = string | url | ident | color | number | percentage |
length | angle | time | frequency | flex | <<dimension-unit>>
</pre>
<!-- Switch the <attr-name> to just use <q-name>
when Namespaces is rewritten
to use the current grammar structures. -->
The <dfn><dimension-unit></dfn> production matches a literal "%" character
(that is, a <<delim-token>> with a value of "%")
or an ident whose value is any of the CSS units
for <<length>>, <<angle>>, <<time>>, <<frequency>>, or <<flex>> values
(such as ''px'' or ''ms'').
The arguments of ''attr()'' are:
: <<attr-name>>
:: Gives the name of the attribute being referenced,
similar to <<wq-name>> (from [[SELECTORS-3]])
but without the possibility of a wildcard prefix.
If no namespace is specified
(just an identifier is given, like ''attr(foo)''),
the null namespace is implied.
(This is usually what's desired,
as namespaced attributes are rare.
In particular, HTML and SVG do not contain namespaced attributes.)
As with [=attribute selectors=],
the case-sensitivity of <<attr-name>> depends on the document language.
If ''attr()'' is used in a property applied to an element,
it references the attribute of the given name on that element;
if applied to a pseudo-element,
the attribute is looked up on the pseudo-element's [=originating element=].
: <<attr-type>>
::
Specifies what kind of CSS value
the attribute's value will be interpreted into
(the ''attr()''’s <dfn dfn for=attr()>substitution value</dfn>)
and what, if any, special parsing will be done to the value.
The possible values and their behavior are defined in [[#attr-types]].
Defaults to ''string'' if omitted.
: <<declaration-value>>
::
Specifies a fallback value for the ''attr()'',
which will be substituted instead of the attribute's value
if the attribute is missing
or fails to parse as the specified type.
If the <<attr-type>> argument is ''string'',
defaults to the empty string if omitted;
otherwise, defaults to the [=guaranteed-invalid value=] if omitted.
If a property contains one or more ''attr()'' functions,
and those functions are syntactically valid,
the entire property's grammar must be assumed to be valid at parse time.
It is only syntax-checked at computed-value time,
after ''attr()'' functions have been [=substitute an attr()|substituted=].
<div class='note'>
Note that the default value need not be of the type given.
For instance, if the type required of the attribute by the author is ''px'',
the default could still be <css>auto</css>,
like in ''width: attr(size px, auto);''.
</div>
<h4 id="attr-types">
''attr()'' Types</h4>
The behavior of the ''attr()'' function
depends partially on the value of the <<attr-type>> argument:
<dl dfn-type=value dfn-for=attr()>
: <dfn>string</dfn>
:: The [=substitution value=] is a CSS string,
whose value is the literal value of the attribute.
(No CSS parsing or "cleanup" of the value is performed.)
No value triggers fallback.
: <dfn>url</dfn>
:: The [=substitution value=] is a CSS <<url>> value,
whose url is the literal value of the attribute.
(No CSS parsing or "cleanup" of the value is performed.)
Note: If ''url()'' was syntactically capable of containing functions,
''attr(foo url)'' would be identical to ''url(attr(foo string))''.
No value triggers fallback.
: <dfn>ident</dfn>
:: The [=substitution value=] is a CSS <<custom-ident>>,
whose value is the literal value of the attribute,
with [=strip leading and trailing ASCII whitespace|leading and trailing ASCII whitespace stripped=].
(No CSS parsing of the value is performed.)