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

On Sat, Dec 7, 2013 at 12:37 PM, Peter-Paul Koch <pp.koch@gmail.com> wrote:
>
>>>
>>> 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
>
>
> To clarify: this table gives the current actual situation on mobile, whether
> that situation corresponds to specifications or not. Every single detail is
> based on extensive testing in 40 or so mobile browsers.
>
> It is my contention that the desktop situation should be brought in line
> with the mobile situation. In order to do that we first must know what the
> mobile situation is. The table, and the further research it links to, does
> that.
>
>>
>> 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.
>
>
> Several mobile browsers, notably Android WebKit, return the physical
> dimensions of the screen in screen.width. The test devices have a DPR of
> more than 1; Android WebKit admits as much, and Chrome on the same devices
> returns the ideal viewport in screen.width.
> See http://quirksmode.org/mobile/tableViewport.html, first table row.
>
> I agree that these browsers use the wrong definition, and that their
> behaviour should be marked a bug.

They are bugs and the browser is not being developed anymore. The new
Android WebView does this correctly (Android level >= 19), unless it
is in Quirks mode, where you get the old buggy behaviour.

>> - 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!
>
>
> For mobile browsers, that always take up the full screen width, the
> distinction is pointless. Ideal viewport === width of screen in unscaled CSS
> pixels.

It is not for height. The initial (before viewport adaptation, coming
from fallback 980px layout or the viewport meta, etc) viewport width
is usually === screen width because most mobile browsers do not have
any chrome horizontally, they usually do vertically though.

> For desktop browsers, the concept of an ideal viewport makes no sense in my
> opinion. Also, Firefox and IE *do* count the zoom level in their
> screen.width definition, and thus do not obey your rule.

Hence the comcept 'initial viewport'.

>> 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!).
>
>
> I do not confuse the media query and the meta viewport directive.
>
> The device-width media query ALWAYS uses the same values as screen.width, in
> ALL mobile and desktop browsers I tested, with the single exception of IE on
> desktop. There are many bugs on mobile, but the source of the actual value
> is always screen.width.
>
> Therefore, if screen.width returns the ideal viewport width, the
> device-width media query also returns it; whether that's theoretically
> correct or not.
>
>>
>> - 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).
>
>
> As far as I can see the physical window (inner) size is the same as the
> physical screen size on mobile.

innerWidth is 320 on Safari on iOS, physical width is 640.

>> - 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...).
>
>
> This is all correct, but the table has constraints on how much information
> fits into it.

That makes the table quite confusing.

>> 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).
>
> That's also correct, but I think that the mobile browsers are slowly coming
> together on screen.width as the way to read out the ideal viewport.

I guess John is one of the people who would know as he works on Chrome
for Android :-)

I see that more of a coincidence as most mobile browser do not have
horizontal chrome. It also doesn't cover height.

>>> - 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...
>
>
>
> I made a mistake in my original article. I confused the definitions of
> document.documentElement.clientWidth and window.innerWidth in the desktop
> browsers.
>
> Fortunately, that should make it easier to bring the desktop browsers in
> line with the mobile ones:
>
> - Desktop browsers want to exclude the scrollbar from width media queries
> because otherwise the page may stretch underneath the scrollbar.

The appearance/disappearance of scrollbars actually change the layout.
Nothing really goes under the scroll bar (unless it is a scroll
indicator as on most mobile browsers; but which Chrome desktop also
supports now), though it might overflow the viewport.

>
> - In order to do so, they should use the
> document.documentElement.clientWidth value for the width media query, like
> the mobile browsers do.

You know that there is no code difference here for Chrome on desktop
and Chrome on mobile. You can check the code yourself.

> Problem solved.
>
>
>>>
>>> - 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 (Ctrl-+),
>> which is different from both pinch zoom and the scaling that occurs when you
>> use a viewport width other than device-width.
>
>
> So far, I defined zoom as the process by which the user increases the size
> of the CSS pixels in order to achieve better legibility. It is true that
> this process works differently on desktop and on mobile.

Page zoom and pinch are very different. The former is like a more
permanent setting (actually it is not a zoom as such, but a relayout
with a different CSS<->device pixel ratio), where as pinch zoom allows
you temporary to zoom in (no relayout).

There is no reason that desktop browsers cannot support both, and IE
does in Metro mode and so does Chrome on the Pixel or the new Acer
C720P, and maybe even on Windows? You will see pinch zoom coming to
more and more desktop browsers, while still having page zoom support
as well.

> It's true that we need to expose page zoom level, but I do not see the
> existence of two types of zooming as an argument for exposing page zoom
> specifically in DPR.

You should not consider page zoom as zooming, but more as an
upscale/downscale done by changing the ratio between CSS and device
pixels. It is called zooming because early browsers callled it that,
and in the beginning it was not a full page zoom, but a
upscale/downscale of the font sizes.

> I feel that if it's so important the difference between the two zooms should
> be made explicit. Say, a pageZoomLevel and a pinchZoomLevel property? The
> first would always be 1 on mobile, the second would always be 1 on desktop.
> And we'd expose both pinch zoom and page zoom.

Pinch zoom is using a lot of optimization like not repainting before
the pinch zoom ends, and not allowing JavaScript interaction (at least
on iOS where JS execution is suspended during pinch zoom). Allowing
developers to add hooks to pinch zoom could make it not smooth anymore
and very confusing for users.

>> 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,
>
>
> The physical pixel count never changes, but something must change in order
> to get another DPR reading. That means the unscaled pixels must scale when
> you use page zoom.

So why is the DPR value useful? If I have a Retina display (initial
viewport DPR == 2) and set my page zoom to 50% (DPR == 1) then why
should I download high quality (x2) images and scale them down, when I
could just paint the x1 image directly which is optimized for the
actual CSS<->device pixel ratio.

> That sounds weird to me. Either the unscaled pixels don't scale, or they
> scale, but in that case they aren't unscaled pixels. I'd like some more
> clarifications before I can accept this.
>
> I mean, DIPs, the old name for what's apparently now called unscaled pixels,
> were supposed to be static, right?
>
>
>>>
>>> - 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.
>
>
> This is how Firefox does it, but it doesn't make sense to me. Unscaled
> pixels scale.
>
>
>>
>>
>> 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.
>
>
> window.outerWidth is the one property I never researched because it has no
> meaning on mobile. Leaving out that one, I agree to all of this. But it
> doesn't prove anything about exposing page zoom level in DPR, and it
> requires unscaled pixels to scale.

Samsung devices now support split screen and even windowed apps. It
will soon have meaning.

>> 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).
>
>
> The resize event works with page zoom on desktop, but not with pinch zoom on
> mobile.

Nor should it.

> The resize event does not reliably fire when a page is pinch-zoomed and
> cannot stand in for a zoom event on mobile.
> http://quirksmode.org/dom/events/resize_mobile.html , third row in second
> table.
>
> --
> --------------------------------------------
> ppk, mobile platform strategist
> http://quirksmode.org/about/
> +.31.6.29585782
> --------------------------------------------



-- 
Kenneth Rohde Christiansen
Web Platform Architect, Intel Corporation.
Phone  +45 4294 9458 ﹆﹆﹆

Received on Saturday, 7 December 2013 12:43:20 UTC