30

I have a print stylesheet for my (Wordpress) site, and I want images to print on a single page rather than being split across pages. In some cases, even lines of text are being split across pages. I've included img {page-break: avoid;) in my print stylesheet, but no luck. I've found some previous answers but they're kind of old.

Is there a reliable way to print a moderately-sized image on a single page rather than splitting it across pages? Why are lines of text breaking across pages?

picture broken across two pages

lines breaking across pages

Site: http://74.220.217.211/housing-developments/grafton-townhomes/

Related posts:

Community
  • 1
  • 1
Katie Fritz
  • 883
  • 2
  • 9
  • 14

6 Answers6

25

It could be that the parent element of the img element has style:

display: flex

Then the break-inside doesn’t work.

For example if you change parent element display style to:

display: block

Then it will work.

Kristjan Retter
  • 411
  • 5
  • 11
  • 1
    Oh! What a peculiar gotcha! If you have a reference link, it would be helpful. – mike Sep 11 '20 at 17:09
  • Never thought about this!! Also check this thread for alternative solution for display:flex https://stackoverflow.com/questions/20408033/how-to-get-page-break-inside-avoid-to-work-nicely-with-flex-wrap-wrap Thanks – Jimmy Feb 18 '21 at 10:36
  • Just fyi - `display:flex` can cause issues but not guaranteed to be a problem. Also, `display:grid` also can cause issues – bendytree Oct 29 '21 at 16:27
21

Different browsers have weird limitations for page-break-inside: avoid. Following limitations have been suggested in different articles:

  • If the document tree has the parent or grandparent with display:flex or display:grid, avoiding page-breaks will not work.
  • If the parent element has display:inline-block, avoid doesn't work.
  • In some cases, parent element needs position:relative for the value avoid to work in children. (Exact rules unknown.)
  • In some cases, both the parent element and the element that needs to avoid breaking needs position:relative for the value avoid to work. (Exact rules unknown.)
  • The parent element MUST NOT have display: inline-block.
  • The element MUST NOT have display:table-cell.

In short, @media print styles should probably avoid using float, flex, grid, position:absolute and position:sticky if you need to use page-break-inside: avoid. For best compatibility with different browsers, try to define whole tree from root to parent with display:block and the element that shouldn't break with display:inline-block in addition to page-break-inside: avoid.

None of the above exceptions are part of any specs so these are just bugs or limitations in browser implementations.

Also note that even though latest specs prefer break-inside: avoid instead of page-break-inside: avoid the real world browser supports is still pretty bad. I would recommend declaring both:

.nobreak
{
  page-break-inside: avoid;
  break-inside: avoid
}
Mikko Rantalainen
  • 14,132
  • 10
  • 74
  • 112
  • See also: https://www.smashingmagazine.com/2019/02/css-fragmentation/ – Mikko Rantalainen Mar 24 '21 at 08:49
  • See also: my hack for keeping headers on the same page with the following content https://stackoverflow.com/a/68268825/334451 – Mikko Rantalainen Jul 15 '21 at 17:00
  • Another limitation for your list is: When parent /and/ child declare "page-break-inside: avoid" only the child is kept on one page; the parent will undergo a break. – jifb Feb 17 '22 at 14:15
  • If parent, however, has `overflow: auto` additionally to `page-break-inside: avoid`, parent has sane break avoidance (independend of (grand)child) but margin-collapsing doesn't work any more (see https://stackoverflow.com/a/34755272/12227050). – jifb Feb 17 '22 at 14:24
  • @jifb: which browser and which version number you had? – Mikko Rantalainen Feb 17 '22 at 19:07
  • 1
    Browser is: wkhtmltopdf 0.12.6 (with patched qt). This internally has Qt4 Webkit Engine (ten years old) see https://wkhtmltopdf.org/status.html (But still useful and there are still people contributing - see: https://github.com/wkhtmltopdf/wkhtmltopdf/pull/5167) – jifb Feb 21 '22 at 08:20
  • Thanks for the information. I tried to use `wkhtmltopdf` but it had so much problems with modern web pages that we're nowadays using Electron based version. See e.g. https://github.com/fraserxu/electron-pdf – Mikko Rantalainen Feb 21 '22 at 09:08
  • "Following limitations have been suggested in different articles ..." proceeds to not link to a single article ... – spinkus Jan 12 '23 at 05:53
  • The spec do specifies some of the limitations mentioned, for example the inline block exception for parents. See *Applies to* in https://drafts.csswg.org/css-break-3/#propdef-break-inside – Gruber Jul 07 '23 at 17:17
  • Yes, that lists some exceptions but real world user agents have *a lot more* exceptions. – Mikko Rantalainen Jul 10 '23 at 08:31
1

I think the problem may come from the position property of elements. The element you don't want to break at page end and its parent should be declared as:

position: relative;

The rest of code styles is right and should looks like

@media print {
    img {
        page-break-before: auto;
        page-break-after: auto; 
        page-break-inside: avoid;
        position: relative;
    }
}
0

Try this:

.site-container, .site-inner (heck body tag possibly) {position:relative;}

p {
    page-break-inside: avoid;
    position: relative; 
}

Check this FIDDLE

Add that in your print media

I just review this in Chrome and it looks fine minus the image which also needs this:

img {
    page-break-before: auto;
    page-break-after: auto; 
    page-break-inside: avoid;
    display: block;
}

Lastly Wordpress has this but in reality not sure if it helps...

 <!--nextpage-->
Riskbreaker
  • 4,621
  • 1
  • 23
  • 31
0
img {
    page-break-before: auto;
    page-break-after: auto; 
    page-break-inside: avoid;
    display: block;
}

this will work

Paulo Mendonça
  • 635
  • 12
  • 28
  • 4
    Welcome to Stack Overflow. When answering a four year old question with three other answers it is useful to point out what new aspect of the question your answer addresses and to acknowledge if the passage of time has made new answers possible. In this case your answer is very similar to an existing answer, but is code only, lacking explanation, and it doesn't have details that the other answer has like the use of `@media print {` – Jason Aller Mar 05 '20 at 18:32
0

Use @media print and set a suitable height for the page body element or set small size for the image

For example:

@media print{
body{
height: 800px;
}
}
Mohamed Saad
  • 368
  • 3
  • 8