-
Notifications
You must be signed in to change notification settings - Fork 707
/
Copy pathOverview.bs
3106 lines (2577 loc) · 132 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 Images Module Level 4
Status: WD
Work Status: Exploring
Shortname: css-images
Level: 4
Group: csswg
ED: https://drafts.csswg.org/css-images-4/
TR: https://www.w3.org/TR/css-images-4/
Editor: Tab Atkins Jr., Google, http://xanthir.com/contact/, w3cid 42199
Editor: Elika J. Etemad / fantasai, Apple, http://fantasai.inkedblade.net/contact, w3cid 35400
Editor: Lea Verou, Invited Expert, http://lea.verou.me/about, w3cid 52258
Abstract: This module contains the features of CSS level 4 relating to the <<image>> type and replaced elements.
It includes and extends the functionality of CSS level 2 [[CSS2]] and in the previous level of this specification [[css-images-3]].
The main extensions compared to "CSS Images Module Level 3" [[css-images-3]] are several additions to the <<image>> type, such as the ''image()'' notation, the ''element()'' notation, and conic gradients.
This level is currently maintained as a diff spec over the level 3 module.
!Delta Spec: yes
Issue Tracking: Tracker http://www.w3.org/Style/CSS/Tracker/products/27
Previous Version: https://www.w3.org/TR/2017/WD-css-images-4-20170413/
Ignored Terms: <offset>, background positioning area, border image area, <meetorslice>, Map, <image>, invalid image, invalid images, concrete object size, linear-gradient(), radial-gradient(), default object size, CSS
Ignored Vars: H, P
Include Can I Use Panels: yes
Default Highlight: css
Complain About: missing-example-ids true
WPT Path Prefix: css/css-images/
WPT Display: open
</pre>
<pre class=link-defaults>
spec: css-color-4; type: type; text: <color-interpolation-method>
</pre>
Introduction {#intro}
=====================
<em>This section is not normative.</em>
This module introduces additional ways of representing 2D images,
for example as <a section href="#image-notation">a URL with color fallback</a>,
as <a href="#conic-gradients">conic gradients</a>,
or as the <a href="#element-notation">rendering of another element in the document</a>.
Value Definitions {#values}
---------------------------
This specification follows the <a href="https://www.w3.org/TR/CSS2/about.html#property-defs">CSS property definition conventions</a> from [[!CSS2]]
using the <a href="https://www.w3.org/TR/css-values-3/#value-defs">value definition syntax</a> from [[!CSS-VALUES-3]].
Value types not defined in this specification are defined in CSS Values & Units [[!CSS-VALUES-3]].
Combination with other CSS modules may expand the definitions of these value types.
In addition to the property-specific values listed in their definitions,
all properties defined in this specification
also accept the <a>CSS-wide keywords</a> as their property value.
For readability they have not been repeated explicitly.
<!--
██ ████ ██ ██ ███ ██████ ████████ ██
██ ██ ███ ███ ██ ██ ██ ██ ██ ██
██ ██ ████ ████ ██ ██ ██ ██ ██
██ ██ ██ ███ ██ ██ ██ ██ ████ ██████ ██
██ ██ ██ ██ █████████ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██ ████ ██ ██ ██ ██ ██████ ████████ ██
-->
2D Image Values: the <<image>> type {#image-values}
===================================================
The <<image>> value type denotes a 2D image. It can be a
<a section href="#url-notation">url reference</a>,
<a section href="#image-notation">image notation</a>,
or <a section href="#gradients">gradient notation</a>.
Its syntax is:
<pre class="prod"><dfn><image></dfn> = <<url>> | <<image()>> | <<image-set()>> | <<cross-fade()>> | <<element()>> | <<gradient>></pre>
An <<image>> can be used in many CSS properties,
including the 'background-image', 'list-style-image', 'cursor' properties [[!CSS2]]
(where it replaces the <<url>> component in the property's value).
In some cases an image is invalid,
such as a <<url>> pointing to a resource that is not a valid image format
or that has failed to load.
An <dfn export lt="invalid image|valid image">invalid image</dfn> is rendered
as a solid-color ''transparent'' image with no [=natural dimensions=].
However, <a>invalid images</a> can trigger error-handling clauses
in some contexts.
For example, an <a>invalid image</a> in 'list-style-image'
it is treated as ''list-style-type/none'',
allowing the 'list-style-type' to render in its place. [[CSS2]]
While an image is loading,
is a <dfn export>loading image</dfn>.
[=Loading images=] are <em>not</em> [=invalid images=],
but have similar behavior:
they are rendered as a solid-color ''transparent'' image with no [=natural dimensions=],
and may trigger fallback rendering in contexts that offer it,
but must not trigger loading of fallback resources.
Alternately, if a <a>loading image</a> happens to be replacing
an already-loaded image
(for example due to changes in the document or style sheet)
and the UA is tracking this information,
it may continue to render the already-loaded image
in place of the <a>loading image</a>.
Partially-loaded images (whose [=natural dimensions=] are known, but whose image data is not fully loaded)
may be either treated as [=loading images=]
or as loaded images rendered with partial data.
For example, a UA may render an interlaced GIF in place
as soon as its first pass of pixel data has loaded
or even as soon as the image header (which contains sizing data) has parsed
and refresh the rendering as more data loads;
or it may wait until the entire image has loaded before using it.
A <dfn export>[=computed value|computed=] <<image>></dfn> value
is the [=specified value=]
with any <<url>>s, <<color>>s, and <<length>>s computed.
Image File Formats {#image-file-formats}
----------------------------------------
At minimum, the UA must support the following image file formats
when referenced from an <<image>> value,
for all the properties in which using <<image>> is valid:
<ul>
<li>PNG, as specified in [[!PNG]]
<li>SVG, as specified in [[!SVG11]],
using the <a href="https://www.w3.org/TR/svg-integration/#secure-static-mode">secure static mode</a> (See [[!SVG-INTEGRATION]])
<li>If the UA supports animated <<image>>s,
SVG, as specified in [[!SVG11]],
using the <a href="https://www.w3.org/TR/svg-integration/#secure-animated-mode">secure animated mode</a> (See [[!SVG-INTEGRATION]])
</ul>
The UA may support other file formats as well.
Image References: the ''url()'' notation {#url-notation}
--------------------------------------------------------
Note: No change from [[css-images-3]].
Fetching External Images {#fetching-images}
-------------------------------------------
To <dfn export>fetch an external image for a stylesheet</dfn>,
given a <<url>> |url| and {{CSSStyleSheet}} sheet,
[=fetch a style resource=] given |url|,
with stylesheet {{CSSStyleSheet}},
destination "image",
CORS mode "no-cors",
and processResponse being the following steps
given [=/response=] <var ignore>res</var>
and null, failure or
a byte stream |byteStream|:
If |byteStream| is a byte stream, load the image from the byte stream.
<!--
████ ██ ██ ███ ██████ ████████ ██████ ████████ ████████ ███ ███
██ ███ ███ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██ ████ ████ ██ ██ ██ ██ ██ ██ ██ ██ ██
██ ██ ███ ██ ██ ██ ██ ████ ██████ ███████ ██████ ██████ ██ ██ ██
██ ██ ██ █████████ ██ ██ ██ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
████ ██ ██ ██ ██ ██████ ████████ ██████ ████████ ██ ███ ███
-->
Resolution/Type Negotiation: the ''image-set()'' notation {#image-set-notation}
-------------------------------------------------------------------------------
Delivering the most appropriate image resolution for a user's device can be a difficult task.
Ideally, images should be in the same resolution as the device they're being viewed in,
which can vary between users.
However, other factors can factor into the decision of which image to send;
for example, if the user is on a slow mobile connection,
they may prefer to receive lower-res images
rather than waiting for a large proper-res image to load.
The <dfn>image-set()</dfn> function allows an author to ignore most of these issues,
simply providing multiple resolutions of an image
and letting the UA decide which is most appropriate in a given situation.
Issue: This solution assumes that resolution is a proxy for filesize,
and therefore doesn't appropriately handle multi-resolution sets of vector images,
or mixing vector images with raster ones (e.g. for icons).
For example, use a vector for high-res,
pixel-optimized bitmap for low-res,
and same vector again for low-bandwidth (because it's much smaller, even though it's higher resolution).
The syntax for ''image-set()'' is:
<pre class='prod'>
<<image-set()>> = image-set( <<image-set-option>># )
<dfn><image-set-option></dfn> = [ <<image>> | <<string>> ]
[ <<resolution>> || type(<<string>>) ]?
</pre>
Issue: We should add "w" and "h" dimensions as a possibility
to match the functionality of HTML's <a element>picture</a>.
Each <<string>> inside ''image-set()'' represents a <<url>>.
The ''image-set()'' function can not be nested inside of itself,
either directly
or indirectly
(as an argument to another <<image>> type).
Each <<image-set-option>> defines a possible image for the ''image-set()'' function to represent,
composed of three parts:
* An image reference (required).
This can be a URL,
or a CSS generated image,
such as a ''linear-gradient()''.
* A <<resolution>> (optional).
This is used to help the UA decide which <<image-set-option>> to choose.
If the image reference is for a raster image,
it also specifies the image's [=natural resolution=],
overriding any other source of data that might supply a [=natural resolution=].
If not specified,
it behaves as ''1x'' for the purpose of selecting which <<image-set-option>> to use.
It also <em>defaults</em> the image's [=natural resolution=] to ''1x'',
but if some other source of data supplies a [=natural resolution=],
that resolution must be honored instead.
* A <dfn function for=image-set() lt=type()>type( <<string>> )</dfn> function (optional),
specifying the image's MIME type in the <<string>>.
If the <<string>>,
when parsed as a [=valid MIME type string=],
is either not valid,
or is valid but doesn't specify a supported image format,
the <<image-set-option>> does not define a valid option.
(This has no effect on the validity of the ''image-set()'' function.)
It does not have any effect on the image itself;
an <<image-set-option>> like <code highlight=css>url("picture.png") 1x type("image/jpeg")</code> is valid,
and if chosen will display the linked PNG image,
even though it was declared to be a JPEG.
If not specified,
it has no effect on the <<image-set-option>>.
<wpt>
image-set/image-set-all-options-invalid.html
image-set/image-set-calc-x-rendering-2.html
image-set/image-set-calc-x-rendering.html
image-set/image-set-computed.sub.html
image-set/image-set-conic-gradient-rendering.html
image-set/image-set-content-rendering.html
image-set/image-set-dpcm-rendering.html
image-set/image-set-dpi-rendering-2.html
image-set/image-set-dpi-rendering.html
image-set/image-set-dppx-rendering.html
image-set/image-set-empty-url-rendering.html
image-set/image-set-first-match-rendering.html
image-set/image-set-linear-gradient-rendering.html
image-set/image-set-negative-resolution-rendering-2.html
image-set/image-set-negative-resolution-rendering-3.html
image-set/image-set-negative-resolution-rendering.html
image-set/image-set-no-res-rendering-2.html
image-set/image-set-no-res-rendering.html
image-set/image-set-no-url-rendering.html
image-set/image-set-parsing.html
image-set/image-set-radial-gradient-rendering.html
image-set/image-set-rendering-2.html
image-set/image-set-rendering.html
image-set/image-set-repeating-conic-gradient-rendering.html
image-set/image-set-repeating-linear-gradient-rendering.html
image-set/image-set-repeating-radial-gradient-rendering.html
image-set/image-set-resolution-001.html
image-set/image-set-resolution-002.html
image-set/image-set-resolution-003.html
image-set/image-set-type-first-match-rendering.html
image-set/image-set-type-rendering-2.html
image-set/image-set-type-rendering-3.html
image-set/image-set-type-rendering.html
image-set/image-set-type-skip-unsupported-rendering.html
image-set/image-set-type-unsupported-rendering-2.html
image-set/image-set-type-unsupported-rendering.html
image-set/image-set-unordered-res-rendering.html
image-set/image-set-zero-resolution-rendering-2.html
image-set/image-set-zero-resolution-rendering.html
</wpt>
An ''image-set()'' function contains a list of one or more <<image-set-option>>s,
and must select only one of them
to determine what image it will represent:
1. First, remove any <<image-set-option>>s from the list
that specify an unknown or unsupported MIME type in their ''type()'' value.
2. Second, remove any <<image-set-option>>s from the list
that have the same <<resolution>> as a previous option in the list.
3. If there are no <<image-set-option>> left at this point,
the function represents an [=invalid image=].
3. Finally, among the remaining <<image-set-option>>s,
make a UA-specific choice of which to load,
based on whatever criteria deemed relevant
(such as the resolution of the display,
connection speed,
etc).
4. The ''image-set()'' function then represents the <<image>>
of the chosen <<image-set-option>>.
UAs <strong>may</strong> change which <<image-set-option>> they wish to use for a given ''image-set()''
over the lifetime of the page,
if the criteria used to determine which option to choose change significantly enough to make it worthwhile in the UA's estimation.
<div class='example' id='ex-image-set'>
This example shows how to use ''image-set()'' to provide an image in three versions:
a "normal" version,
a "high-res" version,
and an extra-high resolution version for use in high-quality printing
(as printers can have <em>extremely</em> high resolution):
<pre>
background-image: image-set( "foo.png" 1x,
"foo-2x.png" 2x,
"foo-print.png" 600dpi );
</pre>
</div>
<div class='example' id='ex-image-set-type'>
This example shows use of the ''type()'' function
to serve multiple versions of the same image
in both new, higher-quality formats,
and older, more widely-supported formats:
<pre>
background-image: image-set( "foo.avif" type("image/avif"),
"foo.jpg" type("image/jpeg") );
</pre>
Note that the AVIF image is given first;
since both images have the same resolution
(defaulting to ''1x'' since it's unspecified),
the JPEG image,
coming second,
is automatically dropped in UAs that support AVIF images.
In older UAs, however,
the AVIF image is ignored
(because the UA knows it doesn't support <code>"image/avif"</code> files),
and so the JPEG is chosen instead.
</div>
<div class=example id='eximage-set-multi-resolution'>
Raster images can be mixed with vector images,
or even CSS generated images.
For example, in this code snippet
a high-resolution image with subtle details is used on screens that can do it justice,
while an ordinary CSS ''linear-gradient()'' is used instead for low-resolution situations:
<pre>
background-image: image-set( linear-gradient(cornflowerblue, white) 1x,
url("detailed-gradient.png") 3x );
</pre>
</div>
<!--
████ ██ ██ ███ ██████ ████████ ███ ███
██ ███ ███ ██ ██ ██ ██ ██ ██ ██
██ ████ ████ ██ ██ ██ ██ ██ ██
██ ██ ███ ██ ██ ██ ██ ████ ██████ ██ ██
██ ██ ██ █████████ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ██ ██ ██
████ ██ ██ ██ ██ ██████ ████████ ███ ███
-->
Image Fallbacks and Annotations: the ''image()'' notation {#image-notation}
---------------------------------------------------------------------------
The ''image()'' function allows an author to:
* use <a href="https://www.w3.org/TR/media-frags/">media fragments</a> to clip out a portion of an image
* use a solid color as an image
* fallback to a solid-color image, when the image at the specified url can't be downloaded or decoded
* automatically respect the image orientation specified in the image's metadata
The ''image()'' notation is defined as:
<pre class='prod'>
<dfn>image()</dfn> = image( <<image-tags>>? [ <<image-src>>? , <<color>>? ]! )
<dfn><image-tags></dfn> = [ ltr | rtl ]
<dfn><image-src></dfn> = [ <<url>> | <<string>> ]
</pre>
A <<string>> used in ''image()'' represents a <<url>>.
As usual for URLs in CSS,
relative URLs are resolved to an absolute URL
(as described in Values & Units [[!CSS-VALUES-3]])
when a specified ''image()'' value is computed.
If the image has an orientation specified in its metadata,
such as EXIF,
the UA must rotate or flip the image to correctly orient it
as the metadata specifies.
### Image Fallbacks ### {#image-fallbacks}
If both a URL and a <<color>> are specified in ''image()'',
then whenever the URL represents an [=invalid image=] or [=loading image=],
the ''image()'' function renders as if the URL were not specified at all;
it generates a solid-color image as specified in [[#color-images]].
If just a URL is specified (no <<color>>)
and it represents an [=invalid image=] or [=loading image=],
the ''image()'' function represents the same.
<wpt>
css-image-fallbacks-and-annotations.html
css-image-fallbacks-and-annotations002.html
css-image-fallbacks-and-annotations003.html
css-image-fallbacks-and-annotations004.html
css-image-fallbacks-and-annotations005.html
</wpt>
<div class='example' id='ex-fallback'>
The fallback color can be used to ensure that text is still readable
even when the image fails to load.
For example, the following legacy code works fine if the image is rectangular and has no transparency:
<pre class="lang-css">
body { color: black; background: white; }
p.special { color: white; background: url("dark.png") black; }
</pre>
When the image doesn't load,
the background color is still there to ensure that the white text is readable.
However, if the image has some transparency,
the black will be visible behind it,
which is probably not desired.
The ''image()'' function addresses this:
<pre class="lang-css">
body { color: black; background: white; }
p.special { color: white; background: image("dark.png", black); }
</pre>
Now, the black won't show at all if the image loads,
but if for whatever reason the image fails,
it'll pop in and prevent the white text from being set against a white background.
</div>
<!-- Good example for the fallback() function
<div class='example' id='ex-fallback-2'>
For example, if a future specification defined a way to refer to a specific frame of an animated GIF with a fragment identifier,
an author could write the following to get newer browsers to use the GIF's frame,
and older browsers to instead download the fallback image:
<pre class="lang-css">background-image: image("cat_meme.gif#frame=5", "lolcat.png");</pre>
</div>
-->
### Image Fragments ### {#image-fragments}
When a URL specified in ''image()'' represents a portion of a resource
(e.g. by the use of <a href="https://www.w3.org/TR/media-frags/#naming-space">media fragment identifiers</a>)
that portion is clipped out of its context and used as a standalone image.
<div class="example" id='ex-image-fragment'>
For example, given the following image and CSS:
<a href="images/sprites.svg">
<img src="images/sprites.svg" height="20" width="180" alt="[9 circles, with 0 to 8 eighths filled in]">
</a>
<pre class="lang-css">background-image: image('sprites.svg#xywh=40,0,20,20')</pre>
...the background of the element will be the portion of the image that starts at (40px,0px) and is 20px wide and tall,
which is just the circle with a quarter filled in.
</div>
So that authors can take advantage of CSS's forwards-compatible parsing rules to provide a fallback for image slices,
implementations that support the ''image()'' notation
<em>must</em> support the <code>xywh=#,#,#,#</code> form of media fragment identifiers
for images specified via ''image()''. [[!MEDIA-FRAGS]]
<div class='example' id='ex-image-fragment-fallback'>
Note that image fragments can also be used with the ''url()'' notation.
However, a legacy UA that doesn't understand the media fragments notation
will ignore the fragment and simply display the entirety of the image.
Since the ''image()'' notation requires UAs to support media fragments,
authors can take advantage of CSS's forward-compatible parsing rules
to provide a fallback when using an image fragment URL:
<pre class="lang-css">
background-image: url('swirl.png'); /* old UAs */
background-image: image('sprites.png#xywh=10,30,60,20'); /* new UAs */
</pre>
</div>
If a URL uses a fragment identifier syntax that the implementation does not understand,
or does not consider valid for that type of image,
the URL must be treated as representing an <a>invalid image</a>.
Note: This error-handling is limited to ''image()'',
and not in the definition of URL,
for legacy compat reasons.
### Solid-color Images ### {#color-images}
If the ''image()'' function is specified with only a <<color>> argument (no URL),
it represents a solid-color image of the specified color with no [=natural dimensions=].
<div class='example' id='ex-solid-color'>
For example,
one can use this as a simple way to "tint" a background image,
by overlaying a partially-transparent color over the top of the other image:
<pre class="lang-css">background-image: image(rgba(0,0,255,.5)), url("bg-image.png");</pre>
'background-color' does not work for this,
as the solid color it generates always lies <em>beneath</em> all the background images.
</div>
### Bidi-sensitive Images ### {#bidi-images}
Before listing any <code><image-src>s</code>,
the author may specify a directionality for the image,
similar to adding a <code>dir</code> attribute to an element in HTML.
If a directional image is used on or in an element with opposite <a href="https://www.w3.org/TR/CSS21/visuren.html#propdef-direction">direction</a>,
the image must be flipped in the inline direction
(as if it was transformed by, e.g., <code>scaleX(-1)</code>, if the inline direction is the X axis).
Note: Absent this declaration,
images default to no directionality at all,
and thus don't care about the directionality of the surrounding element.
<div class='example' id='ex-image-directionality'>
A list may use an arrow for a bullet that points into the content.
If the list can contain both LTR and RTL text,
though, the bullet may be on the left or the right,
and an image designed to point into the text on one side will point out of the text on the other side.
This can be fixed with code like:
<pre class="lang-html">
<ul style="list-style-image: image(ltr 'arrow.png');">
<li dir='ltr'>My bullet is on the left!</li>
<li dir='rtl'>MY BULLET IS ON THE RIGHT!</li>
</ul>
</pre>
This should render something like:
<pre class="lang-html">
⇒ My bullet is on the left!
!THGIR EHT NO SI TELLUB YM ⇐
</pre>
In LTR list items, the image will be used as-is.
In the RTL list items, however,
it will be flipped in the inline direction,
so it still points into the content.
</div>
<!--
██████ ████████ ███████ ██████ ██████ ████████ ███ ████████ ████████ ███ ███
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██ ████████ ██ ██ ██████ ██████ ███████ ██████ ██ ██ ██ ██ ██████ ██ ██
██ ██ ██ ██ ██ ██ ██ ██ █████████ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██████ ██ ██ ███████ ██████ ██████ ██ ██ ██ ████████ ████████ ███ ███
-->
Combining images: the ''cross-fade()'' notation {#cross-fade-function}
----------------------------------------------------------------------
When transitioning between images,
CSS requires a way to explicitly refer to the intermediate image
that is a combination of the start and end images.
This is accomplished with the ''cross-fade()'' function,
which indicates the two images to be combined
and how far along in the transition the combination is.
Note: Authors can also use the ''cross-fade()'' function for many simple image manipulations,
such as tinting an image with a solid color
or highlighting a particular area of the page by combining an image with a radial gradient.
The syntax for ''cross-fade()'' is defined as:
<pre class=prod>
<dfn caniuse="css-cross-fade">cross-fade()</dfn> = cross-fade( <<cf-image>># )
<dfn><cf-image></dfn> = [ <<image>> | <<color>> ] && <<percentage [0,100]>>?
</pre>
The function represents an image generated by
combining one or more images.
The <<percentage>> represents how much of each image is retained
when it is blended with the other images.
The <<percentage>> must be between ''0%'' and ''100%'' inclusive;
any other value is invalid.
If any percentages are omitted,
all the specified percentages are summed together
and subtracted from ''100%'',
the result is floored at ''0%'',
then divided equally between all images with omitted percentages
at computed-value time.
<div class=note>
While this is not reflected in the computed value,
when all the arguments’ percentages sum to greater than ''100%'',
the sizing/painting details effectively rescale them so that they sum to exactly ''100%''.
On the other hand,
when the sum is less than ''100%'',
the sizing/painting details effectively act like there's an additional ''transparent'' argument,
with its percentage set to the remaining value
necessary to make the sum equal ''100%''.
</div>
If a <<color>> is provided,
it represents a solid-color image
with “automatic” dimensions
(it doesn't participate in the sizing of the result image at all;
see details in the sizing details below).
<wpt>
cross-fade-basic.html
cross-fade-computed-value.html
cross-fade-legacy-crash.html
cross-fade-natural-size.html
cross-fade-premultiplied-alpha.html
cross-fade-target-alpha.html
</wpt>
### ''cross-fade()'' Sizing ### {#cross-fade-sizing}
The dimensions of the image represented by a ''cross-fade()''
are a weighted average of dimensions of the <<image>> arguments to the function;
the <<color>> arguments have no effect.
They are calculated as follows:
<div algorithm>
To determine the <dfn export>[=natural dimensions=] of a cross-fade()</dfn>:
1. Let |images| be an empty list.
2. For each |argument| of the ''cross-fade()'' function with an <<image>> value:
1. Let |item| be a [=tuple=] consisting of a width, a height, and a percentage.
2. Run the [=object size negotiation=] algorithm for the <<image>>,
as appropriate for the context in which the ''cross-fade()'' appears,
and set |item|’s width and height
to the width and height of the resulting [=concrete object size=].
3. Set |item|’s percentage to the |argument|’s percentage.
3. If |images| is empty,
return no [=natural dimensions=].
4. Let |percentage sum| be the sum of all the percentages of the [=list/items=] in |images|.
5. [=list/For each=] |item| in |images|,
divide |item|’s percentage by |percentage sum|,
and set |item|’s percentage to the result.
Assert: The percentages in |images| now sum to ''100%''.
6. Let |final width| and |final height| be ''0px''.
7. [=list/For each=] |item| in |images|,
multiply |item|’s width by |item|’s percentage
and add the result to |final width|,
and multiply |item|’s height by |item|’s percentage
and add the result to |final height|.
8. Return a [=natural width=] of |final width|
and a [=natural height=] of |final height|.
</div>
### ''cross-fade()'' Painting ### {#cross-fade-painting}
The image represented by a ''cross-fade()''
is a weighted average of the input arguments to the function,
calculated as follows:
<div algorithm>
To determine the <dfn export>appearance of a cross-fade()</dfn>:
1. Let |images| be an empty list.
2. Let |size| be a [=tuple=] of width and height,
initialized to the result of finding the [=concrete object size=]
of the ''cross-fade()'' function
(using the [=natural dimensions of a cross-fade()=]).
3. For each |argument| of the ''cross-fade()'' function:
1. Let |item| be a [=tuple=] consisting of an image and a percentage.
2. If |argument| has an <<image>>,
rescale it to |size|’s width and height
and set |item|’s image to the result.
Otherwise, |argument| has a <<color>>;
set |item|’s image to a solid-color image of the <<color>>,
with |size|’s dimensions.
3. Set |item|’s percentage to the |argument|’s percentage.
4. Let |percentage sum| be the sum of all the percentages of the [=list/items=] in |images|.
5. If |percentage sum| is less than ''100%'',
append a [=tuple=] to |images|
consisting of a solid-color transparent-black image
with |size|’s dimensions,
and a percentage equal to ''100%'' minus |percentage sum|.
Otherwise,
if |percentage sum| is greater than ''100%'',
then [=list/for each=] |item| in |images|,
divide |item|’s percentage by |percentage sum|,
and set |item|’s percentage to the result.
6. Let |final image| be an image
with |size|’s dimensions,
and every pixel being the weighted linear average of the corresponding pixels of [=list/for each|each=] |item|’s image in |images|,
weighted according to the |item|’s percentage.
(Average both the color channels and the alpha channel of the pixels.)
For the purpose of this calculation,
each pixel's color must be in pre-multiplied sRGB.
<details class=note>
<summary>Details on the above operation</summary>
This is applying an N-way Porter-Duff <code>dissolve</code> operation to the source images.
Wikipedia defines <code>dissolve</code> as a stochastic operation,
with the result pixels independently randomly chosen from the source images’ corresponding pixels
according to their source images’ weights,
but as pixels shrink to infinitely small,
this converges to doing color-averaging in pre-multiplied color space.
In particular, this means that `cross-fade(white 50%, transparent 50%)`
will produce a partially-transparent solid white image.
(Rather than a partially-transparent gray,
which is what you'd get if you averaged the opaque white and transparent black pixels
in non-premultiplied space.)
As converting to pre-multiplied does entail some loss of precision,
and graphics libraries may or may not support this operation natively,
as per usual any method can be used so long as it achieves the specified effect.
For example, one can instead rebalance the percentages
according to the alphas of each pixel,
then do the color-channel averages in non-premultiplied space.
E.g., to render ''cross-fade(rgb(255 0 0 / 1) 40%, rgb(0 255 0 / .5) 20%, rgb(0 0 255 / 0) 40%)'',
rebalancing the percentages according to the 1 / .5 / 0 alphas
would produce 40% / 10% / 0%
(which renormalizes to 80% / 20% / 0%),
at which point you can average the raw color channel values
and end up with an ''rgb(204 51 0 / .5)'' image.
(Note that the alpha channel is still averaged using the original percentages,
not the rebalanced ones.)
</details>
7. Return |final image|.
</div>
### Simplifying Complex ''cross-fade()'' ### {#cross-fade-complex}
Issue: Per WG resolution,
define a notion of "equality" for images,
and combine "same" images at computed-value time,
summing their percentages.
Issue: Per WG resolution,
simplify directly-nested ''cross-fade()'' at computed-value time
by just distributing the percentage and flattening;
''cross-fade(A 10%, cross-fade(B 30%, C 70%) 90%)''
becomes ''cross-fade(A 10%, B 27%, C 63%)''.
<!--
████████ ██ ████████ ██ ██ ████████ ██ ██ ████████ ███ ███
██ ██ ██ ███ ███ ██ ███ ██ ██ ██ ██
██ ██ ██ ████ ████ ██ ████ ██ ██ ██ ██
██████ ██ ██████ ██ ███ ██ ██████ ██ ██ ██ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ████ ██ ██ ██
██ ██ ██ ██ ██ ██ ██ ███ ██ ██ ██
████████ ████████ ████████ ██ ██ ████████ ██ ██ ██ ███ ███
-->
<h3 id='element-notation' caniuse="css-element-function">Using Elements as Images: the ''element()'' notation</h3>
The ''element()'' function allows an author to use an element in the document as an image.
As the referenced element changes appearance,
the image changes as well.
This can be used, for example,
to create live previews of the next/previous slide in a slideshow,
or to reference a canvas element for a fancy generated gradient or even an animated background.
Note: The ''element()'' function only reproduces the <em>appearance</em> of the referenced element,
not the actual content and its structure.
Authors should only use this for decorative purposes,
and must not use ''element()'' to reproduce an element with significant content across the page.
Instead, just insert multiple copies of the element into the document.
The syntax for ''element()'' is:
<pre class=prod><dfn>element()</dfn> = element( <<id-selector>> )</pre>
where <<id-selector>> is an ID selector [[!SELECT]].
<p class='issue'>
Do we need to be able to refer to elements in external documents
(such as SVG paint servers)?
Or is it enough to just use url() for this?
<p class='issue'>
This name conflicts with a somewhat similar function in GCPM.
This needs to be resolved somehow.
<p class='issue'>
Want the ability to do "reflections" of an element,
either as a background-image on the element or in a pseudo-element.
This needs to be specially-handled to avoid triggering the cycle-detection.
<p class='issue'>
When we have overflow:paged,
how can we address a single page in the view?
The ''element()'' function references the element matched by its argument.
The ID is first looked up in the <a idl>elementSources</a> map,
as described in that section.
If it's not found,
it's then matched against the document.
If multiple elements are matched,
the function references the first such element.
The image represented by the ''element()'' function can vary based on whether the element is visible in the document:
<dl>
<dt>
an <a lt="element-not-rendered">element that is rendered</a>,
is not a descendant of a replaced element,
and generates a <a spec=css2>stacking context</a>
<dd>
The function represents an image with its [=natural size=]
equal to the <dfn export>decorated bounding box</dfn> of the referenced element:
<ul>
<li>
for an element rendered using a CSS rendering model,
the <a>decorated bounding box</a> is the smallest axis-aligned rectangle
that contains the <a href="https://www.w3.org/TR/2011/CR-css3-background-20110215/#border-image-area">border image areas</a> of all the fragments of the principal box
<li>
for an element rendered using the SVG rendering model,
<a href="https://www.w3.org/TR/SVGTiny12/intro.html#TermDecoratedBoundingBox">the decorated bounding box is defined by SVG</a>
</ul>
Note: Because images clip anything outside their bounds by default,
this means that decorations that extend outside the <a>decorated bounding box</a>,
like box shadows,
may be clipped.
The image is constructed by rendering the referenced element and its descendants
(at the same size that they would be in the document)
over an infinite ''transparent'' canvas,
positioned so that the edges of the <a>decorated bounding box</a> are flush with the edges of the image.
<p class='issue'>
Requiring some degree of stacking context on the element appears to be required for an efficient implementation.
Do we need a full stacking context, or just a pseudo-stacking context?
Should it need to be a stacking context normally,
or can we just render it as a stacking context when rendering it to element()?
If the referenced element has a transform applied to it or an ancestor,
the transform must be ignored when rendering the element as an image. [[!CSS3-TRANSFORMS]]
If the referenced element is broken across pages,
the element is displayed as if the page content areas were joined flush in the pagination direction,
with pages' edges corresponding to the initial containing block's start edge aligned.
<span class='note'>Elements broken across lines or columns are just rendered with their <a>decorated bounding box</a>.</span>
Implementations may either re-use existing bitmap data generated for the referenced element
or regenerate the display of the element to maximize quality at the image's size
(for example, if the implementation detects that the referenced element is an SVG fragment);
in the latter case, the layout of the referenced element in the image must not be changed by the regeneration process.
That is, the image must look identical to the referenced element,
modulo rasterization quality.
<div class='example' id='ex-element-reuse'>
As a somewhat silly example, a <{p}> element can be reused as a background elsewhere in the document:
<pre class="lang-html">
<style>
#src { color: white; background: lime; width: 300px; height: 40px; position: relative; }
#dst { color: black; background: element(#src); padding: 20px; margin: 20px 0; }
</style>
<p id='src'>I'm an ordinary element!</p>
<p id='dst'>I'm using the previous element as my background!</p>
</pre>
<img src="images/element-function.png" alt="">
</div>
<dt>an <a lt='element-not-rendered'>element that is not rendered</a>, but which provides a <a>paint source</a>
<dd>
The function represents an image with the [=natural dimensions=] and appearance of the <a>paint source</a>.
The host language defines the size and appearance of paint sources.
<div class='example' id='ex-element-not-rendered-ref'>
For example, the ''element()'' function can reference an SVG <code><pattern></code> element in an HTML document:
<pre class=lang-html>
<!DOCTYPE html>
<svg>
<defs>
<pattern id='pattern1'>
<path d='...'>
</pattern>
</defs>
</svg>
<p style="background: element(#pattern1)">
I'm using the pattern as a background!
If the pattern is changed or animated,
my background will be updated too!
</p>
</pre>
HTML also defines that a handful of elements,
such as <{canvas}>, <{img}>, and <{video}>,
provide a paint source.
This means that CSS can, for example,
reference a canvas that's being drawn into,
but not displayed in the page:
<pre class=lang-html>
<!DOCTYPE html>
<script>
var canvas = document.querySelector('#animated-bullet');
canvas.width = 20; canvas.height = 20;
drawAnimation(canvas);
</script>
<canvas id='animated-bullet' style='display:none'></canvas>
<ul style="list-style-image: element(#animated-bullet);">
<li>I'm using the canvas as a bullet!</li>
<li>So am I!</li>
<li>As the canvas is changed over time with Javascript,
we'll all update our bullet image with it!</li>
</ul>
</pre>
</div>
<dt>anything else
<dd>
The function represents an <a>invalid image</a>.
<div class='example' id='ex-invalid image'>
For example, all of the following ''element()'' uses will result in a transparent background:
<pre class=lang-html>
<!DOCTYPE html>
<p id='one' style="display:none; position: relative;">one</p>
<iframe src="http://example.com">
<p id='two' style="position: relative;">I'm fallback content!</p>
</iframe>
<ul>
<li style="background: element(#one);">
A display:none element isn't rendered, and a P element
doesn't provide a paint source.
</li>
<li style="background: element(#two);">
The descendants of a replaced element like an IFRAME
can't be used in element() either.
</li>
<li style="background: element(#three);">
There's no element with an id of "three", so this also
gets rendered as a transparent image.
</li>
</ul>
</pre>
</div>
</dl>
An element is <dfn export id='element-not-rendered' lt='element-not-rendered'>not rendered</dfn> if it does not have an associated box.
This can happen, for example,
if the element or an ancestor is ''display:none''.
Host languages may define additional ways in which an element can be considered not rendered;
for example, in SVG,
any descendant of a <code><defs></code> element is considered to be not rendered.
<div class='example' id='ex-element-preview'>