Re: [csswg-drafts] Revisiting standardization of the `zoom` property (#5623)

Here are some additional thoughts based on my research into zoom, as part of my [effort](https://bugs.chromium.org/p/chromium/issues/detail?id=1142663) to potentially deprecate and remove CSS zoom from Chromium. The research involved reading the Mozilla [issue](https://bugzilla.mozilla.org/show_bug.cgi?id=390936), relevant Chromium [issues](https://bugs.chromium.org/p/chromium/issues/list?q=label%3Acss-zoom&can=1), comments on this issue (i.e. #5623) analyzing a number of sites, and conversations with Gmail engineers.

# Compat risks:

* Microsoft Excel for Web uses CSS zoom in order to make text in cells larger.  (+)
* The Gmail mobile web app (which displays emails in a webview) uses CSS zoom to scale down HTML emails that are wider than the visible viewport, or scaling up ones that are a lot narrower, while also displaying them inline with adjacent emails or spacer divs in the same thread ([extracted example with zoom](https://jsfiddle.net/6sondL4b/1/)). (++)
* The Chrome UseCounter is [quite high](https://chromestatus.com/metrics/feature/timeline/popularity/3578).
* I [reviewed](https://docs.google.com/document/d/1cmbXpjAcXAht2ufi7bNKy-rbVNveqaf0UzeYg_DIMNA/edit?pli=1) a large number of other sites that hit the Chrome UseCounter and didn't see very many that seemed too problematic if zoom was removed.

It may not be feasible to get all of these fixed.

# Use cases I found that were compelling to me:

* Resizing external/non-responsive design content that is infeasible to make responsive (Example: Gmail.)
* A11y zooming features within the web page (examples: Microsoft Excel, and [this](https://css-tricks.com/forums/topic/emulating-browser-zoom-with-css-for-accessibility/). One other site I examined also used this pattern to provide a zoom button for a (conceptual, not iframe) sub-document.)
* Previewing content in a interstitial dialog by shrinking it down (Gmail desktop email themes do this - during the wizard flow it shows you an example result previewed in a second column. Transforms might work for this, but have worse responsive design and need special care to size correctly.)

# Chromium Implementation notes

* Chromium's implementation is not actually all that complex -- it just multiplies all non-percentage lengths, and all font sizes including percents, by the zoom factor, for the subdocument. Nested zoom multiplies. 

* On all platforms, Chromium actually implements both browser zoom (ctrl-+/-) scale factor and device scale factor by using zoom on the HTML element. (And this is reflected in the computed style of the HTML element presented to JS.) So even if CSS zoom was removed the code in Chromium would not be significantly simplified.

* APIs like `getBoundingClientRect` and `offsetWidth` divide all values by the multiplied zoom across ancestors (including self).

# Chromium Implementation known issues that should be fixed

* `getBoundingClientRect` reports values that don’t make a lot of sense:
  * X and y offsets are divided by zoom, even for cases when they shouldn’t affect it (Example: `data:text/html,<!doctype html><div style="background: lightblue;width: 100px; height: 100px; zoom: 2"></div>`. Should be x=8 and y=8 since those come from margin above the zoomed element.)
  * The result is [not usable for hit testing](https://bugs.chromium.org/p/chromium/issues/detail?id=967097&q=label%3Acss-zoom&can=1) or geometrical measurement.

# Summary

In general, I found that CSS zoom's superpower is a reliable way to make text, and the elements around it, zoom in or out, while retaining responsive design accessibility principles such as reflow within the content and to adjacent or wrapping content elements, and ensuring content is always readable. You can polyfill it by injecting custom variables into the entire document or with CSS pre-processors, but that may not be feasible for imported external content.

I think the visual implementation of zoom in Chromium works very well, and is consistent across all elements. Evidence includes:
* Web developers consistently say the same thing (including via comments on this issue and the Mozilla feature request issue).
* The browser zoom feature in Chromium works very well for increasing readability/accessibility, as does the same feature for Gecko and WebKit (which works the same way AFAIK).

The only significant problems with CSS zoom that I'm aware of are the inconsistent/illogical JS API behavior. (@emilio mentioned other complications that I'm not seeing, so I might be missing something?)

# My recommendation

* Standardize CSS zoom's *visual* behavior as-is (including behavior for percentage lengths, which I think are good as-is based on the above evidence)
* Adjust existing JS APIs as necessary to return *unzoomed* values for lengths, so that these values round-trip and are consistent with style sheets and existing browser zoom features.
* Adjust existing JS APIs as necessary to return *zoomed* values for offsets. For example `getBoundingClientRect().x` or `offsetLeft` should return a physical value that includes zoom. This allows hit testing to work and fixes an existing illogical behavior. (+++)

(+) The equivalent feature in Google Sheets / Docs uses custom code that modifies element styles to multiply their sizes by the desired zoom factor. 

(++) Imperfect [prototype version with transforms](https://jsfiddle.net/6sondL4b/2/) - note the background color is wrong in some areas. 

(+++) `offsetLeft` should only include zoom of ancestors, not self.

-- 
GitHub Notification of comment by chrishtr
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/5623#issuecomment-1644208565 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Thursday, 20 July 2023 16:12:53 UTC