Forum How do I...?

Absolute page size and position elements

jdown
Hi, I'm evaluating Prince for a project I'm working on. I have the trial implemented through PHP, HTML string to PDF method.

The document I'm converting is a list of pages, and each element is absolute positioned inside each page. When I view the HTML output the elements are positioned as they should be, when I run it through Prince the elements start from the top left corner, and run vertically down the page in a list.

Each page div has an explicit width/height in pixels, is there a way to reference the actual page size vs. pixel equivalents? Or is this safe?

Each element has a style tag, with its top and left set to it's position, but both values seem to be ignored?

Here's an example of the HTML:
<html>
<head>
<title>Tim's Proposal</title>

<link href="/assets/css/pp.export.css" type="text/css" rel="stylesheet" media="all" />
<style type="text/css">
@page {
size: US-Letter portrait;
margin:0 0 0 0;
}
.page-size {
position:relative;
width:816px;
height:1056px;
outline:1px solid black;
}
.ppUserStyle23 {
font-family:Georgia;
font-size:14px;
line-height:12px;
color:#a10da1;
text-align:left;
}
.ppUserStyle22 {
font-family:Verdana;
font-size:10px;
line-height:12px;
color:#000000;
text-align:left;
}
</style>

</head>
<body>

<div class="proposal-pages">
<div class="proposal-page page-size">
<div class="textbox" style="width:237px;height:143px;top:27px;left:19px;z-index:500px;">This is some other text.<br></div>
</div>

<div class="proposal-page page-size">
<div class="textbox" style="width:237px;height:143px;top:27px;left:19px;z-index:500px;">This is some other text.<br></div>
</div>

<div class="proposal-page page-size">
<div class="textbox" style="width:217px;height:177px;top:60px;left:86px;z-index:500px;"><span class="ppUserStyle23">This is some text.</span><br><br><span class="ppUserStyle23 ppUserStyle22">This is some other text.</span><br><br><span class="ppUserStyle23">This is another text.</span><br></div>
<img src="http://jonathan.pitchperfectapp.com/uploads/images_library/placeholder1.jpg" class="image" style="width:98px;height:138px;top:369px;left:489px;z-index:500px;" />
<img src="http://jonathan.pitchperfectapp.com/uploads/images_library/placeholder1.jpg" class="image" style="width:191px;height:269px;top:45px;left:457px;z-index:500px;border:5px solid #db83db;border-radius:10px;" />
</div>

<div class="proposal-page page-size">
<div class="textbox" style="width:217px;height:177px;top:60px;left:86px;z-index:500px;"><span class="ppUserStyle23">This is some text.</span><br><br><span class="ppUserStyle23 ppUserStyle22">This is some other text.</span><br><br><span class="ppUserStyle23">This is another text.</span><br></div>
<img src="http://jonathan.pitchperfectapp.com/uploads/images_library/placeholder1.jpg" class="image" style="width:98px;height:138px;top:369px;left:489px;z-index:500px;" />
<img src="http://jonathan.pitchperfectapp.com/uploads/images_library/placeholder1.jpg" class="image" style="width:191px;height:269px;top:45px;left:457px;z-index:500px;border:5px solid #db83db;border-radius:10px;" />
</div>
</div>

</body>
</html>


Any ideas on why it's not working as expected?
mikeday
Sounds reasonable, would you be able to provide a link to the style sheet as well? Presumably this applies "position: absolute" to the elements.
jdown
The stylesheet has two classes, .textbox and .image, both which apply position:aboslute, then the elements have inline style tags for the top/left values. I ended up fixing it by just moving the pos:abs to the inline styles and it works perfectly, so it must not like mixing class/inline styles for that attribute.

Here's the CSS file in case you want to replicate it;
body, html {
	width:100%;
	height:100%;
	margin:0;
	padding:0;
}

.proposal-pages {
	display:block;
	position:relative;
}

.proposal-page {
	display:block;
	position:relative;
	page-break-after:always;
}

.textbox {
	display:block;
	position:absolute;
}

.image {
	display:block;
	position:absolute;
	box-sizing:border-box;
}


For my second question, is setting pages (divs) by pixel width/height the best way to accomplish a full page container or is there a way to reference the "size" tag like this:
[code]
@page {
size: US-Letter portrait;
margin:0 0 0 0;
}
[/size]
As far as I know there is no way to reference that type of value in normal CSS, does Prince provide any custom CSS rule for this or are pixel values the only way to do it?

Very impressed with Prince so far!
mikeday
Thanks for the sample document. It appears to be correctly generating a four page PDF output file. I would suggest removing this rule from your style sheet:
body, html {
   width:100%;
   height:100%;
}

Specifying a height for the root element can cause unexpected behaviour in Prince, as 100% of the physical paper height has different implications to the browser, where it is 100% of the window/viewport height.

Other than that, everything looks fine! You can specify widths and heights of absolutely positioned blocks in physical units, like inches or millimetres, that will make it easier to match the page size. There is no way to literally use a page size for the block, but for US-Letter it's just 8.5" x 11".
ohenrik
It seems that the only way to get a background image to cover 100% and 61.8% of a page height is to set the body, html and all other parent divs to height 100%. However as you note here, this causes problem with prince, for example with footnotes (they always appear on the next page).

So it seems like i have to hard code the page height, unless there is a way to make an element 61.8% of a page (for example A4*0.681)?
hallvord
It seems that the only way to get a background image to cover 100% and 61.8% of a page height is to set the body, html and all other parent divs to height 100%.


I'm not entirely sure what you meant by "100% and 61.8% of a page height" - perhaps it was supposed to say 100% of the width and 61.8% of the height?

It is possible to style the content with position:absolute to be able to fit it to the page. However, I'm not yet sure if this is the best way to do it.

Announcement: repos for tests/utils

hallvord
The Prince devs recently added "Support vh/vw units relative to the @page area" to the Prince roadmap. When implemented, this should help you scale content relative to the size of the page (or to be precise, relative to the size of the page's content area). For now you'll have to hard-code dimensions in physical units though.

Announcement: repos for tests/utils

ohenrik
I mean 100% or 61.5%, but yes also with width 100%. Support for something like 100vw and 61.8vh would be awesome :)

Please also check how how this works with the inline footnotes css that you have built (great feature btw!) :)
hallvord
hallvord wrote:
For now you'll have to hard-code dimensions in physical units though.


I take that back :) If you set position:fixed you can style dimensions in percentages of page width/height. If you have an outer element that's position:fixed and an inner with width set (or implicit) and margin-left/margin-right set to auto, horizontal centering is also easy:

.outer{
    position: fixed;
    width: 100%;
    height: 100%;
    page-break-after: always;
    page-break-before: always;
    page-break-inside: avoid;
}
.inner{
    max-height: 70%;
    margin-left: auto;
    margin-right: auto;
    margin-top: 25%;
}


If .inner is an image (for example if you style it with content:url(image.jpg)) it will now be resized proportionally to fit inside the available height (or 70% of the height to be specific) and centered.

True vertical centering is however harder. I have not yet found a good solution for that.

Announcement: repos for tests/utils

Edited by hallvord

hallvord
Vertical centering is best achieved with a display:table-cell hack - unless all you need to do is to center an image vertically, in which case you might get away with a simple background-position style.

@ohenrik: are there any yet unsolved questions here? :)

Announcement: repos for tests/utils

wouterg
Will the vw support be for the next release? This would help us a lot in achieving responsive text. So as long as the aspect ratio is the same, one could use one document for different sizes.
mikeday
Difficult to say, it's on the roadmap but may present technical difficulties due to the fact that the page size or orientation can be changed halfway through the document, eg. for landscape pages. We'll do our best. :)