Open emilio opened 4 years ago
cc @lilles @mstensho
Thanks @emilio for bringing this one up. Yes, viewport units are a bit of a pain point for us, when applied to font sizing anyway.
vw
as "Equal to 1% of the width of the content area of the first page"vw
in their current documentation, but they are "on the roadmap"vw
as "Unit of the width expressing the viewport width as 100. It cannot be used with elements for which a viewport, such as the root element, has not been established". But I'm struggling to parse that.vw
as 100% of the content-box of the current page, so you can fragment a table that is width: 50vw
from portrait to landscape and it will increase in width. This is what I believe is currently specified. But, we still have issues breaking text where font size is in viewport units, eg font-size: 80vh
and the page size changes.So I agree it's "the page box minus margins". We don't accept viewport units in @page dimensions at all, they collapse to auto
the same way a percentage against shrink-to-fit does. So size: 100vw 100vh
is invalid. I don't know about the other print engines.
Media Queries are more interesting. RealObjects, Prince and ourselves allow a nominal page width/height to be set externally, and evaluates media queries against those values. I've no information on AH formatter. And I hadn't spotted this sentence until you pointed it out:
Media queries do not honor size: they assume the paper size that would be chosen if no @page rules were specified
I think that's a very problematic sentence. Without a @page rule the default page size is auto
- UA dependent, so effectively undefined. Which means any width/height related media query is also UA dependent in print. I'm pretty sure we can, and should, improve on this.
I don't think evaluating MQ width/height against the the "first page" is useful, as that's layout dependent - for example, the first page here is arguably[1] landscape, not portrait:
@page cover {
size: a4 landscape;
}
<html>
<body>
<img style="page: cover"/>
But you could define the media width/height against the size of the last unqualified page rule - i.e. the highest priority @page rule that has no selectors and is not itself nested inside a @media or imported from a media-qualified @import. This is unambiguous once you've parsed all the stylesheets, and doesn't require layout to evaluate [EDIT: this has already been proposed in css-page issue 2]. And it still lets you do stuff like this, which might be tricky otherwise:
@media print and (width: 210mm) and (height: 297mm) {
@page landscape {
size: 297mm 210mm;
}
}
@media print and (width: 8.5in) and (height: 11in) {
@page landscape {
size: 11in 8.5in;
}
}
I could imagine this rule in an author stylesheet, and a @page rule selecting the current paper loaded into the printer being set in the user stylesheet generated by the print dialog (for example). Without any @page rule it collapses to what we have now, so there should be no compat issue for Prince or RealObjects.
Finally, I'm not sure I agree that media-query "width" should be defined to equal 100vw. Media has a very specific meaning in print (eg "Media Box" in PDF means the size of the physical page, which is well-known terminology). Personally, I don't find the fact it's not 100vw problematic - media != viewport. [EDIT: and in fact RealObjects and AH both have non-standard units that evaluate against physical media size, not viewport size]
[1] Not just arguably but actually in Prince and our product; untested elsewhere.
So I agree it's "the page box minus margins". We don't accept viewport units in @page dimensions at all, they collapse to auto the same way a percentage against shrink-to-fit does. So size: 100vw 100vh is invalid. I don't know about the other print engines.
Interesting, so they just compute to auto? Get parsed as auto? They don't get parsed? Something else? If we decide making this dependent on @page rules, it should be defined! :)
Media queries do not honor size: they assume the paper size that would be chosen if no @page rules were specified I think that's a very problematic sentence. Without a @page rule the default page size is auto - UA dependent, so effectively undefined. Which means any width/height related media query is also UA dependent in print. I'm pretty sure we can, and should, improve on this.
I don't get why that would be problematic? The user should be able to choose a page size, and this allows the website to react to that.
I don't think evaluating MQ width/height against the the "first page" is useful, as that's layout dependent - for example, the first page here is arguably[1] landscape, not portrait...
That's fair. I agree, and I think we should evaluate with the default page size, but it seems you disagree with that per the above :)
But you could define the media width/height against the size of the last unqualified page rule - i.e. the highest priority @page rule that has no selectors and is not itself nested inside a @media or imported from a media-qualified @import. This is unambiguous once you've parsed all the stylesheets, and doesn't require layout to evaluate
This is indeed a workable and possibly nicer solution, specially if you fallback to the default page size if there's no @page
rule specified size / margins. I'm a bit concerned about the complexity though: it requires two passes instead of one over all rules in the page, and it makes stuff like matchMedia
depend on the stylesheets currently applying to the page which is a bit annoying :)
Finally, I'm not sure I agree that media-query "width" should be defined to equal 100vw. Media has a very specific meaning in print (eg "Media Box" in PDF means the size of the physical page, which is well-known terminology). Personally, I don't find the fact it's not 100vw problematic - media != viewport. [EDIT: and in fact RealObjects and AH both have non-standard units that evaluate against physical media size, not viewport size]
I would expect device-width
to be the full page size, and width
to match viewport units, fwiw. Seems more similar and author-friendly to screen-based pages where width
matches viewport units while device-width
may be larger.
When printing pages that were not designed for print, it's not hard to imagine something like:
@media (min-width: 900px) {
#container { width: 900px; }
}
Or such. If viewport units don't match the width
media feature, then this would cause stuff to overflow outside of the content box, which means lost content and sad user :)
Media queries do not honor size: they assume the paper size that would be chosen if no @page rules were specified
I don't get why that would be problematic? The user should be able to choose a page size, and this allows the website to react to that.
Well I suppose when you put it like that :-) Sure. But this means the user is the only one that can choose the page size used for media query matching, and it's done by some out-of-band method rather than adding a @page to a user stylesheet. Put another way, media queries would only be used by authors to query the user's requested page size - a user couldn't use one in a user stylesheet to query the page size chosen by the author.
On rereading this paragraph, it doesn't really sound like it's a big deal. So no, not really problematic. The first-pass scan for unqualified @page rules is neater and a bit more CSS-y, but certainly it's more work. Of course, as it is now with the value being basically undefined, a UA could do that and still be in compliance...
I would expect device-width to be the full page size, and width to match viewport units
Whoops. I forgot about device-width
. The PDFReactor example shows this. PrinceXML doesn't mention device-width
, but a bit of digging found this post which makes it look likewidth
is the same as 100vw, exactly as you suggest. Your CSS example makes sense, so yes I agree on device-width.
so they just compute to auto? Get parsed as auto? They don't get parsed? Something else?
As of right now it falls back to size: auto
for us. I agree it should be defined, although I don't think it makes much difference if it's invalid at parse or compute time.
This would also mean un-deprecating device-width
in MQ
This would also mean un-deprecating device-width in MQ
Well, that, or crafting a page-width
for the paper size, with width
for the inner size, and presumably both doing the same thing on medias which don't have page margins. We can reuse the device-width
name with that meaning, but it's less clear, and unless it brings us some measure of compat with existing content, I'm not convinced there's any particular value in reusing existing names like that.
I don't know if it would be a compat issue - cc @bernhardf-ro for comment, as it was their example that showed the usage.
Thanks for tagging us in this issue. We have compiled some information on how we got to our current implementations and thoughts on the further development:
Media Features:
We support the deprecation of device-width
. While we gave it a default value equal to the default page width, this was mainly to have a sensible default value for the common case that no media feature values are set in the API. We don't think there is an actual need for this feature.
We don't oppose adding a page-width
media feature, but don't consider it necessary, either.
The width
media feature having a default value matching the default page content width matches the common concept of the first page content box being the equivalent of the viewport.
The reason we decided against actually using the sizes of the first page for those was to avoid multipass processing of CSS and potential cyclical dependencies, as already discussed here. However, once fully specified we'd of course adapt our behavior accordingly.
About computing the width
media feature value from page styles there are some details we'd like to discuss:
@media
rules (and @import
with non-empty media-query-list) be skipped or should expressions based on affected features specifically be considered non-matching?@page
rules (i.e. those without selectors) or from the @page
rules that affect the first page?Units:
For the vw
unit we use the width of the page area (content) of the first page. We also have the proprietary unit -ro-pw
("page width"), which is based on the page box (margin/trim).
After reading through this issue we are considering changing that from the first page to the generic one (computed from @page
rules without selectors, but in this case not generally skipping @media
rules).
As the computations for the units include @page
rules within matching @media
rules, and the computations for media features don't, 100vw
can differ from the value of the width
feature.
To avoid cyclical dependencies for vw
units in @page
rules (at least for size
, margin
, border-width
and padding
) we'd prefer to handle this at the point of resolving the units, either using a fixed reference size or per-property fixed results, independent of the number. Either of those could be based on common values or intentionally noticeable ones. For simplicity this should affect all values in @page
rules, regardless of their properties.
FYI, Antenna House (I was a developer) has the page-size versions of the viewport units, pvw, pvh, pvmin, pvmax (see: https://www.antenna.co.jp/AHF/help/v70e/ahf-ext.html#pvw), and the viewport units vw, vh, vmin, vmax use page area size (page-size - margin - border - padding). Vivliostyle also implemented these units in the same way (see https://github.com/vivliostyle/vivliostyle.js/pull/507).
I would like to propose the page viewport-percentage length units, pvw, pvh, pvi, pvb, pvmin, pvmax. These units should be same as normal vw, vh, vi, vb, vmin, vmax in non-paged media context.
A test sample for the viewport-percentage length units in paged media: vw, vh, vi, vb, vmin, vmax: https://github.com/vivliostyle/vivliostyle.js/blob/master/packages/core/test/files/viewport_unit.html Test with Vivliostyle Viewer: https://vivliostyle.org/viewer/#src=https://raw.githack.com/vivliostyle/vivliostyle.js/master/packages/core/test/files/viewport_unit.html
A test sample for the page viewport-percentage length units: pvw, pvh, pvi, pvb, pvmin, pvmax: https://github.com/vivliostyle/vivliostyle.js/blob/master/packages/core/test/files/page_viewport_unit.html Test with Vivliostyle Viewer: https://vivliostyle.org/viewer/#src=https://raw.githack.com/vivliostyle/vivliostyle.js/master/packages/core/test/files/page_viewport_unit.html
Antenna House (I was a developer) has the page-size versions of the viewport units, pvw, pvh, pvmin, pvmax (see: https://www.antenna.co.jp/AHF/help/v70e/ahf-ext.html#pvw), and the viewport units vw, vh, vmin, vmax use page area size (page-size - margin - border - padding). Vivliostyle also implemented these units in the same way (see vivliostyle/vivliostyle.js#507).
FYI, we are also in the process of adding these units to Prince in the same way.
So vw
/vh
/... being based on the page content size seems unopposed.
And the majority wants similar units for page size (names TBD).
What pages or virtual pages to take the sizes from is still up for discussion.
Also, should media queries be split into a separate issue?
What pages or virtual pages to take the sizes from is still up for discussion.
We currently resolve vw/vh against the generic page computed from page rules without selectors, rather than the first page. With the possibility of deferring floats it would be challenging to figure out exactly which rules apply to the thing that is going to end up first. Moreover, even if there was a :first
rule it's not clear to me that that's the page the author really wants to resolve against.
Also, should media queries be split into a separate issue?
I think it is at least a separate question. Media queries should resolve against the width that is available to the author or user (possibly after considering some stylesheets), whereas vw/vh should resolve against the size the user actually ends up with.
+1 to @markbrown's comment - the first page cannot reliably be resolved without at least some layout, so resolving against the vw/vh from the generic @page
rule will be far easier to implement.
While we currently use the first page in our implementation we agree that it would be best to use a virtual page computed from the @page
rules without selectors of any kind.
For easier discussion we suggest naming that virtual page. We suggest "base page".
The fact that pages are supposed to inherit from the root element (#5970) makes it clear to me that we shouldn't let @page
influence media queries. Otherwise sizes specified in em
s are trivially cyclic.
Per spec, while printing, currently:
The width / height media features are compared against the "page box", which is the box without subtracting margins, per https://drafts.csswg.org/mediaqueries-5/#width / https://drafts.csswg.org/css2/#page-box.
In https://drafts.csswg.org/css-values-4/#viewport-relative-lengths it is deferred to css-page, but there's no mention of
vh
orvw
or viewport relative units in that spec. So following the usual definition, viewport units resolve against the width of the ICB, which is the page box minus margins.This is, as an author, I think, a bit unfortunate. I think these two should match (and IMO it should be the later).
Regardless of whether we decide to keep stuff as-currently-defined, there are other issues... Should we account for
@page
rules, as these can change both sizes and margins? If so, which page size should be considered? The first one? The largest? (the largest is not really possible to compute I think, as that'd be circular).Some of this circularity is intended to be addressed in the size property definition https://drafts.csswg.org/css-page-3/#page-size-prop:
But that's not great in two different ways:
@page { size: 101vw 101vh }
would still be circular with the current definition.rem
units, where we've generally just provided a sensible initial value). This definition causes the process of collecting rules for a given paged document to have two passes, which is not amazing.Current status in browsers is the following:
Firefox: Does something useless for viewport units. Uses the page box size for
@media
, without accounting for@page
(we don't support@page { size }
yet anyways). Note that I'm likely changing this in https://bugzilla.mozilla.org/show_bug.cgi?id=1414600 to always use page-box-minus-margins without accounting for@page
margins for both viewport units and@page
.Chrome: Does page-box-minus-margins accounting for
@page
rules for viewport units. I haven't figured out what they exactly do for media queries, but it doesn't make sense to me, see https://bugs.chromium.org/p/chromium/issues/detail?id=1117050WebKit: Does page-box-minus-margins for viewport units as well. Doesn't seem to support
@page { margin }
or@page { size }
.Status from print engines would be very useful here I think.
I think the sanest way to prevent circularities is to not account for
@page
neither for viewport units nor media queries (if the author is specifying the margin, they can deal with it just fine). But I think this should be better defined over-all. Though maybe I've missed some place?