W3C home > Mailing lists > Public > www-style@w3.org > August 2012

[css3-values] viewport units (v*) and zoom

From: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
Date: Mon, 20 Aug 2012 15:37:35 +0200
Message-ID: <CAOxFTcwWnSUik0viROaWX49nxDWQ6m6ynbYHArqhTA1Ya4_9FA@mail.gmail.com>
To: WWW Style <www-style@w3.org>
Hello all,

I'm toying around with view-port based lengths (specifically vh) for
font sizing, and I'm seeing unexpected results on the only browser I
have that supports them, Chromium 21.0.1180.75 (Developer Build
150248) Debian wheezy/sid on Linux amd64. It's not clear to me if the
behavior I'm seeing is related to my lack of understanding about the
units, a bug in Chromium, or some other factor I don't get, so I'm
going to expose the problem here before a submission to the Chromium
issue tracker.

The situation is the following: I have a #content div inside of which
I have a number of inline-block divs. I want the #content to be large
enough to lay out as many inner blocks side-by-side as possible
without overflowing the viewport. While waiting for the fit-content
width specification to be support in major browsers, I achieved my
desired effect by specifying a number of media queries that set the
#content width according to the viewport width; so I have a number of
specifications in the form @media (min-width: somewidth) { #content {
width: somewidth } } with increasing somewidth: 66em, 98em, 131em and
so on and so forth. This works pretty well (although it's tedious to
write), and if I zoom in or out the #content gets resized whenever the
zoom factor allows a new inner div to fit or whenever the content
would overflow the viewport. (Almost) perfect (in Chromium a reload is
necessary to let it re-apply the media queries, in Opera and
Iceweasel/Firefox the media queries are reapplied instantly when
zooming).

Now I wanted to try something slightly different: whenever the
#content fitting width would leave space around, I wanted a bigger
font size to be selected, allowing it to fill up the viewport more
nicely.

Example: let's say that the viewport is 76em; the #content is thereby
sized at 66em, and this leaves 10em of space around it. Since the 76em
of the viewport refer to the initial font size (let's say, 16px
font-size, so it's 1216px of viewport), while the 66em of the #content
refers to the actual font size, I want to set the html font-size to
something that brings the 66em of the #content to be about as large as
the viewport width (i.e. 1216px in this example).

My idea was to use html { font-size: <some width in vw > } inside the
media query, with the vw amount computed from the content width; for
example, when the #content is 66em, I want _this_ to be 100% of the
viewport, so I compute the font-size as 100/66 = 1.5vw. In practice, I
still want 1em around each side of #content, so I do 100/68 = 1.47vw.
I get the following media queries:

@media (min-width: 66em) {
	html { font-size: 1.47vw }
	#content { width: 66em }
}

@media (min-width: 98em) {
	html { font-size: 1vw }
	#content { width: 98em }
}

@media (min-width: 131em) {
	html { font-size: 0.75vw }
	#content { width: 131em }
}

@media (min-width: 164em) {
	html { font-size: 0.6vw }
	#content { width: 164em }
}

and so on.

At the default zoom level, this works exactly the way I hoped: on my
1080p external monitor, without the html font-size specification, I
get three inline divs with plenty of white space around the #content,
with the html font-size specification I still get only three columns,
but the font is larger and the viewport is full. On my laptop display
the same happens, with only two inline divs.

However, if I zoom in or out (to fit less/more inline divs) and reload
(because Chromium does not rematch media queries until I reload),
something strange happens: the selected font is either too small (if I
zoomed out) or too big (if I zoomed in). More specifically, it's the
font size that I would need to fit that many inline divs _at the
default zoom level_ (which I can see by resetting the zoom level
without reloading).

Let's talk numbers. At the default zoom level, the viewport (and the
html) is 1903px wide, and the selected font-size becomes 19px. This is
exactly what I expect: from the initial font-size of 16px, the
media-query with min-width: 98em is matche, and the next (131em) is
not matched, so the font size is 1vw = 1903/100 = 19px.

I then zoom out once. This brings the viewport (and html) to be 2114
(zoomed) px wide, or 132em for the initial font-size of 16px. The
131em media query is matched, but not the next (164em). I expect a
font size of 15.86px to be selected (2114/100 * 0.75); instead,
Chromium selects a font-size of 14.44px, which is (not exactly, but
pretty close to) 1903 / 100 * 0.75. If I zoom in instead, the opposite
happens. In both cases, what seems to be happening is that the vw is
computed on the _unzoomed_ size of the viewport, but the resulting
pixel size is applied with _zoomed_ pixel values.

To me, this looks as an inconsistency in the management of the units,
but I can't find anything pertaining the current zoom level in the CSS
values specifications, and it's not clear whether the 'initial
containing block' which the specification refers to for  the v* units
should be considered before or after the zoom factor is applied by the
user agent. The reason why I believe this is an inconsistency in
Chromium is that the actual width of the html element (which matches
the 'initial containing block' width in my case because there is no
other specification) uses _zoomed_ units. Or am I missing something
about these units? (In either case, a clarification of this in the
specification would be very useful.)




-- 
Giuseppe "Oblomov" Bilotta
Received on Monday, 20 August 2012 13:38:22 GMT

This archive was generated by hypermail 2.3.1 : Tuesday, 26 March 2013 17:20:58 GMT