Forum How do I...?

Margin collision and page-break-before

Stephane
In Prince 6.0rev2, elements with a non-zero margin-top and "page-break-before: always" are displayed at the top of a page (as they should), with their margin. While the same element that appears at the top of a page in the normal flow has no margin. This is a change for previous versions. I assume it has to do with the different treatment of margin collision on first pages in 6.0rev2, but is this exact case intended?
mikeday
Yes, this is a change from the old behaviour. In the past, block margins at the top of a page were always ignored. However, this was inconsistent with web browsers, and made it awkward to do simple things like move chapter headings down the page. The new policy is that block margins will be kept if they occur on a "first page", such as the first page of the document, or the first page following a user-induced page break.
whittaker007
Wouldn't it make more sense for the first element of the body flow on a new page to always have it's top margin applied regardless of whether the page is broken manually or automatically?

I've just come across a case where my content is automatically broken into pages, and the headings at the top of the new pages are much too close to the header element. I've had to go through my markup and place classes on those headings to apply a page-break-before to get my margins back.

It just seems wrong. In my mind, a page is really another enclosing element around it's content, and if that were literally true (a page treated as a container div) then margins on content inside would be applied. So why aren't they in this case?
mikeday
The reason for this is that always applying the top margin can result in unwanted space above paragraphs that occur at the top of the page. This is a particular problem when the author adds a margin to separate paragraphs, but it ends up resulting in the text starting lower on some pages than others.
whittaker007
Sorry, I don't quite follow that rationale. If I understand what you're suggesting, the "unwanted space" above paragraphs that occur at the top of the page is presumably from a top margin applied to the paragraph style? Isn't that the way the box model is supposed to work? If the author didn't want that space they could easily apply a style that only applies a bottom margin to paragraphs instead of both top and bottom margins, or they could apply a p:first-child rule to eliminate the top margin from the first paragraph, and so on.

CSS rules empower the author power to change the way their document is rendered to get the effect they want - which is a good thing. If the user agent applies a blanket rule that removes margins that have been explicitly set by the author, that is taking power away from the author and stylesheets - which is a bad thing. And the only way to override this behaviour is to modify the markup to apply an explicit page break to places where a page break would naturally occur anyway, purely in order to apply margins which have already been set - which is a crazy thing IMHO!
mikeday
It's not possible to select the first paragraph on a page unfortunately, as that would give authors more precise control over the margins that are used for such elements. A similar problem occurs with text in columns, where you typically want the text to line up at the top of each column, even if one of the columns happens to start with a paragraph. While the author could remove the top margin from every paragraph, this can cause other complications when paragraphs follow tables or other blocks that may not have a bottom margin applied to them.
whittaker007
Forgive me if that sounded like a rant, it was intended in good humour and my bemusement may well be due to an incomplete understanding of paged media on my part. Perhaps I should be applying some top padding to the body element to ensure a minimum gap instead, but there are almost certainly other valid cases apart prom paragraphs where you will want top margins to be respected when an element flows onto a new page.

For example, what if you had an element which contains absolutely positioned content which is placed outside it's bounding box with a negative top value - a legend in a fieldset for example. A top margin applied to the parent element may be necessary to prevent the positioned content from being placed over elements above it. What would happen in this case? Would the positioned elements be placed over the header element, or cropped off?
mikeday
Adding padding with an @page rule is a convenient way of ensuring that body content keeps its distance from the page headers. It is possible to overlap with other content when negative margins are used, and some care is required in such cases.
whittaker007
There are certainly issues to consider when doing any kind of complex CSS layout. Removing options from the author is not usually the best way to go about standardisation though - unless you provide the user with a stylesheet rule to override that behaviour.

But just respecting the regular CSS box model should be enough. For the text in columns issue, if your columns all contained text in the same style then they would all have the same margins applied and would therefore line up. If you want your text to line up at the very top of the column without a top margin, don't apply a top margin to the paragraph style. If that causes some text to be too close to a preceeding element such as a table, then apply a bottom margin to that element.

It's really not that difficult to achieve the effect you want with CSS (unless you want to position content vertically, in which case CSS totally sucks - but that's beside the point). The point is, CSS gives you options. If you feel a new behaviour is so beneficial to the majority of users that it is worth making it a default behaviour, then you should provide a mechanism to revert back to "standard" behaviour. If you don't, you can cause more problems than are solved.