Page-break-inside:avoid not working
Asked Answered
D

6

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:

Dosi answered 30/12, 2015 at 17:29 Comment(3)
try adding position: relative to the parentChaschase
@riskbreaker, thanks! I'm not sure which parent to add that to though.Dosi
What browser are you using?Dixon
C
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.

Condottiere answered 22/1, 2020 at 10:52 Comment(3)
Oh! What a peculiar gotcha! If you have a reference link, it would be helpful.Indole
Never thought about this!! Also check this thread for alternative solution for display:flex #20408533 ThanksJokjakarta
Just fyi - display:flex can cause issues but not guaranteed to be a problem. Also, display:grid also can cause issuesGothurd
D
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
}
Despair answered 24/3, 2021 at 8:32 Comment(10)
See also: smashingmagazine.com/2019/02/css-fragmentationDespair
See also: my hack for keeping headers on the same page with the following content https://mcmap.net/q/333031/-how-do-i-avoid-a-page-break-immediately-after-a-headingDespair
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.Roberto
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://mcmap.net/q/500378/-css-margin-of-internal-div-extending-past-surrounding-div).Roberto
@jifb: which browser and which version number you had?Despair
Browser is: wkhtmltopdf 0.12.6 (with patched qt). This internally has Qt4 Webkit Engine (ten years old) see wkhtmltopdf.org/status.html (But still useful and there are still people contributing - see: github.com/wkhtmltopdf/wkhtmltopdf/pull/5167)Roberto
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. github.com/fraserxu/electron-pdfDespair
"Following limitations have been suggested in different articles ..." proceeds to not link to a single article ...Sublittoral
The spec do specifies some of the limitations mentioned, for example the inline block exception for parents. See Applies to in drafts.csswg.org/css-break-3/#propdef-break-insideLawtun
Yes, that lists some exceptions but real world user agents have a lot more exceptions.Despair
C
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;
    }
}
Crepe answered 21/8, 2017 at 8:21 Comment(0)
C
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-->
Chaschase answered 30/12, 2015 at 17:41 Comment(3)
Tried it, but no luck. Thanks.Dosi
Where are you putting this in your WP files?Chaschase
might want to check that theme - if you add at least the img tag on the print media and still get no results then might be more to the theme to implementChaschase
W
0
img {
    page-break-before: auto;
    page-break-after: auto; 
    page-break-inside: avoid;
    display: block;
}

this will work

Withers answered 5/3, 2020 at 16:39 Comment(1)
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 {Rib
F
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;
}
}
Fructuous answered 26/3, 2020 at 13:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.