w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.43k stars 652 forks source link

[css-mediaqueries] [css-page] Viewport units / media queries interaction in print documents. #5437

Open emilio opened 4 years ago

emilio commented 4 years ago

Per spec, while printing, currently:

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:

If a size property declaration is qualified by a width, height, device-width, device-height, aspect-ratio, device-aspect-ratio or orientation media query [MEDIAQ] (or other conditional on the size of the paper), then the declaration must be ignored. Media queries do not honor size: they assume the paper size that would be chosen if no @page rules were specified.

But that's not great in two different ways:

Current status in browsers is the following:

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?

emilio commented 4 years ago

cc @lilles @mstensho

faceless2 commented 4 years ago

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.

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.

emilio commented 4 years ago

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 :)

faceless2 commented 4 years ago

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.

faceless2 commented 4 years ago

This would also mean un-deprecating device-width in MQ

frivoal commented 3 years ago

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.

faceless2 commented 3 years ago

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.

bernhardf-ro commented 3 years ago

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:

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.

MurakamiShinyu commented 3 years ago

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

markbrown commented 3 years ago

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.

bernhardf-ro commented 3 years ago

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?

markbrown commented 3 years ago

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.

faceless2 commented 3 years ago

+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.

bernhardf-ro commented 3 years ago

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".

emilio commented 3 years ago

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 ems are trivially cyclic.