Skip to content

Commit 94cfc4c

Browse files
chrishtrzcorpan
andauthored
[css-viewport] [cssom-view-1] Add a definition of the zoom CSS property (#9699)
* Add definition of the zoom css property * Spell out the complete spec * none * Avoid zero * Further clarifications * Add zoom in more places * Fixes to formatting * Fixes to formatting * Replace 'or zoom' with 'unscaled' * Fix formatting and add alt text * Shorten notes * Shorten heading * Add background images * Omit fenced frames; clarify note about iframes * Fix spec reference type * Fix spaces and tabs * Fix some lint issues * Remove stray character * Remove more 'and zoom' * fix unscaled * Fix newlines * Special-case 0 and 0% * HTMLImageElement.{x,y} should be scaled * Address code review feedback * Address code review comments * Fix flat tree * Add notes about web compat * Fix references that should say 'scaled' * Clarify effective zoom * Fix typo Co-authored-by: Simon Pieters <[email protected]> * Switch to used value instead of computed style * define used value instead of claiming it as a consequence * Clarify flat tree ancestors --------- Co-authored-by: Simon Pieters <[email protected]>
1 parent 667d335 commit 94cfc4c

File tree

4 files changed

+181
-15
lines changed

4 files changed

+181
-15
lines changed

css-cascade-3/Overview.bs

+2
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,8 @@ Used Values</h3>
465465
the result of taking the <a>computed value</a>
466466
and completing any remaining calculations to make it the absolute theoretical value
467467
used in the formatting of the document.
468+
The effect of the 'zoom' property is applied during this stage,
469+
and before any calculations that require layout.
468470

469471
<p class='example'>
470472
For example, a declaration of ''width: auto'' can't be resolved into a length without knowing the layout of the element's ancestors,

css-viewport/Overview.bs

+163
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ spec: virtual-keyboard; urlPrefix: https://w3c.github.io/virtual-keyboard
2727
type: attribute; text: overlaysContent; for: VirtualKeyboard; url: dom-virtualkeyboard-overlayscontent
2828
</pre>
2929

30+
<pre class="anchors">
31+
spec: fenced-frames; urlPrefix: https://wicg.github.io/fenced-frame/
32+
type: interface; text: FencedFrames
33+
</pre>
3034

3135
<h2 id="intro">
3236
Introduction</h2>
@@ -358,6 +362,165 @@ only the value previously set to it.
358362
}
359363
</pre>
360364

365+
<h2 id='zoom-property'>
366+
The 'zoom' property
367+
</h2>
368+
369+
An element becomes zoomed when the 'zoom' property has a positive computed value different than 1
370+
(or when a flat tree ancestor has zoom).
371+
372+
To apply zoom, the [=used value=] of a CSS property is pre-multiplied
373+
(before any other steps in the [=used value=] stage)
374+
by the [=used value=] of 'zoom' for the element.
375+
It also multiplies the [=natural size=] of all replaced elements,
376+
background images,
377+
and nested frames
378+
(except for fenced frames [[!FENCED-FRAME]])
379+
by the [=used value=] of 'zoom'.
380+
381+
Note: This results in a magnification or minification effect.
382+
383+
Note: Since this multiplication is on [=computed value=]s, it applies to
384+
all inherited properties such as 'line-height' and 'font-size'.
385+
386+
Nested values of 'zoom' multiply, resulting in additional scaling of <<length>> values.
387+
The [=used value=] for zoom is always its [=effective zoom=].
388+
389+
The 'zoom' property has no effect on <<length>> property values with computed values that are 'auto' or <<percentage>>.
390+
391+
Note: Unlike 'transform',
392+
scaling the 'zoom' property affects layout.
393+
394+
Note: The computed value of 'font-size' is never <<percentage>>;
395+
thus 'zoom' always applies.
396+
397+
Note: 'zoom' does not affect or prevent 'transform' scaling.
398+
399+
<pre class="propdef">
400+
Name: zoom
401+
Value: <<number>> || <<percentage>>
402+
Initial: 1
403+
Applies to: all <<length>> property values of all elements
404+
Inherited: no
405+
Percentages: Converted to <<number>>
406+
Media: visual
407+
Computed value: as specified, but with <<percentage>> converted to the equivalent <<number>>
408+
Animation type: not animatable
409+
</pre>
410+
411+
The values of this property have the following meanings:
412+
413+
<dl dfn-for="zoom" dfn-type=value>
414+
<dt><dfn><<number>></dfn>
415+
<dd>
416+
Positive floating point number indicating a zoom factor.
417+
Numbers smaller than 1.0 indicate a "zoom out" or minification effect,
418+
while numbers greater than 1.0 indicate a "zoom in" or magnification effect.
419+
A 0 value is treated as if it was 1.
420+
421+
Note: The treatment of 0 is a web compatibility quirk.
422+
423+
<dt><dfn><<percentage>></dfn>
424+
<dd>
425+
Positive floating point number,
426+
followed by a percentage character ("%") which indicates a zoom factor multiplied by 100.
427+
A 0 percentage is treated as if it was 100%.
428+
429+
Note: The treatment of 0 is a web compatibility quirk.
430+
431+
</dl>
432+
433+
Negative values for 'zoom' are illegal.
434+
435+
<div class="example">
436+
Example of the 'zoom' property applied during hover for magnification effect.
437+
438+
<pre>
439+
&lt;div class="messageBox"&gt;
440+
&lt;div class="label"&gt;Text of the label&lt;/div&gt;
441+
&lt;/div&gt;
442+
443+
&lt;style&gt;
444+
.messageBox {
445+
width: 10em;
446+
padding: 2em;
447+
border: medium solid lightblue;
448+
}
449+
450+
.messageBox:hover {
451+
zoom: 150%;
452+
}
453+
454+
.label {
455+
background: lightgrey;
456+
padding: 1em;
457+
text-align: center;
458+
}
459+
&lt;/style&gt;
460+
</pre>
461+
462+
Here is an llustration of the before and after hover state of the message box element:
463+
<img src="css_zoom_hover_example.png" alt="Two images,
464+
showing the zooming effect before and after zoom has applied. The second is 1.5 larger.">
465+
</div>
466+
467+
<div class="example">
468+
Example of nested zoom.
469+
In this example, "Inner text" is 4x as large as "Outer text",
470+
and "Middle text" is 2x as large as "Outer text".
471+
472+
<pre>
473+
&lt;div style="zoom: 2"&gt;
474+
Middle text
475+
&lt;div style="zoom: 2"&gt;
476+
Inner text
477+
&lt;div&gt;
478+
&lt;div&gt;
479+
Outer text
480+
</pre>
481+
</div>
482+
483+
<div class="example">
484+
Example of replaced elements. In this example,
485+
the image and iframe will be twice as large as their default sizing.
486+
487+
<pre>
488+
&lt;div style="zoom: 2"&gt;
489+
&lt;img src="..."&gt;
490+
&lt;iframe src="..."&gt;&lt;/iframe&gt;
491+
&lt;div&gt;
492+
</pre>
493+
</div>
494+
495+
The <dfn>effective zoom</dfn> of an element is the product of its computed
496+
value of 'zoom' and all flat tree ancestors' computed values of 'zoom'.
497+
498+
The <dfn export>scaled</dfn> value of a CSS length is the [=used value=] of that length;
499+
in particular it includes zoom.
500+
501+
The <dfn export>unscaled</dfn> value of a CSS length relative to an element is the [=scaled=] value divided by the element's [=effective zoom=].
502+
503+
<div class="note">
504+
The [=effective zoom=] of an element in a nested frame may be a value other than 1 even if 'zoom' is never set on an element in that frame. This can be observed by authors via APIs such as {{Window/devicePixelRatio}} and {{Element/getBoundingClientRect}}.
505+
</div>
506+
507+
<h3 id='zoom-om'>
508+
DOM and CSSOM interaction
509+
</h3>
510+
511+
Computed style APIs (i.e., all values returned by {{getComputedStyle()}}) that are non-auto and non-percentage lengths must be [=unscaled=].
512+
513+
The {{Element/getBoundingClientRect}},
514+
{{Element/getClientRects}},
515+
and {{IntersectionObserver}} APIs must return rects with [=scaled=]
516+
lengths.
517+
518+
All other APIs related to element geometries must return [=unscaled=] lengths.
519+
This is explained in detail in [[cssom-view#extensions-to-the-htmlelement-interface]].
520+
521+
The {{Window/devicePixelRatio}} of a frame is multiplied by the [=effective zoom=] inherited by its parent frame.
522+
</h3>
523+
361524
<h2 class="no-num" id="changes">Appendix A. Changes</h2>
362525

363526
This appendix is <em>informative</em>.
4.95 KB
Loading

cssom-view-1/Overview.bs

+16-15
Original file line numberDiff line numberDiff line change
@@ -1141,7 +1141,7 @@ aborting on the first step that returns a value:
11411141
1. Return the {{DOMRect}} object in <var>list</var> at index 0.
11421142
1. If <a>caret node</a> is a text entry widget that is a replaced element,
11431143
and that is in the document,
1144-
return a {{DOMRect}} object for the caret in the widget
1144+
return a [=scaled=] {{DOMRect}} object for the caret in the widget
11451145
as represented by the <a>caret offset</a> value.
11461146
The <a>transforms</a> that apply to the element and its ancestors are applied.
11471147
1. Return null.
@@ -1197,7 +1197,7 @@ namely {{CheckVisibilityOptions/opacityProperty}} and {{CheckVisibilityOptions/v
11971197
The <dfn method for=Element>getClientRects()</dfn> method, when invoked, must return the result of the following algorithm:
11981198

11991199
1. If the element on which it was invoked does not have an associated [=CSS/box=] return an empty {{DOMRectList}} object and stop this algorithm.
1200-
1. If the element has an associated <a>SVG layout box</a> return a {{DOMRectList}} object containing a single {{DOMRect}} object that describes the bounding box of the element as defined by the SVG specification, applying the <a>transforms</a> that apply to the element and its ancestors.
1200+
1. If the element has an associated <a>SVG layout box</a> return a [=scaled=] {{DOMRectList}} object containing a single {{DOMRect}} object that describes the bounding box of the element as defined by the SVG specification, applying the <a>transforms</a> that apply to the element and its ancestors.
12011201
1. Return a {{DOMRectList}} object containing {{DOMRect}} objects in content order, one for each <a spec=css-break>box fragment</a>, describing its border area (including those with a height or width of zero) with the following constraints:
12021202

12031203
* Apply the <a>transforms</a> that apply to the element and its ancestors.
@@ -1418,24 +1418,24 @@ The <dfn attribute for=Element>scrollHeight</dfn> attribute must return the resu
14181418
The <dfn attribute for=Element>clientTop</dfn> attribute must run these steps:
14191419

14201420
1. If the element has no associated [=CSS/box=] or if the [=CSS/box=] is inline, return zero.
1421-
1. Return the computed value of the 'border-top-width' property plus the height of any scrollbar rendered between the top <a>padding edge</a> and the top <a>border edge</a>, ignoring any <a>transforms</a> that apply to the element and its ancestors.
1421+
1. Return the [=unscaled=] computed value of the 'border-top-width' property plus the height of any scrollbar rendered between the top <a>padding edge</a> and the top <a>border edge</a>, ignoring any <a>transforms</a> that apply to the element and its ancestors.
14221422

14231423
The <dfn attribute for=Element>clientLeft</dfn> attribute must run these steps:
14241424

14251425
1. If the element has no associated [=CSS/box=] or if the [=CSS/box=] is inline, return zero.
1426-
1. Return the computed value of the 'border-left-width' property plus the width of any scrollbar rendered between the left <a>padding edge</a> and the left <a>border edge</a>, ignoring any <a>transforms</a> that apply to the element and its ancestors.
1426+
1. Return the [=unscaled=] computed value of the 'border-left-width' property plus the width of any scrollbar rendered between the left <a>padding edge</a> and the left <a>border edge</a>, ignoring any <a>transforms</a> that apply to the element and its ancestors.
14271427

14281428
The <dfn attribute for=Element>clientWidth</dfn> attribute must run these steps:
14291429

14301430
1. If the element has no associated [=CSS/box=] or if the [=CSS/box=] is inline, return zero.
14311431
1. If the element is the [=root element=] and the element's <a>node document</a> is not in <a>quirks mode</a>, or if the element is <a>the <code>body</code> element</a> and the element's <a>node document</a> <em>is</em> in <a>quirks mode</a>, return the <a>viewport</a> width excluding the size of a rendered scroll bar (if any).
1432-
1. Return the width of the <a>padding edge</a> excluding the width of any rendered scrollbar between the <a>padding edge</a> and the <a>border edge</a>, ignoring any <a>transforms</a> that apply to the element and its ancestors.
1432+
1. Return the [=unscaled=] width of the <a>padding edge</a> excluding the width of any rendered scrollbar between the <a>padding edge</a> and the <a>border edge</a>, ignoring any <a>transforms</a> or that apply to the element and its ancestors.
14331433

14341434
The <dfn attribute for=Element>clientHeight</dfn> attribute must run these steps:
14351435

14361436
1. If the element has no associated [=CSS/box=] or if the [=CSS/box=] is inline, return zero.
14371437
1. If the element is the [=root element=] and the element's <a>node document</a> is not in <a>quirks mode</a>, or if the element is <a>the <code>body</code> element</a> and the element's <a>node document</a> <em>is</em> in <a>quirks mode</a>, return the <a>viewport</a> height excluding the size of a rendered scroll bar (if any).
1438-
1. Return the height of the <a>padding edge</a> excluding the height of any rendered scrollbar between the <a>padding edge</a> and the <a>border edge</a>, ignoring any <a>transforms</a> that apply to the element and its ancestors.
1438+
1. Return the [=unscaled=] height of the <a>padding edge</a> excluding the height of any rendered scrollbar between the <a>padding edge</a> and the <a>border edge</a>, ignoring any <a>transforms</a> that apply to the element and its ancestors.
14391439

14401440

14411441
<h3 id=element-scrolling-members>{{Element}} Scrolling Members</h3>
@@ -1553,6 +1553,7 @@ The <dfn attribute for=HTMLElement>offsetParent</dfn> attribute must return the
15531553
1. If <var>ancestor</var> is <a>closed-shadow-hidden</a> from the element and its computed value of the 'position' property is ''position/fixed'', terminate this algorithm and return null.
15541554
1. If <var>ancestor</var> is not <a>closed-shadow-hidden</a> from the element and satisfies at least one of the following, terminate this algorithm and return <var>ancestor</var>.
15551555
* The element is a containing block of absolutely-positioned descendants (regardless of whether there are any absolutely-positioned descendants).
1556+
* The element has a non-default used value of 'zoom'.
15561557
* It is <a>the <code>body</code> element</a>.
15571558
* The computed value of the 'position' property of the element is ''static'' and the ancestor is one of the following <a>HTML elements</a>: <code>td</code>, <code>th</code>, or <code>table</code>.
15581559
1. If there is no more parent of <var>ancestor</var> in the <a>flat tree</a>, terminate this algorithm and return null.
@@ -1561,8 +1562,8 @@ The <dfn attribute for=HTMLElement>offsetParent</dfn> attribute must return the
15611562
The <dfn attribute for=HTMLElement>offsetTop</dfn> attribute must return the result of running these steps:
15621563

15631564
1. If the element is <a>the <code>body</code> element</a> or does not have any associated [=CSS/box=] return zero and terminate this algorithm.
1564-
1. If the {{HTMLElement/offsetParent}} of the element is null return the y-coordinate of the top <a>border edge</a> of the first [=CSS/box=] associated with the element, relative to the <a>initial containing block</a> origin, ignoring any <a>transforms</a> that apply to the element and its ancestors, and terminate this algorithm.
1565-
1. Return the result of subtracting the y-coordinate of the top <a>padding edge</a>
1565+
1. If the {{HTMLElement/offsetParent}} of the element is null return the [=unscaled=] y-coordinate of the top <a>border edge</a> of the first [=CSS/box=] associated with the element, relative to the <a>initial containing block</a> origin, ignoring any <a>transforms</a>that apply to the element and its ancestors and terminate this algorithm.
1566+
1. Return the [=unscaled=] result of subtracting the y-coordinate of the top <a>padding edge</a>
15661567
of the first [=CSS/box=] associated with the {{HTMLElement/offsetParent}} of the element
15671568
from the y-coordinate of the top <a>border edge</a>
15681569
of the first [=CSS/box=] associated with the element,
@@ -1574,13 +1575,13 @@ The <dfn attribute for=HTMLElement>offsetTop</dfn> attribute must return the res
15741575
The <dfn attribute for=HTMLElement>offsetLeft</dfn> attribute must return the result of running these steps:
15751576

15761577
1. If the element is <a>the <code>body</code> element</a> or does not have any associated [=CSS/box=] return zero and terminate this algorithm.
1577-
1. If the {{HTMLElement/offsetParent}} of the element is null return the x-coordinate of the left <a>border edge</a> of the first [=CSS/box=] associated with the element, relative to the <a>initial containing block</a> origin, ignoring any <a>transforms</a> that apply to the element and its ancestors, and terminate this algorithm.
1578-
1. Return the result of subtracting the x-coordinate of the left <a>padding edge</a> of the first [=CSS/box=] associated with the {{HTMLElement/offsetParent}} of the element from the x-coordinate of the left <a>border edge</a> of the first [=CSS/box=] associated with the element, relative to the <a>initial containing block</a> origin, ignoring any <a>transforms</a> that apply to the element and its ancestors.
1578+
1. If the {{HTMLElement/offsetParent}} of the element is null return the [=unscaled=] x-coordinate of the left <a>border edge</a> of the first [=CSS/box=] associated with the element, relative to the <a>initial containing block</a> origin, ignoring any <a>transforms</a> that apply to the element and its ancestors, and terminate this algorithm.
1579+
1. Return the [=unscaled=] result of subtracting the x-coordinate of the left <a>padding edge</a> of the first [=CSS/box=] associated with the {{HTMLElement/offsetParent}} of the element from the x-coordinate of the left <a>border edge</a> of the first [=CSS/box=] associated with the element, relative to the <a>initial containing block</a> origin, ignoring any <a>transforms</a> that apply to the element and its ancestors.
15791580

15801581
The <dfn attribute for=HTMLElement>offsetWidth</dfn> attribute must return the result of running these steps:
15811582

15821583
1. If the element does not have any associated [=CSS/box=] return zero and terminate this algorithm.
1583-
1. Return the width of the axis-aligned bounding box
1584+
1. Return the [=unscaled=] width of the axis-aligned bounding box
15841585
of the [=border boxes=]
15851586
of all fragments generated by the element's [=principal box=],
15861587
ignoring any <a>transforms</a> that apply to the element and its ancestors.
@@ -1593,7 +1594,7 @@ The <dfn attribute for=HTMLElement>offsetWidth</dfn> attribute must return the r
15931594
The <dfn attribute for=HTMLElement>offsetHeight</dfn> attribute must return the result of running these steps:
15941595

15951596
1. If the element does not have any associated [=CSS/box=] return zero and terminate this algorithm.
1596-
1. Return the height of the axis-aligned bounding box
1597+
1. Return the [=unscaled=] height of the axis-aligned bounding box
15971598
of the [=border boxes=]
15981599
of all fragments generated by the element's [=principal box=],
15991600
ignoring any <a>transforms</a> that apply to the element and its ancestors.
@@ -1613,11 +1614,11 @@ partial interface HTMLImageElement {
16131614
};
16141615
</pre>
16151616

1616-
The <dfn attribute for=HTMLImageElement>x</dfn> attribute, on getting, must return the x-coordinate of the left <a>border edge</a> of the
1617+
The <dfn attribute for=HTMLImageElement>x</dfn> attribute, on getting, must return the [=scaled=] x-coordinate of the left <a>border edge</a> of the
16171618
first [=CSS/box=] associated with the element, relative to the <a>initial containing block</a> origin, ignoring any
16181619
<a>transforms</a> that apply to the element and its ancestors, or zero if there is no [=CSS/box=].
16191620

1620-
The <dfn attribute for=HTMLImageElement>y</dfn> attribute, on getting, must return the y-coordinate of the top <a>border edge</a> of the
1621+
The <dfn attribute for=HTMLImageElement>y</dfn> attribute, on getting, must return the [=scaled=] y-coordinate of the top <a>border edge</a> of the
16211622
first [=CSS/box=] associated with the element, relative to the <a>initial containing block</a> origin, ignoring any
16221623
<a>transforms</a> that apply to the element and its ancestors, or zero if there is no [=CSS/box=].
16231624

@@ -1637,7 +1638,7 @@ containing a list of {{DOMRect}} objects in content order that matches the follo
16371638

16381639
* For each element selected by the range, whose parent is not selected by the range, include the border areas returned by invoking {{Element/getClientRects()}} on the element.
16391640
* For each {{Text}} node selected or partially selected by the range (including when the
1640-
boundary-points are identical), include a {{DOMRect}} object (for the part that is selected, not
1641+
boundary-points are identical), include [=scaled=] {{DOMRect}} object (for the part that is selected, not
16411642
the whole line box). The bounds of these {{DOMRect}} objects are computed using font metrics;
16421643
thus, for horizontal writing, the vertical dimension of each box is determined by the font
16431644
ascent and descent, and the horizontal dimension by the text advance width. If the range covers

0 commit comments

Comments
 (0)