Re: [mediaqueries][css-page] MQs should respond to page size

We discussed making media queries respond to the @page size property and vice versa on the call, and I was actioned to give use cases and a proposed solution. 

First, let's start with some context. As far as this question is concerned, we can split paged media into 3 broad categories of paged media.

Use cases for the @page's size property:

- Rendering to pdf

This is the simple case.

In the absence of an @page size property, the UA uses a default size, typically something like A4 or US letter.

If there is an @page size property, The UA renders the document on a page which is exactly that size

- Interactive paged UA

Vivliostyle viewer is a good example of this. This is similar to the pdf situation, with 2 important nuances:

 * In the absence of an @page size property, the UA
   does not a hardcoded default size, but rather fits
   the page size to the screen size or window size

 * The UA can offer a pan & zoom UI to deal with page
   sizes (set by an @page size property) that don't
   match the screen size, analogous to the one used
   by mobile browsers to deal with large layout viewports

- Rendering to paper

This is trickier, as the UA cannot generate arbitrary sizes of paper sheets, and needs to pick between existing ones. Still, the UA is expected to layout the document at the requested page size, then fit the result onto paper as best as it can.


With that in mind, I think there are 2 key features we need:

1) the width & height media queries (and consequently the aspect-ratio and orientation MQs as well) need to respond the the page size actually used. 

This is essential to be able to combine a responsive design with a preferred page size. Note that authors cannot just assume that the page size they've asked for is the one they get (not all UAs support the @page size property, users might override it in the user stylesheet...), so they need to query to be able to respond.

2) It needs to be possible to use the @page size property inside a width/height media query. Even when an author makes their design responsive, there's always a size below which things break down. no page fits in 1px width, and few work fine in 50px. Many will work at for instance 320px, but there's no hard rule about that. The author is in a good position to know what is the smallest size his design can deal with.

Recognizing that, for scrollable media, we've made it possible for an author who knows their design works fine down to 400px but not beyond to write this:
  @viewport { width: auto; }
  @media (width <= 400px ) {
    @viewport { width: 400px; }
  }
If the layout viewport would be large, let it be whatever the screen size is. but if it would be less than 400px (because the screen is smaller than that), make the layout viewport 400px. 

The exact same logic applies with paged media. An author may be perfectly happy to let the UA pick the page size, unless it would pick something too small, in which case they would want to enforce a page size they know works for their design.

This is often not an issue when printing to pdf or to your typical home printer, since the default page size, being A4 or thereabout, isn't that small. The use case is still real, but it is somewhat uncommon.

However, if you consider vivliostyle viewer or other ebook readers, which may pick as the page size the size of the screen of the mobile device they're running on (or half of it, if they want to show a spread), this becomes much more critical.

We can solve both use cases by using the following rule (suggested in the issue in the spec, and used by @viewport):

* Cascade the size property of @page rules which do not have a selector using the initial page size for viewport unit values and media query evaluations which rely on page size
* Compute the actual page size from the @page size properties cascaded above
* Cascade all other rules using that page size

With all that in place, you you can do stuff like this:

  /* Base styles */
  @media (width >= 1024px) { /* when it's wide */ }
  @media (width <= 800px) { /* when it's narrow */ }
  @media (width <= 5.8in) { /* Don't get too small*/
    @page { size: A5; }
    @viewport { width: 5.8in; }
  }

This does exactly what you'd want when printing to pdf or for interactive paged UAs. When printing on paper, it can't work around fact you've got to work with whatever paper size you do have, but it still does a decent job there.

 - Florian

Received on Sunday, 8 May 2016 22:55:08 UTC