-
Notifications
You must be signed in to change notification settings - Fork 689
/
Copy pathOverview.bs
3539 lines (2878 loc) · 133 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: WD
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, <wq-name>
Ignored Vars: Cn+1, n
Inline Github Issues: no
Default Highlight: css
Status Text: <strong>This spec is in the early exploration phase. Feedback is welcome, and and major breaking changes are expected.</strong>
</pre>
<pre class='link-defaults'>
spec:css-color-4; type:property; text:color
spec:css-values-4; type: dfn;
text: determine the type of a calculation
text: keyword
text: identifier
spec:selectors-4; type: dfn; text: selector
spec:css-conditional-5; type:type; text:<size-feature>
spec:css-conditional-5; type:dfn; text:container feature
spec:css-conditional-5; type:type; text:<container-name>
spec:css-conditional-5; type:at-rule; text:@container
spec:css-conditional-5; type:type; text:<style-query>
spec:css-conditional-5; type:type; text:<style-query>
spec:css-mixins-1; type:dfn; text:custom function
spec:css-properties-values-api; type:dfn; text: supported syntax component names
spec:html; type:element; text:link
spec:infra; type:dfn; text:list
</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]].
Additionally,
<ol>
<li value=5>Boolean combinations of a conditional notation.
These are written using the <<boolean-expr[]>> notation,
and represent recursive expressions of boolean logic
using keywords and parentheses,
applied to the grammar specified in brackets,
e.g. <<boolean-expr[ ( <media-feature> ) ]>> to express [=media queries=].
</ol>
<h3 id=component-functions>
Functional Notation Definitions</h3>
See [[css-values-4#component-functions]].
<h4 id=component-function-commas>
Commas in Function Arguments</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.
These values
(currently <<whole-value>>, <<declaration-value>>, and <<any-value>>)
are <dfn export>comma-containing productions</dfn>.
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 <em>contents</em> of that block,
and applies whatever specific restrictions it defines for itself
to those contents,
ignoring the {} block wrapper.
<div class="example">
For example, the grammar of the ''random-item()'' function is:
<pre>
random-item( <<random-caching-options>>, [<<declaration-value>>?]# )
</pre>
The ''#'' indicates comma-separated repetitions,
so randomly choosing between three keywords
would be written as normal for functions,
like:
<pre>
font-family: random-item(--x, serif, sans-serif, monospace);
</pre>
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:
<pre>
font-family: random-item(--x, {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''.
This is not all-or-nothing;
you can use {} around <em>some</em> 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:
<pre>
font-family: random-item(--x, {Times, serif}, sans-serif, {monospace});
</pre>
This represents choosing between three font-family lists:
either ''Times, serif'', or ''sans-serif'', or ''monospace''.
However, this {}-wrapping is <em>only</em> 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 <strong>invalid</strong>:
<pre>
background-image: linear-gradient(to left, {red}, magenta);
</pre>
</div>
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, <l property>''font-family: random-item(--x, {var(--list1)}, monospace)''</l>
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=]:
* <<any-value>>
* <<whole-value>>
* <<declaration-value>>
For legacy compat reasons,
the <<declaration-value>> defined the fallback value for ''var()''
is a <dfn export>non-strict comma-containing production</dfn>.
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 <em>does</em> start with a "{" token, however:
the fallback is just the contents of the {} block,
and doesn't include the {} wrapper itself.
Other contexts <em>may</em> define that they use [=non-strict comma-containing productions=],
but it <em>should</em> be avoided unless necessary.
<h3 id=boolean>
Boolean Expression Multiplier <<boolean-expr[]>></h3>
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 <dfn type><<boolean-expr>></dfn> production represents this pattern generically.
The <<boolean-expr[]>> 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:
<xmp class=prod>
<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>
</xmp>
The <<boolean-expr[]>> 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 <<boolean-expr[]>>)
resolving to false unless otherwise specified;
see [[#boolean-logic]] for details.
<div class=example>
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 <<boolean-expr[]>>, the grammar for an ''@container'' query
could be written as:
<xmp class=prod>
<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>
</xmp>
</div>
The <<general-enclosed>> 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 <css><test></css> term in a <<boolean-expr[]>>
should be defined to match <<general-enclosed>>.
<h3 id=css-syntax>
Specifying CSS Syntax in CSS: the <<syntax>> type</h3>
Some features in CSS,
such as the ''attr()'' function
or [=registered custom properties=],
allow you to specify how <em>another</em> value is meant to be parsed.
This is declared via the <<syntax>> 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=]:
<pre class="prod def" nohighlight>
<dfn><<syntax>></dfn> = '*' | <<syntax-component>> [ <<syntax-combinator>> <<syntax-component>> ]* | <<syntax-string>>
<dfn><<syntax-component>></dfn> = <<syntax-single-component>> <<syntax-multiplier>>?
| '<' transform-list '>'
<dfn><<syntax-single-component>></dfn> = '<' <<syntax-type-name>> '>' | <<ident>>
<dfn><<syntax-type-name>></dfn> = angle | color | custom-ident | image | integer
| length | length-percentage | number
| percentage | resolution | string | time
| url | transform-function
<dfn><<syntax-combinator>></dfn> = '|'
<dfn><<syntax-multiplier>></dfn> = [ '#' | '+' ]
<dfn><<syntax-string>></dfn> = <<string>>
</pre>
A <<syntax-component>> consists of either
a <<syntax-type-name>> between <> (angle brackets),
which maps to one of the [=supported syntax component names=],
or an <<ident>>, which represents any [=keyword=].
Additionally,
a <<syntax-component>> may contain a [[css-properties-values-api-1#multipliers|multiplier]],
which indicates a [=list=] of values.
Note: This means that <code><length></code>
and <code>length</code> are two different types:
the former describes a <<length>>,
whereas the latter describes a [=keyword=] <code>length</code>.
Multiple <<syntax-component>>s may be [[css-properties-values-api-1#combinator|combined]]
with a <code>|</code> <<delim-token>>,
causing the syntax components to be matched
against a value
in the specified order.
<div class='example'>
<xmp class='lang-css'>
<percentage> | <number> | auto
</xmp>
The above, when parsed as a <<syntax>>,
would accept <<percentage>> values,
<<number>> values,
as well as the keyword <code>auto</code>.
</div>
<div class='example'>
<xmp class='lang-css'>
red | <color>
</xmp>
The [=syntax definition=] resulting from the above <<syntax>>,
when used as a grammar for [=parse|parsing=],
would match an input <code>red</code> as an [=identifier=],
but would match an input <code>blue</code> as a <<color>>.
</div>
The <code>*</code> <<delim-token>> represents the [=universal syntax definition=].
The <code><transform-list></code> production
is a convenience form equivalent to <code><transform-function>+</code>.
<span class=note>Note that <code><transform-list></code> may not
be followed by a <<syntax-multiplier>>.</span>
[=Whitespace=] is not allowed
between the angle bracket <<delim-token>>s (<code><</code> <code>></code>)
and the <<syntax-type-name>> they enclose,
nor is [=whitespace=] allowed to precede a <<syntax-multiplier>>.
Note: The [=whitespace=] restrictions also apply to <code><transform-list></code>.
A <<syntax-string>> is a <<string>>
whose value successfully [=CSS/parses=] as a <<syntax>>,
and represents the same value as that <<syntax>> would.
Note: <<syntax-string>> mostly exists for historical purposes;
before <<syntax>> was defined,
the ''@property'' rule used a <<string>> for this purpose.
<h4 id=parse-syntax>
Parsing as <<syntax>></h4>
The purpose of a <<syntax>>
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 <syntax>=]:
<div algorithm>
To <dfn export>parse with a <<syntax>></dfn>
given a [=string=] or [=list=] or [=CSS/component values=] |values|,
a <<syntax>> 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 <code><<declaration-value>>?</code>,
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 <<syntax>> defines an unambiguous parse result
(or the ''*'' syntax is unambiguous on its own).
6. Return |parsed result|.
</div>
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.
<h2 id="level-4-extensions">
Extensions to Level 4 Value Types</h2>
See <a href="https://www.w3.org/TR/css-values-4/">CSS Values and Units Level 4</a>.
<!-- 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 [=URL request modifier steps=] for |url|'s <<request-url-modifier>>s in sequence
given |req|.
</div>
<!-- Big Text: position
████▌ ███▌ ███▌ ████ █████▌ ████ ███▌ █ █▌
█▌ █▌ █▌ █▌ █▌ █▌ ▐▌ █▌ ▐▌ █▌ █▌ █▌ █▌
█▌ █▌ █▌ █▌ █▌ ▐▌ █▌ ▐▌ █▌ █▌ ██▌ █▌
████▌ █▌ █▌ ███▌ ▐▌ █▌ ▐▌ █▌ █▌ █▌▐█ █▌
█▌ █▌ █▌ █▌ ▐▌ █▌ ▐▌ █▌ █▌ █▌ ██▌
█▌ █▌ █▌ █▌ █▌ ▐▌ █▌ ▐▌ █▌ █▌ █▌ █▌
█▌ ███▌ ███▌ ████ █▌ ████ ███▌ █▌ ▐▌
-->
<h3 id="position">
2D Positioning: the <<position>> type</h3>
The <dfn><<position>></dfn> 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:
<pre class=prod>
<<position>> = <<position-one>> | <<position-two>> | <<position-four>>
<dfn><<position-one>></dfn> = [
left | center | right | top | bottom |
x-start | x-end | y-start | y-end |
block-start | block-end | inline-start | inline-end |
<<length-percentage>>
]
<dfn><<position-two>></dfn> = [
[ left | center | right | x-start | x-end ] &&
[ top | center | bottom | y-start | y-end ]
|
[ left | center | right | x-start | x-end | <<length-percentage>> ]
[ top | center | bottom | y-start | y-end | <<length-percentage>> ]
|
[ block-start | center | block-end ] &&
[ inline-start | center | inline-end ]
|
[ start | center | end ]{2}
]
<dfn><<position-four>></dfn> = [
[ [ left | right | x-start | x-end ] <<length-percentage>> ] &&
[ [ top | bottom | y-start | y-end ] <<length-percentage>> ]
|
[ [ block-start | block-end ] <<length-percentage>> ] &&
[ [ inline-start | inline-end ] <<length-percentage>> ]
|
[ [ start | end ] <<length-percentage>> ]{2}
]
</pre>
If only one value is specified (<<position-one>>),
the second value is assumed to be ''center''.
If two values are given (<<position-two>>),
a <<length-percentage>> as the first value represents
the horizontal position as the offset between
the left edges of the [=alignment subject=] and [=alignment container=],
and a <<length-percentage>> as the second value represents
the vertical position as an offset between their top edges.
If both keywords are one of ''<position>/start'' or ''<position>/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.
''<position>/start'' and ''<position>/end'' aren't axis-specific,
so ''start end'' and ''end start'' represent two different positions.
If four values are given (<<position-four>>)
then each <<length-percentage>> 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 <em>inward</em>
from the edge of the [=alignment container=].
Negative values represent an offset <em>outward</em>
from the edge of the [=alignment container=].
<div class="example">
The following declarations give the stated (horizontal, vertical)
offsets from the top left corner:
<pre>
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 */
</pre>
</div>
<div class=example>
<<position>>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:
<pre>background-position: right 3em bottom 10px</pre>
</div>
The [=computed value=] of a <<position>> is
a pair of offsets (horizontal and vertical),
each given as a computed <<length-percentage>> value,
representing the distance between the left edges and top edges (respectively)
of the [=alignment subject=] and [=alignment container=].
<dl dfn-for="<position>" dfn-type=value>
<dt><dfn><<length-percentage>></dfn>
<dd>
A <<length-percentage>> 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 <<percentage>> for the horizontal offset is relative to
(<var ignore>width of [=alignment container=]</var> - <var ignore>width of [=alignment subject=]</var>).
A <<percentage>> for the vertical offset is relative to
(<var ignore>height of [=alignment container=]</var> - <var ignore>height of [=alignment subject=]</var>).
<div class=example>
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=].
<figure>
<img src="images/bg-pos.png"
alt="Diagram of image position within element"
>
<figcaption>
Diagram of the meaning of ''background-position: 75% 50%''.
</figcaption>
</figure>
</div>
<dt><dfn>top</dfn>
<dt><dfn>right</dfn>
<dt><dfn>bottom</dfn>
<dt><dfn>left</dfn>
<dd>
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.
<dt><dfn>y-start</dfn>
<dt><dfn>y-end</dfn>
<dt><dfn>x-start</dfn>
<dt><dfn>x-end</dfn>
<dd>
Computes the same as the physical edge keyword
corresponding to the [=start=]/[=end=] side
in the [=y-axis|y=]/[=x-axis|x=] axis.
<dt><dfn>block-start</dfn>
<dt><dfn>block-end</dfn>
<dt><dfn>inline-start</dfn>
<dt><dfn>inline-end</dfn>
<dd>
Computes the same as the physical edge keyword
corresponding to the [=start=]/[=end=] side
in the [=block axis|block=]/[=inline axis|inline=] axis.
<dt><dfn>center</dfn>
<dd>
Computes to a ''50%'' offset in the corresponding axis.
</dl>
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.
<h4 id="position-parsing">
Parsing <<position>></h4>
When specified in a grammar alongside other keywords, <<length>>s, or <<percentage>>s,
<<position>> is <em>greedily</em> parsed;
it consumes as many components as possible.
<div class=example>
For example,
'transform-origin' defines a 3D position
as (effectively) ''<<position>> <<length>>?''.
A value such as ''left 50px''
will be parsed as a 2-value <<position>>,
with an omitted z-component;
on the other hand,
a value such as ''top 50px''
will be parsed as a single-value <<position>>
followed by a <<length>>.
</div>
<h4 id="position-serialization">
Serializing <<position>></h4>
When serializing the [=specified value=] of a <<position>>:
<dl class=switch>
<dt>If only one component is specified:
<dd>
* The implied <a value spec="css-backgrounds-3">center</a> keyword is added,
and a 2-component value is serialized.
<dt>If two components are specified:
<dd>
* Keywords are serialized as keywords.
* <<length-percentage>>s are serialized as <<length-percentage>>s.
* Components are serialized horizontal first, then vertical.
<dt>If four components are specified:
<dd>
* Keywords and offsets are both serialized.
* Components are serialized horizontal first, then vertical;
alternatively [=block-axis=] first, then [=inline-axis=].
</dl>
Note: <<position>> 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 <<position>> is placed next to a <<length>>,
such as 'transform-origin'.
The [=computed value=] of a <<position>>
is serialized as a pair of <<length-percentage>>s
representing offsets from the left and top edges, in that order.
<h4 id="combine-positions">
Combination of <<position>></h4>
<l spec=css-values-4>[=Interpolation=]</l> of <<position>> is defined as
the independent interpolation of each component (x, y)
normalized as an offset from the top left corner
as a <<length-percentage>>.
<l spec=css-values-4>[=value addition|Addition=]</l> of <<position>> is likewise defined as
the independent <l spec=css-values-4>[=value addition|addition=]</l> each component (x, y)
normalized as an offset from the top left corner
as a <<length-percentage>>.
<!-- 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 noexport>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 ignore>progress-function</var>() = <var ignore>progress-function</var>( <var ignore>progress value</var> from <var ignore>start value</var> to <var ignore>end value</var> )
</pre>
Each resolves to a <<number>>
by [=calculating a progress function=].
<div algorithm>
To <dfn export>calculate a progress function</dfn>,
given a [=progress value=],
[=progress start value=],
and [=progress end value=]:
: If the [=progress start value=] and [=progress end value=] are different values
:: <code>([=progress value=] - [=progress start value=]) / ([=progress end value=] - [=progress start value=])</code>.
: 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.
Note: The return value is a plain <<number>>,
not [=made consistent=] with its arguments by default.
</div>
The resulting number 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=]).
''progress()'' is a [=math function=].
The syntax of ''progress()'' is defined as follows:
<pre class=prod>
<dfn id=typedef-progress-fn><<progress()>></dfn> = progress(<<calc-sum>>, <<calc-sum>>, <<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 argument [=calculations=] can resolve to any <<number>>, <<dimension>>, or <<percentage>>,
but must have a [=consistent type=]
or else the function is invalid.
The value of ''progress()'' is a <<number>>,
determined by [=calculating a progress function=],
then [=made consistent=] with the [=consistent type=] of its arguments.
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,
so it's a [=math function=].
<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(<<mf-name>>, <<calc-sum>>, <<calc-sum>>)
</pre>
where the value of the [=media feature=] corresponding to <<mf-name>>
represents the [=progress value=],
and the two <<calc-sum>> values represent
the [=progress start value=] and [=progress end value=],
respectively.
The specified [=media feature=] must be a valid “range” type feature,
the specified [=progress start value=] and [=progress end value=]
must be valid values for the specified [=media query=],
and both [=calculation=] values must have a [=consistent type=],
or else the function is invalid.
The [=progress start value=] and [=progress end value=] [=calculations=]
are interpreted as specified for the [=media feature=]
(rather than as specified by the context the function is used in).
The value of ''media-progress()'' is a <<number>>,
determined by [=calculating a progress function=].
Note: ''media-progress()'' is <em>not</em> a [=math function=];
it's just a function that evaluates to a <<number>>.
<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(<<mf-name>> [ of <<container-name>> ]?, <<calc-sum>>, <<calc-sum>>)
</pre>
where <<mf-name>> represents a [=size feature=]
and the optional <<container-name>> component specifies
the named containers to consider when selecting a container
to resolve them against.
The value of the [=size feature=] is the [=progress value=],
and the two <<calc-sum>> values represent
the [=progress start value=] and [=progress end value=],
respectively.
The specified <<mf-name>> must be a valid [=size feature=],
the specified [=progress start value=] and [=progress end value=]
must be valid values for that [=size feature=],
and both [=calculation=] values must have a [=consistent type=],
or else the function is invalid.
''container-progress()'' is only valid in a property value context;
it cannot be used in, for example, a [=media query=].
The [=progress start value=] and [=progress end value=] [=calculations=]
are interpreted as specified for the [=size feature=]
(rather than as specified by the context the function is used in).
If no appropriate containers are found,
''container-progress()'' resolves its <<size-feature>> query
against the [=small viewport size=].
The value of ''media-progress()'' is a <<number>>,
determined by [=calculating a progress function=].
Note: ''container-progress()'' is <em>not</em> a [=math function=];
it's just a function that evaluates to a <<number>>.
<!-- Big Text: *-mix()
█ █ ████ █ █ ██ ██
█ █ ██ ██ ▐▌ █ █ █▌ ▐█
█ █ █▌█ █▐█ ▐▌ █ █ █▌ ▐█
███████ ████▌ █▌ █ ▐█ ▐▌ █ █▌ ▐█
█ █ █▌ ▐█ ▐▌ █ █ █▌ ▐█
█ █ █▌ ▐█ ▐▌ █ █ █▌ ▐█
█▌ ▐█ ████ █ █ ██ ██
-->
<h2 id="mixing">
Mixing and Interpolation Notations: the *-mix() family</h2>
ISSUE(6245): This feature <a href="https://css.typetura.com/ruleset-interpolation/explainer/">does not handle multiple breakpoints very well</a>,
and <a href="https://github.com/w3c/csswg-drafts/issues/6245#issuecomment-2469190377">might need to be redesigned</a>.
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>>, <l>[=mix start value|start-value=]</l>, <l>[=mix end value|end-value=]</l> )
</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</h3>
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-token>> | <<number>> | <<'animation-timeline'>> ] && [ by <<easing-function>> ]?
</pre>
where:
<dl dfn-type=value dfn-for="<progress>">
<dt><dfn><<percentage-token>></dfn>
<dd>