page-break-inside doesn't work in Chrome?
Asked Answered
G

16

51

I have a bunch of paragraphs on a page:

<p> ... </p>
<p> ... </p>
<p> ... </p>

The CSS rule for those paragraphs is:

p {
    margin: 20px 0;
    page-break-inside: avoid;
}

Live demo: http://jsfiddle.net/KE9je/2/show/

If I understand the page-break-inside property correctly, the above should ensure that no paragraph is split between two pages. (A paragraph is either displayed on the "current" page, or if it doesn't fit completely, it's moved to the next page.)

This doesn't seem to work in Chrome. Open the demo, right-click the page, choose "Print...". You'll see a print preview - the fifth paragraph is split between page 1 and 2.

What am I doing wrong? How can I make this work in Chrome?


Galactometer answered 9/10, 2011 at 20:57 Comment(5)
Which version of Chrome are you running? Your jsFiddle works for me. I'm on version 14.0.835.202 m.Cannikin
@TonyLeeper I have the same version.Mckinzie
@TonyLeeper I've updated my question with a picture. That paragraph is pushed onto the 2. page in your Chrome?Mckinzie
@Šime Vidas on my 14.0.835.202 m Chrome, it works fine though..Sheepcote
Yeah, but never mind I think my print settings are different to yours, and your example fitted on page1 for me. I made the paragraph bigger and can see the same problem as you now.Cannikin
T
48

Actually, it DOES work in Chrome, and the solution is really silly!!

Both the parent and the element onto which you want to control page-breaking must be declared as:

position: relative;

Check out this fiddle (or in fullscreen)

This is true for:

page-break-before
page-break-after
page-break-inside

However, controlling page-break-inside in Safari does not work (in 5.1.7, at least)

I hope this helps!!!

Terrier answered 12/9, 2012 at 10:54 Comment(11)
Actually, it seems that Chrome has implemented page-break-inside. My original demo (from my answer) works now in Chrome :DMckinzie
Indeed, page-break-inside does work in Chrome (as long as you don't declare position: absolute; on either the element or its parent, but it does not work in Safari (at least the 5.x versions) - Cheers!Terrier
I have no idea how you figured it out, but it solved the page break issues I had using wkhtmltopdf - thanks!Nobukonoby
It does not work for table rows (display:table-row); page-break-* works only for block elements (display: block). To avoid wrapping table rows, you must set the row as block and keep the cells as table-cell. But it breaks the table layout if there is not enough space. Alternatively you can try Flexbox (display: flex)Aisne
Does not work for me on a div despite the suggested CSS {display: block; position: relative;page-break-before: auto;page-break-after:auto;page-break-inside: avoid;}. There must be another nuanceResurrectionism
This still works for me... Note that the fiddle is in an iframe; you have to click the fullscreen link to the fiddle... @Stan: remember that the parent must also be position: relative; Terrier
FYI I had to add CSS to multiple parents for it to work, as my html structure is pretty complex. I added position: relative; page-break-inside: avoid; display: block; to every single element up the parent path until it fixed the problem. I progressively removed them once I solved it, in order to apply them only where they need to be appliedEscapade
I have tried adding position as relative but it is not working . may i know is there anything causing issue for this? ( working in firefox but no in chrome)Posehn
Seems like having display: flex doesn't support page-break-inside properties. Changing the display type to block worked for me!Cosimo
I have tried to add position: relative and display: block to all elements with their parents up to the body and it didin't work. Chrome is the new IE. :-/ edit: what did work was to set position: relative !important and display: block !important to all of those elements and then it worked.Mcmurry
Adding position: relative and display: block for all parent div elmens helped to avoid breaking images. A strange behaviour.Pepys
B
15

This worked best for me:

.no-page-break {
   display: inline-block;
   width: 100%;
   page-break-inside: avoid;
}

You can also specify the height if needed.

Bilander answered 14/12, 2018 at 12:47 Comment(4)
I just checked my original code in Chrome. It seems that this works now. Open this demo output.jsbin.com/ziruyoc/quiet in Chrome and check the print preview.Mckinzie
I'm using Bootstrap v3.3 and I was able to exclude the width: 100%; and this worked a TREAT! You are the manBaguio
display: inline-block; did it for me as Andrew Fox said. Bootstrap 4.5Susy
This solution to add display: inline-block worked for me. Thanks.Isopiestic
B
9

I've been fighting with this for a while and as well as follow the advice in the other answers I had to make sure that the element and all parent elements had the styling Display: block;.

Blazer answered 22/8, 2017 at 11:22 Comment(3)
Close, but I actually found that I needed display: inline-tableAxiom
After an hour wasted on various other sites and StackOverflow questions, this was it – the container of the element that I wanted to avoid breaking had display: flex;. I wouldn't have figured this out till the end of eternity on my own. Thanks!Antonetteantoni
@DánielKis-Nagy you're my savior. I spent an hour as well as you, and replacing display flex to float: left helped me, everything is working now. Thank youIvoryivorywhite
D
6

I know this is an old question but Chrome has changed since it was originally answered and this may help.

It looks like page-break-inside:avoid works in Chrome based on the height of the element, so if you are floating a bunch of elements in a div, page-break-inside:avoid will not work.

It's possible to get around this by explicitly defining the height the element you don't want broken up. jQuery example:

$('#page_break_inside_avoid_element').height($('#page_break_inside_avoid_element').height());
During answered 17/9, 2015 at 23:41 Comment(6)
“height of your desired element” - Which one, the paragraphs which I don’t want to be broken up, or their container element?Mckinzie
@ŠimeVidas - clarified per your comment.During
I’ve made a new demo: output.jsbin.com/fuvazi/quiet From what I can tell, page-break-inside: avoid works in Chrome now. I did not specify any heights.Mckinzie
Yeah that will work fine. I'm talking about cases where the page-break-inside: avoid is a div that has other divs inside it, and those inside divs are floated.During
Hm, I wouldn’t float in a print layout, at least not the main paragraphs. If the page uses floats, I’d revert them in the print stylesheet.Mckinzie
I found I had similar issues, which seemed to come from the fact that some elements had a fixed height. Setting the height to 'auto' for print seemed to fix the issue.Mercie
H
5

According to SitePoint, Chrome is not supported here, only Opera (and IE 8 buggy)...

http://reference.sitepoint.com/css/page-break-inside

Other references:

http://www.webdevout.net

http://www.reddit.com/r/css/comments/jdeim/pagebreakinside_avoid_doesnt_work/

Stack Overflow threads:

Cross-browser support of `page-break-inside: avoid;`

"page-break-inside: avoid "- does not work

Google Chrome Printing Page Breaks

Which browsers support page break manipulation using CSS and the page-break-inside element?

Google Chrome Forum:

http://www.google.com/support/forum

I will not post the W3Schools link (due to general unreliability) but they also state it's only supported in Opera, for whatever it's worth.

Harbaugh answered 9/10, 2011 at 21:5 Comment(10)
"Chrome versions up to and including 3 don’t support this property."Cannikin
The first link tests Chrome 2 (it's now on version 14) and the second link makes no mention of Chrome.Squamosal
The Wiki Comparison page says it's implemented in Webkit: http://en.wikipedia.org/wiki/Comparison_of_layout_engines_(Cascading_Style_Sheets)Mckinzie
@ŠimeVidas: Definitely, others report it working here: #1631319Squamosal
@Šime Vidas, your experience seems to indicate that the MDN is mistaken.Harbaugh
@Šime Vidas, What explains reputable sources saying that only Opera (and maybe IE 8) support this?Harbaugh
@ŠimeVidas - Does seem to need a page-break-after: setting.Curculio
@ŠimeVidas, I found a possible workaround on the Chrome Wiki for version 14 by adding margin: 0px;. See my updated answer.Harbaugh
@Sparky672 But I don't want page-break-after: always for each paragraph. That would result in only one paragraph per page...Mckinzie
@ŠimeVidas, Yeah, it's not looking good for a solution. Lots of complaints about it but no practical workarounds.Harbaugh
A
5

I recently worked on the pdf download story which was having dynamic rows of data in table format which include various charts images(tech used=>Angular + Spring + Thymleaf + Puppeteer) Some of the key points for handling page-breaks

  1. Try to use <div></div>blocks instead of HTML tables

  2. Do not use display: flex on the parent container on which you want page-break-inside: avoid(use float in child element)

    .child1{ float: left; }

3.If you are rendering div in loop and page-break-inside: avoid; not working You should use this CSS hack to work on a particular div

<div class="parent-container">
<div class="child1"></div>
<div class="child2"></div>
</div>
.parent-container{
 position: relative;
 page-break-inside: avoid;
} 
.parent-container::after {
content: "";
display: block;
height: 200px;
margin-bottom: -200px;
}
Anorthosite answered 4/7, 2021 at 16:40 Comment(0)
C
3

Check if the parent container display is not inline-block!! If so, then it will never work! I waste few hours to figure it out.

Works in Chrome 87

Crouse answered 19/1, 2021 at 9:14 Comment(0)
C
2

For Bootstrappers, be aware that page-break-inside or others may not (highly) work under container or row or other classes of bootstrap even if you change manually the position property. When I exclude container and row, it worked like a charm!

Coact answered 24/12, 2018 at 14:17 Comment(0)
P
2

I solved it: my problem was "a" parent div (not "the" parent div) set as display: flex.

I set it to display: block and it works.

Pushball answered 23/3, 2021 at 10:30 Comment(0)
C
1

I just tested this with a larger paragraph in IE9, Chrome 14 and Firefox 7, and it looks like only IE9 works as expected. You might have to resort to adding page breaks manually where you want them with

page-break-after:always

Of course that's only any good to you if you know the content length in advance.

Cannikin answered 9/10, 2011 at 21:36 Comment(2)
I'm baffled why Chrome and Firefox wouldn't implement this. It's such an old feature...Mckinzie
@ŠimeVidas Yeah, weird eh. The spec here w3.org/TR/css3-page/#allowed-pg-brk suggests it should work. In fact Chrome and Firefox appear to violate Rule D since p is a block level element.Cannikin
R
1

What worked for me (in both FFox & Chrome, that is)

.container {
  column-gap: .4em;
  columns: 3;
  padding: .4em;
}

.contained {
  page-break-before: avoid;
  page-break-inside: avoid;
  page-break-after: always;
}

And that's it ; I didn't need position.

Redbug answered 7/3, 2018 at 2:2 Comment(0)
S
1

check if the parent(or top level container) display is flex ; remove it and try again; it works for me in chrome71

Sinnard answered 14/12, 2018 at 6:27 Comment(1)
I confirm that this works.Freeloader
I
1

Here is how I solved this while writing a css for printing.

For example, you put some pictures in an HTML file like this:

<div class="bottom">
    <figure>
        <img src="img01.jpg" alt="Front View">
        <figcaption>Front View</figcaption>
        </figure>
    <figure>
        <img src="img02.jpg" alt="Rear View">
        <figcaption>Rear View</figcaption>
    </figure>
</div>

And write the css like this:

.bottom figure{
  page-break-inside: avoid;
}

Sometimes it won’t work as you expect, because the default value of display for most elements is block or inline, which is not ‘page-break friendly’. I usually change it like this:

.bottom{
    display: contents;
}

This aims to disappear the container, making the child elements children of the element the next level up in the DOM.

As for your question, I suggest you to have a look at the display mode of the container of the paragraph to see whether it is set to block. If so, change it to contents and try again.

I hope this help.

Italia answered 7/10, 2019 at 4:12 Comment(1)
what if i use display: flex in top container?Neritic
H
1

After a huge digging, it seems to be a very silly, annoying and simple issue. The key to fixing this issue is:

First, let's define what's parent and child.

  • Child: It's the element that we need to prevent/avoid cutting through in-between pdf pages
  • Parent: It's the direct parent/container of the child

Now we have the parent and the child very obvious, the next step is to give both parent and child some easy-to-implement rules. so let's do that

  • Parent rules

    display: block;

  • Child rules

    display: block; position: relative: page-break-inside: avoid;

That's it!

Headquarters answered 15/12, 2021 at 16:25 Comment(0)
B
0

It Works for me, like this:

.print{position: absolute;}
.print p{page-break-inside: avoid}
Barrus answered 1/7, 2016 at 19:28 Comment(0)
H
0

Also page-break-inside: avoid may not work if one of parent elements has fixed height (say height: 1000px). I guess that's because browser is trying to fit content in specified height first and only then thinks about page breaking.

Changing to height: 100% fixed it for me.

Hewlett answered 16/4, 2021 at 10:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.