Re: [css-om] Issues with width and resolution media queries

On Fri, Dec 6, 2013 at 1:27 PM, Peter-Paul Koch <pp.koch@gmail.com> wrote:

> Recently I published a few articles where I point out what I think are
> bugs in the media query implementation of the desktop browsers. It was
> suggested I move the discussion here, so I do now.
>
> I saw the resolution discussion has already started. This mail does not
> connect to any of the previous ones but just summarises my starting point.
>
> It is my belief that the desktop browsers break compatibility with the
> mobile browsers in two instances detailed below. In order to explain how
> the mobile browsers currently handle the three viewports and related
> concepts I created a quick-and-dirty overview page at
>
> http://quirksmode.org/mobile/overview.html
>

Thanks for putting this table together! There are a few bugs though:

- physical screen: screen.width has always been defined as returning CSS
pixels[1]; it merely appeared to return physical pixels because for a long
time most devices had 1x screen density.

- ideal viewport: screen.width does *not* return the ideal viewport width.
screen.width returns the width of the screen in unscaled CSS pixels, which
happens to correspond to the ideal viewport width for web browser that take
up the full width of the screen. But web developers should not rely on the
browser being full width! Ditto device-width/device-height refer to the
screen size not the ideal viewport size when used in a media query. Only in
the meta viewport tag, for legacy reasons, do the terms device-width and
device-height refer to the size of the ideal viewport (I can see why this
might lead to confusion!).

- resolution: similarly, this isn't the ratio between the physical screen
size and the ideal viewport size. It's the ratio between the physical
window (inner) size and the ideal viewport size (or the ratio between
physical pixels and unscaled* CSS pixels).

- orientation: Non-webkit/blink browsers don't support window.orientation
(certainly Firefox doesn't). Also, window.orientation doesn't return
"portrait"|"landscape", instead it returns -90|0|90|180 (the Screen
Orientation API[2] is trying to clean this up by introducing
screen.orientation which would return a string, though the strings don't
yet match the media query...).

One thing that's notable, is that there is in fact no cross-browser
compatible way of reading the ideal viewport width (i.e., if your page
doesn't use a width=device-width viewport, finding out how wide the page
would have been if you had done so). This is a serious omission in the
current mobile CSSOM View APIs. It should probably have been provided by
window.innerWidth, but historical accident has led window.innerWidth to
mean the width of the visual viewport taking into account pinch zoom.

[1]: http://www.w3.org/TR/cssom-view/#css-pixels
[2]: http://www.w3.org/TR/screen-orientation/

The articles where I describe the problems I feel desktop browsers are
> having are at
>
> - http://quirksmode.org/blog/archives/2013/12/desktop_media_q.html (width)
> - http://quirksmode.org/blog/archives/2013/12/desktop_media_q_1.html (DPR
> and zoom)
>
> Summarised, these are my findings. All of them are explained in more
> detail in my blog posts.
>
> - Currently, the width media query in the desktop browsers is slaved to
> window.innerWidth (except in Safari), while all mobile browsers slave it to
> document.documentElement.clientWidth. This may cause problems in a few
> instances; notably when clueless web developers would use window.innerWidth
> as an equivalent for the media query. On mobile, this would break horribly,
> since there window.innerWidth is the width of the visual viewport, and not
> the layout viewport.
> Besides, this is just a compatibility issue.
>

It is indeed unfortunate that the width MQ returns the width of the layout
viewport *including* the scrollbar[3], and
document.documentElement.clientWidth returns the width of the layout
viewport *excluding* the scrollbar[4]. We should investigate whether these
can converge on a single definition...

[3]: http://dev.w3.org/csswg/mediaqueries4/#width
[4]: http://dev.w3.org/csswg/cssom-view/#dom-element-clientwidth

- I feel the recent attempts to define desktop devicePixelRatio as the
> current zoom factor are misguided, for the following reasons:
>
>  - Zoom level is not the same as DPR. For better or worse, the definition
> of DPR is now fixed as a device-based constant, and for reasons of
> cross-browser compatibility I feel desktop browsers should not change that
> definition.
>

To clarify, I think you're talking here about desktop page
zoom<http://dev.w3.org/csswg/cssom-view/#zooming>(Ctrl-+), which is
different from both pinch zoom and the scaling that
occurs when you use a viewport width other than device-width.

However it's wrong to pitch this as an incompatibility between mobile and
desktop. Having desktop browsers incorporate page zoom into
devicePixelRatio actually increases compatibility between mobile, since
devicePixelRatio now has the same meaning on mobile and desktop: it gives
the ratio between unscaled* CSS pixels and physical pixels, which is indeed
affected by page zoom (by contrast, neither pinch zoom nor weird viewport
widths affect the size of unscaled* CSS pixels).

- On mobile DPR is a constant; on desktop it is a variable. Thus,
> implementations of DPR in media queries or JavaScript targeting mobile may
> misfire on desktop.
>
> - On desktop, DPR is now de-facto linked to the dimensions of the (layout)
> viewport. No such link exists on mobile. DPR does not change when the
> layout viewport width is changed, for instance by rewriting the <meta
> viewport> tag.
>

To use your terminology, DPR is defined as the ratio of between the
physical window (inner) size and the ideal viewport size. Modifying meta
viewport can only affect the layout viewport, not the ideal viewport. This
is consistent across mobile and desktop.

 - On mobile, DPR is defined as the ratio between the physical device
> dimensions and the ideal viewport dimensions. Thus, oorting DPR to the
> desktop also requires the porting of the ideal viewport concept, which has
> no meaning on desktop. Firefox does so, but the result is that screen.width
> changes as you zoom - a weird effect, though consistent with the emerging
> mobile standard.
>

The Firefox approach is correct here. I can propose 3 arguments in favor of
this:

A) screen.width should correspond to the window width in unscaled* CSS
pixels you would get if your page went fullscreen. Since page zoom
decreases the available window width, it also decreases the window width in
fullscreen, hence should decrease the screen width exposed to JS.

B) Similarly, screen.width * window.devicePixelRatio should equal the width
of the screen in physical screen pixels, so that you know how large an
image/canvas you would need if you were to display raster graphics in
fullscreen.

C) If you combine the following assertions:

C1. screen.width, screen.availWidth and window.outerWidth all need to use
the same units so authors can move windows around reliably.
C2. window.outerWidth should be sized in unscaled* CSS pixels, so that if
you increase the size of your window by one pixel, your web page gets
larger by one CSS pixel (assuming you have a width=device-width viewport on
mobile, or no viewport on desktop).

Then together you find that all 3 of these values should be sized in
unscaled* CSS pixels.

While from a purist perspective, I can understand that it's odd for page
zoom to modify the screen size, the reality is the screen size is only
relevant in so far as the page can use the screen (which is consistently
affected by page zoom).

*: (by unscaled CSS pixel, I mean the size that a CSS pixel would be if
your UA doesn't support meta viewport, or your page has a
width=device-width,minimum-scale=1,maximum-scale=1 viewport; such a pixel
is also called a Device-Independent Pixel, or DIP)

I feel that for reasons of cross-browser compatibility the zoom level
> should be exposed in a separate media query, JavaScript property, and
> event, and that DPR should remain a device-based constant as it currently
> is.
>

There's already an event: window.onresize (since page zoom affects window
width).

-- 
> --------------------------------------------
> ppk, mobile platform strategist
> http://quirksmode.org/about/
> +.31.6.29585782
> --------------------------------------------
>

--John

Received on Friday, 6 December 2013 19:32:07 UTC