8000 csswg-drafts/css-images/Overview.src.html at eb182a8689546e587d298bba67e34e6634ebe1b8 · w3c/csswg-drafts · GitHub
Skip to content

Latest commit

 

History

History
3524 lines (2937 loc) · 166 KB

File metadata and controls

3524 lines (2937 loc) · 166 KB
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?
<p>
The ''element()'' function references the element matched by its argument.
If multiple elements are matched,
the function references the first such element.
<p>
The image represented by the ''element()'' function can vary based on whether the element is visible in the document:
<dl>
<dt>an <i title="element-not-rendered">element that is rendered</i> and is not a descendant of a replaced element
<dd>
<p>
The function represents an image with its intrinsic size equal to the <dfn>decorated bounding box</dfn> of the referenced element:
<ul>
<li>
for an element rendered using a CSS rendering model,
the <i>decorated bounding box</i> is the smallest axis-aligned rectangle
that contains the <a href="http://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="http://www.w3.org/TR/SVGTiny12/intro.html#TermDecoratedBoundingBox">the decorated bounding box is defined by SVG</a>
</ul>
<p class=note>
Note: Because images clip anything outside their bounds by default,
this means that decorations that extend outside the <i>decorated bounding box</i>,
like box shadows,
may be clipped.
<p>
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 <i>decorated bounding box</i> 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()?
<p>
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]]
<p>
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 <i>decorated bounding box</i>.</span>
<p>
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'>
<p>
As a somewhat silly example, a <code>&lt;p></code> element can be reused as a background elsewhere in the document:
<pre><!--
-->&lt;style>&#xa;<!--
-->#src { color: white; background: lime; width: 300px; height: 40px; }&#xa;<!--
-->#dst { color: black; background: element(#src); padding: 20px; margin: 20px 0; }&#xa;<!--
-->&lt;/style>&#xa;<!--
-->&lt;p id='src'>I'm an ordinary element!&lt;/p>&#xa;<!--
-->&lt;p id='dst'>I'm using the previous element as my background!&lt;/p></pre>
<img src="images/element-function.png" alt="">
</div>
<dt>an <i title='element-not-rendered'>element that is not rendered</i>, but which <i title='paint-source'>provides a paint source</i>
<dd>
<p>
The function represents an image with the intrinsic size and appearance of the <i title=paint-source>paint source</i>.
The host language defines the size and appearance of paint sources.
<div class='example'>
<p>
For example, the ''element()'' function can reference an SVG <code>&lt;pattern></code> element in an HTML document:
<pre><!--
-->&lt;!DOCTYPE html>&#xa;<!--
-->&lt;svg>&#xa;<!--
--> &lt;defs>&#xa;<!--
--> &lt;pattern id='pattern1'>&#xa;<!--
--> &lt;path d='...'>&#xa;<!--
--> &lt;/pattern>&#xa;<!--
--> &lt;/defs>&#xa;<!--
-->&lt;/svg>&#xa;<!--
-->&lt;p style="background: element(#pattern1)">&#xa;<!--
--> I'm using the pattern as a background!&#xa;<!--
--> If the pattern is changed or animated, &#xa;<!--
--> my background will be updated too!&#xa;<!--
-->&lt;/p></pre>
<p>
HTML also defines that a handful of elements,
such as <code>&lt;canvas></code>, <code>&lt;img></code>, and <code>&lt;video></code>,
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><!--
-->&lt;!DOCTYPE html>&#xa;<!--
-->&lt;script>&#xa;<!--
--> var canvas = document.querySelector('#animated-bullet');&#xa;<!--
--> canvas.width = 20; canvas.height = 20;&#xa;<!--
--> drawAnimation(canvas);&#xa;<!--
-->&lt;/script>&#xa;<!--
-->&lt;canvas id='animated-bullet' style='display:none'>&lt;/canvas>&#xa;<!--
-->&lt;ul style="list-style-image: element(#animated-bullet);">&#xa;<!--
--> &lt;li>I'm using the canvas as a bullet!&lt;/li>&#xa;<!--
--> &lt;li>So am I!&lt;/li>&#xa;<!--
--> &lt;li>As the canvas is changed over time with Javascript,&#xa;<!--
--> we'll all update our bullet image with it!&lt;/li>&#xa;<!--
-->&lt;/ul></pre>
</div>
<dt>anything else
<dd>
<p>
The function represents an <i>invalid image</i>.
<div class='example'>
<p>
For example, all of the following ''element()'' uses will result in a transparent background:
<pre><!--
-->&lt;!DOCTYPE html>&#xa;<!--
-->&lt;p id='one' style="display:none;">one&lt;/p>&#xa;<!--
-->&lt;iframe src="http://example.com">&#xa;<!--
--> &lt;p id='two'>I'm fallback content!&lt;/p>&#xa;<!--
-->&lt;/iframe>&#xa;<!--
-->&lt;ul>&#xa;<!--
--> &lt;li style="background: element(#one);">&#xa;<!--
--> A display:none element isn't rendered, and a P element&#xa;<!--
--> doesn't provide a paint source.&#xa;<!--
--> &lt;/li>&#xa;<!--
--> &lt;li style="background: element(#two);">&#xa;<!--
--> The descendants of a replaced element like an IFRAME&#xa;<!--
--> can't be used in element() either.&#xa;<!--
--> &lt;/li>&#xa;<!--
--> &lt;li style="background: element(#three);">&#xa;<!--
--> There's no element with an id of "three", so this also&#xa;<!--
--> gets rendered as a transparent image.&#xa;<!--
--> &lt;/li>&#xa;<!--
-->&lt;/ul></pre>
</div>
</dl>
<p>
An element is <dfn id='element-not-rendered' title='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>&lt;defs></code> element is considered to be not rendered.
<div class='example'>
<p>
The ''element()'' function can be put to many uses.
For example, it can be used to show a preview of the previous or next slide in a slideshow:
<pre><!--
-->&lt;!DOCTYPE html>&#xa;<!--
-->&lt;script>&#xa;<!--
-->function navigateSlides() {&#xa;<!--
--> var currentSlide = ...;&#xa;<!--
--> document.querySelector('#prev-slide').id = '';&#xa;<!--
--> document.querySelector('#next-slide').id = '';&#xa;<!--
--> currentSlide.previousElementSibling.id = 'prev-slide';&#xa;<!--
--> currentSlide.nextElementSibling.id = 'next-slide';&#xa;<!--
-->}&#xa;<!--
-->&lt;/script>&#xa;<!--
-->&lt;style>&#xa;<!--
-->#prev-preview, #next-preview { &#xa;<!--
--> position: fixed;&#xa;<!--
--> ...&#xa;<!--
-->}&#xa;<!--
-->#prev-preview { background: element(#prev-slide); }&#xa;<!--
-->#next-preview { background: element(#next-slide); }&#xa;<!--
-->&lt;/style>&#xa;<!--
-->&lt;a id='prev-preview'>Previous Slide&lt;/a>&#xa;<!--
-->&lt;a id='next-preview'>Next Slide&lt;/a>&#xa;<!--
-->&lt;section class='slide'>...&lt;/section>&#xa;<!--
-->&lt;section class='slide current-slide'>...&lt;/section>&#xa;<!--
-->...</pre>
<p>
In this example, the <code>navigateSlides</code> function updates the ids of the next and previous slides,
which are then displayed in small floating boxes alongside the slides.
Since you can't interact with the slides through the ''element()'' function (it's just an image),
you could even use <code>click</code> handlers on the preview boxes to help navigate through the page.
</div>
<h4 id='paint-sources'>
Paint Sources</h4>
<p>
Host languages may define that some elements provide a <dfn title="paint-source">paint source</dfn>.
Paint sources have an intrinsic width, height, and appearance,
separate from the process of rendering,
and so may be used as images even when they're <i title='element-not-rendered'>not rendered</i>.
<p>
In HTML, the <code>&lt;img></code>, <code>&lt;video></code>, and <code>&lt;canvas></code> elements provide paint sources
(defined in each element's section in <a href='http://www.whatwg.org/specs/web-apps/current-work/multipage/'>HTML5</a>).
<p>
In SVG, any element that provides a <a href='http://www.w3.org/TR/SVG/pservers.html'>paint server</a> provides a paint source.
<span class='note'>Note: In SVG1.1,
the <code>&lt;linearGradient></code>,
<code>&lt;radialGradient></code>,
and <code>&lt;pattern></code> elements
provide paint sources.</span>
They are drawn as described in the spec,
with the coordinate systems defined as follows:
<dl>
<dt>objectBoundingBox
<dd>
The coordinate system has its origin at the top left corner of the rectangle defined by the <i>concrete object size</i> that it's being drawn into,
and the same width and height as the <i>concrete object size</i>.
A single <a href="http://www.w3.org/TR/SVG/coords.html#Units">user coordinate</a> is the width and height of the <i>concrete object size</i>.
<dt>userSpaceOnUse
<dd>
The coordinate system has its origin at the top left corner of the rectangle defined by the <i>concrete object size</i> that it's being drawn into,
and the same width and height as the <i>concrete object size</i>.
<a href="http://www.w3.org/TR/SVG/coords.html#Units">User coordinates</a> are sized equivalently to the CSS ''px'' unit.
</dl>
<p class='note'>
It is expected that a future version of this module will define ways to refer to paint sources in external documents,
or ones that are created solely by script and never inserted into a document at all.
<h4 id='element-cycles'>
Cycle Detection</h4>
<p>
The ''element()'' function can produce nonsensical circular relationships,
such as an element using itself as its own background.
These relationships can be easily and reliably detected and resolved, however,
by keeping track of a dependency graph and using common cycle-detection algorithms.
<p>
The dependency graph consists of edges such that:
<ul>
<li>
every element depends on its children
<li>
for any element A with a property using the ''element()'' function pointing to an element B,
A depends on B
<li>
if a host language defines a way for elements to refer to the rendering of other elements,
the referencing element depends on the referenced element.
For example, in SVG,
a <code>&lt;use></code> element depends on the element it referenced.
</ul>
<p>
If the graph contains a cycle,
any ''element()'' functions participating in the cycle are <i>invalid images</i>.
<!--
dddddddd
CCCCCCCCCCCCC ffffffffffffffff d::::::d
CCC::::::::::::C f::::::::::::::::f d::::::d
CC:::::::::::::::C f::::::::::::::::::f d::::::d
C:::::CCCCCCCC::::C f::::::fffffff:::::f d:::::d
C:::::C CCCCCCrrrrr rrrrrrrrr ooooooooooo ssssssssss ssssssssss f:::::f ffffffaaaaaaaaaaaaa ddddddddd:::::d eeeeeeeeeeee
C:::::C r::::rrr:::::::::r oo:::::::::::oo ss::::::::::s ss::::::::::s f:::::f a::::::::::::a dd::::::::::::::d ee::::::::::::ee
C:::::C r:::::::::::::::::r o:::::::::::::::oss:::::::::::::s ss:::::::::::::s f:::::::ffffff aaaaaaaaa:::::a d::::::::::::::::d e::::::eeeee:::::ee
C:::::C rr::::::rrrrr::::::ro:::::ooooo:::::os::::::ssss:::::ss::::::ssss:::::sf::::::::::::f a::::ad:::::::ddddd:::::d e::::::e e:::::e
C:::::C r:::::r r:::::ro::::o o::::o s:::::s ssssss s:::::s ssssss f::::::::::::f aaaaaaa:::::ad::::::d d:::::d e:::::::eeeee::::::e
C:::::C r:::::r rrrrrrro::::o o::::o s::::::s s::::::s f:::::::ffffff aa::::::::::::ad:::::d d:::::d e:::::::::::::::::e
C:::::C r:::::r o::::o o::::o s::::::s s::::::s f:::::f a::::aaaa::::::ad:::::d d:::::d e::::::eeeeeeeeeee
C:::::C CCCCCC r:::::r o::::o o::::ossssss s:::::s ssssss s:::::s f:::::f a::::a a:::::ad:::::d d:::::d e:::::::e
C:::::CCCCCCCC::::C r:::::r o:::::ooooo:::::os:::::ssss::::::ss:::::ssss::::::sf:::::::f a::::a a:::::ad::::::ddddd::::::dde::::::::e
CC:::::::::::::::C r:::::r o:::::::::::::::os::::::::::::::s s::::::::::::::s f:::::::f a:::::aaaa::::::a d:::::::::::::::::d e::::::::eeeeeeee
CCC::::::::::::C r:::::r oo:::::::::::oo s:::::::::::ss s:::::::::::ss f:::::::f a::::::::::aa:::a d:::::::::ddd::::d ee:::::::::::::e
CCCCCCCCCCCCC rrrrrrr ooooooooooo sssssssssss sssssssssss fffffffff aaaaaaaaaa aaaa ddddddddd ddddd eeeeeeeeeeeeee
-->
<h3 id='cross-fade-function'>
Combining images: the ''cross-fade()'' notation</h3>
<p>
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.
<p class="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.
<p>
The syntax for ''cross-fade()'' is defined as:
<pre class=prod><dfn>&lt;image-combination></dfn> = cross-fade( <var>&lt;percentage></var>? <var>&lt;image></var> [, <var>&lt;image></var> | <var>&lt;color></var> ]? )</pre>
<p>
The function represents an image generated by
combining two images.
<p>
The <var>&lt;percentage></var> represents how much of the first image is retained
when it is blended with the second image.
The <var>&lt;percentage></var> must be between ''0%'' and ''100%'' inclusive;
any other value is invalid.
If omitted,
it defaults to the value ''50%''.