Forum How do I...?

Change the "browser" viewport size (CSS responsive designs)

grexican
When rendering web content, is there any way to specify the on-screen "width" of the content being rendered? We have some standard responsive breakpoints that we can't easily manipulate. My goal is to effectively "zoom out" on the content by setting the width in pixels of what I want to be rendered on the page. This is especially important for landscape mode. In Portrait mode, we are more width-constrained. When we switch to landscape, I'd expect to be able to hit a different breakpoint in rendering. But no matter what I do, I can't get Prince to hit that breakpoint. When I manipulate the width and height, it makes things larger or bigger when it renders; but it still, internally, doesn't change the "browser" print size. It's still hitting a smaller media breakpoint. There must be some internal value that's being set that I can't seem to override.

I even went as far as to render the content with a headless browser, where I have full control over the viewport, and then sent the final HTML into Prince to do the printing; but at print time, the CSS still is loaded and its breakpoint is chosen for the final print version.

In short: is there no way I can specify the viewport size when rendering content so that my responsive CSS can pick the proper rendering breakpoint?
mikeday
There is the --css-dpi=DPI option which allows you to change the default from 96dpi to something higher, perhaps that would help?
grexican
No luck. It makes the text really tiny on the screen; but it still doesn't change the breakpoint width of the viewport. I've tried even using the @page { size: ... } and giving my own px values. Extreme values like 3000px 3000px. It does generate a large, square PDF page. But the CSS media query breakpoint that gets used is still the same. I've tried setting DPI to 3x the normal 96. I've tried 1/2 the DPI. I tried all kinds of combinations of pixel and DPI changes. No breakpoint changes :(
grexican
I also tried using the meta viewport tag to see if I could address that, but looks like the Prince engine ignores it (as non-mobile devices usually do!)
mikeday
What is the exact media query that is triggering or failing to trigger?
grexican
It's very simple:
@media (min-width: 1101px)
{
...
}

It's based on bootstrap, with slightly different pixel values, but otherwise, the same concept for breakpoints
grexican
FYI I reached out to DocRaptor asking the same. Here's what their documentation says

For Pipelines 10 and above, DocRaptor always uses an 816px viewport width for media query purposes, regardless of the actual document size. One of DocRaptor's key advantages is that you can use multiple document sizes within the same document.—unlike a webpage, which is always the same width. When combined with media queries, this functionality could create an infinite loop because media queries can adjust and move content from page to page, thereby endlessly resizing the page. Because of this, our viewport width is locked based on our defaults.

https://docraptor.com/documentation/article/8358342-media-queries

So it seems like it's some inherent restriction for PrinceXML. I'm not sure if there's a way to overcome it, or if there's a patch that can be done to help control it.

As we are trying to render a web-based result with a sprinkle of PDF friendliness, I can't just go back to the original source and say "please change your breakpoints to accommodate this). The reality is, if I could get the pixel breakpoint right for my page then shrink to fit (similar to the way meta viewport works), then we'd be set. And PrinceXML already has SOME support for it via prince-shrink-to-fit https://www.princexml.com/doc/11/properties/prince-shrink-to-fit/

I just need to able to specify the actual viewport size used for rendering and then this would all be perfect, but I've been coming up empty with all my trials
mikeday
Right, we will look into this and see if there are any options available.
grexican
I tried a few more things. I was hoping I could use variables as width placeholders, and then load them dynamically at runtime, but that doesn't work :(

:root {
--width1: 900px;
}

@media (min-width: var(--width1)) { /* This will not work */
}

I also tried to rig things with JS, but no luck there either (not surprisingly)
markbrown
Hi,

CSS media queries are supposed to let you respond to things that are coming in from the environment, such as the size of the browser window. For print, this would essentially be the size you would get by default. So I think the DocRaptor (and Prince) behaviour is as intended.

Maybe Viewport Length Units would help?

Mark
grexican
Mark - if I told PrinceXML to print me a 2000px by 2000px PDF, shouldn't THAT be the resolution for the media query?? Instead, the page _WILL_ print at 2000x2000 but the media query used will be the static 816px viewport. I don't see how this is the intended behaviour.

Viewport length units cannot be used to specify media queries. Once in a viewport, they serve for elements; but not for the actual pixel values needed for media queries.
markbrown
Apologies, I wasn't sure which parts you wanted control over. For the purpose of media queries, we treat the '--page-size' command line option as being analogous to the user resizing the browser window. So if you set '--page-size="3000px 3000px"', for example, then media queries should respond to that.

Note that unlike using CSS to set the page size - which can be done from inside a media query - using the command line doesn't create the possibility of infinite loops.

Mark
grexican
I'll build a sample test case then, because I'm not seeing those results. When I set to 3000x3000 it's still using a smaller media query.

See the attached screenshot. You'll see I made a MASSIVE page (print preview, actual size, is just a blip in the middle) but even at that massive scale, the top widgets are 2x2. At 1200px all 4 widgets should be on the same row.

  1. Clipboard Image (9).jpg44.5 kB
markbrown
Thanks, a test case should help. Here's one from my side to show what I mean:
<style>
@page {
    size: 1000px 1000px;
}
@media (min-width: 600px) {
    .test { color: red; }
}
</style>
<div class="test">test</style>

A '--page-size' command line option that sets the width below 600px stops the media query from firing, changing the color, while the actual page and text size are still determined by the @page rule.

You might be interested to know that the issue you've raised gets a mention in the paged media spec. Quote:

> It would be useful if media queries could respond at least to sizes specified on an unqualified @page.

https://www.w3.org/TR/css-page-3/#issue-59a903e8
grexican
I didn't appreciate what you were saying earlier. By setting the command line argument I was able to achieve what I needed. Thanks very much for your help!