_[email protected] commented:_
Which version of PhantomJS are you using?
1.6.0
What steps will reproduce the problem?
- Edit pageBreakAvoid.coffee to point to a local pageBreakAvoid.html
- Run the pageBreakAvoid.coffee script with CasperJS v1.0.0-RC1
- Open the resulting phantomjs-pageBreakAvoid.pdf
What is the expected output? What do you see instead?
The "bar" div should not be split between the first page and the second; it should start on the second (it should look similar to the chrome PDF). Instead, it's split in the middle.
Which operating system are you using?
PhantomJS is running on Ubuntu 12.04, and the Chrome that produced the comparison PDF is running on OSX 10.7.3
Did you use binary PhantomJS or did you compile it from source?
I downloaded the 1.6.0 binary release.
Please provide any additional information below.
Safari 5.1.3 also exhibits this problem, but Chrome 20.0.1132.47 does not.
It looks like there's a patch for WebKit that hasn't made it in yet:
https://bugs.webkit.org/show_bug.cgi?id=5097
This looks tangentially related, but I haven't found a clear "add this feature" but in Chromium:
Disclaimer:
This issue was migrated on 2013-03-15 from the project's former issue tracker on Google Code, Issue #638.
:star2: 10 people had starred this issue at the time of migration.
_[email protected] commented:_
Found this, which implies that this was fixed in webkit in 2010:
https://bugs.webkit.org/show_bug.cgi?id=34080
However, given the behavior of Safari, I suspect that's not actually true.
+1 - I'm seeing this same problem on MacOS 10.7.5 with phantomjs 1.8.2. Sample test html document pasted below:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>title</title>
<style>
p {
page-break-inside: avoid;
border: 1px solid black;
}
</style>
</head>
<body>
<p>But the probability of making a six is no greater than that of rolling a seven. Flair is what marks the difference between artistry and mere competence. Some days you get the bear, and some days the bear gets you. Yes, absolutely, I do indeed concur, wholeheartedly! When has justice ever been as simple as a rule book? Your shields were failing, sir. I'm afraid I still don't understand, sir. Your head is not an artifact! Commander William Riker of the Starship Enterprise. They were just sucked into space. I guess it's better to be lucky than good. Congratulations - you just destroyed the Enterprise. The look in your eyes, I recognize it. You used to have it for me. Our neural pathways have become accustomed to your sensory input patterns. We have a saboteur aboard. I am your worst nightmare! You enjoyed that. The game's not big enough unless it scares you a little. I recommend you don't fire until you're within 40,000 kilometers. The Enterprise computer system is controlled by three primary main processor cores, cross-linked with a redundant melacortz ramistat, fourteen kiloquad interface modules. What? We're not at all alike! I suggest you drop it, Mr. Data. When has justice ever been as simple as a rule book?</p>
<p>But the probability of making a six is no greater than that of rolling a seven. Flair is what marks the difference between artistry and mere competence. Some days you get the bear, and some days the bear gets you. Yes, absolutely, I do indeed concur, wholeheartedly! When has justice ever been as simple as a rule book? Your shields were failing, sir. I'm afraid I still don't understand, sir. Your head is not an artifact! Commander William Riker of the Starship Enterprise. They were just sucked into space. I guess it's better to be lucky than good. Congratulations - you just destroyed the Enterprise. The look in your eyes, I recognize it. You used to have it for me. Our neural pathways have become accustomed to your sensory input patterns. We have a saboteur aboard. I am your worst nightmare! You enjoyed that. The game's not big enough unless it scares you a little. I recommend you don't fire until you're within 40,000 kilometers. The Enterprise computer system is controlled by three primary main processor cores, cross-linked with a redundant melacortz ramistat, fourteen kiloquad interface modules. What? We're not at all alike! I suggest you drop it, Mr. Data. When has justice ever been as simple as a rule book?</p>
<p>But the probability of making a six is no greater than that of rolling a seven. Flair is what marks the difference between artistry and mere competence. Some days you get the bear, and some days the bear gets you. Yes, absolutely, I do indeed concur, wholeheartedly! When has justice ever been as simple as a rule book? Your shields were failing, sir. I'm afraid I still don't understand, sir. Your head is not an artifact! Commander William Riker of the Starship Enterprise. They were just sucked into space. I guess it's better to be lucky than good. Congratulations - you just destroyed the Enterprise. The look in your eyes, I recognize it. You used to have it for me. Our neural pathways have become accustomed to your sensory input patterns. We have a saboteur aboard. I am your worst nightmare! You enjoyed that. The game's not big enough unless it scares you a little. I recommend you don't fire until you're within 40,000 kilometers. The Enterprise computer system is controlled by three primary main processor cores, cross-linked with a redundant melacortz ramistat, fourteen kiloquad interface modules. What? We're not at all alike! I suggest you drop it, Mr. Data. When has justice ever been as simple as a rule book?</p>
<p>But the probability of making a six is no greater than that of rolling a seven. Flair is what marks the difference between artistry and mere competence. Some days you get the bear, and some days the bear gets you. Yes, absolutely, I do indeed concur, wholeheartedly! When has justice ever been as simple as a rule book? Your shields were failing, sir. I'm afraid I still don't understand, sir. Your head is not an artifact! Commander William Riker of the Starship Enterprise. They were just sucked into space. I guess it's better to be lucky than good. Congratulations - you just destroyed the Enterprise. The look in your eyes, I recognize it. You used to have it for me. Our neural pathways have become accustomed to your sensory input patterns. We have a saboteur aboard. I am your worst nightmare! You enjoyed that. The game's not big enough unless it scares you a little. I recommend you don't fire until you're within 40,000 kilometers. The Enterprise computer system is controlled by three primary main processor cores, cross-linked with a redundant melacortz ramistat, fourteen kiloquad interface modules. What? We're not at all alike! I suggest you drop it, Mr. Data. When has justice ever been as simple as a rule book?</p>
<p>But the probability of making a six is no greater than that of rolling a seven. Flair is what marks the difference between artistry and mere competence. Some days you get the bear, and some days the bear gets you. Yes, absolutely, I do indeed concur, wholeheartedly! When has justice ever been as simple as a rule book? Your shields were failing, sir. I'm afraid I still don't understand, sir. Your head is not an artifact! Commander William Riker of the Starship Enterprise. They were just sucked into space. I guess it's better to be lucky than good. Congratulations - you just destroyed the Enterprise. The look in your eyes, I recognize it. You used to have it for me. Our neural pathways have become accustomed to your sensory input patterns. We have a saboteur aboard. I am your worst nightmare! You enjoyed that. The game's not big enough unless it scares you a little. I recommend you don't fire until you're within 40,000 kilometers. The Enterprise computer system is controlled by three primary main processor cores, cross-linked with a redundant melacortz ramistat, fourteen kiloquad interface modules. What? We're not at all alike! I suggest you drop it, Mr. Data. When has justice ever been as simple as a rule book?</p>
<p>But the probability of making a six is no greater than that of rolling a seven. Flair is what marks the difference between artistry and mere competence. Some days you get the bear, and some days the bear gets you. Yes, absolutely, I do indeed concur, wholeheartedly! When has justice ever been as simple as a rule book? Your shields were failing, sir. I'm afraid I still don't understand, sir. Your head is not an artifact! Commander William Riker of the Starship Enterprise. They were just sucked into space. I guess it's better to be lucky than good. Congratulations - you just destroyed the Enterprise. The look in your eyes, I recognize it. You used to have it for me. Our neural pathways have become accustomed to your sensory input patterns. We have a saboteur aboard. I am your worst nightmare! You enjoyed that. The game's not big enough unless it scares you a little. I recommend you don't fire until you're within 40,000 kilometers. The Enterprise computer system is controlled by three primary main processor cores, cross-linked with a redundant melacortz ramistat, fourteen kiloquad interface modules. What? We're not at all alike! I suggest you drop it, Mr. Data. When has justice ever been as simple as a rule book?</p>
</body>
</html>
+1 Would also like to see this fixed
This was pretty much a deal breaker for me. A lot of the content is being cut off in the headers/footers.
I found that setting * {overflow: visible;}
fixed a lot of my issues. And then I implemented a horrendous Javascript hack which seems to work... for now.
page.open(system.args[1], function (status) {
page.includeJs('http://code.jquery.com/jquery-1.10.0.min.js', function() {
page.evaluate(function() {
// I couldn't figure out how to get this value programatically.
// To get it, print out a page while logging jQuery(document).height().
// You can get this value from (jQuery(document).height() / number_of_pages).
var height_per_page = 518.57;
// When items get cut off, the DOM shows the item as being very close
// to the top of the next page. So if we make the elements have a minimum
// distance from the top, we can add a page break before the element.
// You'll probably have to muck around with this value to get it to
// work.
var minimum_distance_from_top = 90;
// Select whatever elements you want to stop from being cut-off
jQuery('.crayon-syntax').each(function() {
// Distance from top of the first page.
var offset_top_document = jQuery(this).offset().top;
// Distance from top of current page.
var offset_top_page = offset_top_document % height_per_page;
if (offset_top_page < minimum_distance_from_top)
jQuery(this).css('page-break-before', 'always');
});
});
page.render(system.args[2]);
phantom.exit();
});
});
+1 please fix this
I came up with a much simpler method than @jkz88 's:
.unbreakable
{
/* page-break-inside: avoid !important; <-- doesn't work*/
display:inline-block;
}
.unbreakable:after
{
display:block;
height:0px;
visibility: hidden;
}
The reasoning behind is that webkit already tries to preserve images from breaking. And images are inline-blocks.
After transforming your block into an inline-block the only thing you need is to force a carriage return.
update: the newline forcing doesn't work, but you get the point :)
Ah great, that's much better. Thanks :+1:
+1 . Reproducible in 1.9.1 (Ubuntu 12.04)
+1 Tested with the fix that @tacone provided. It helps but there are still some problems.
This should also make the newline forcing work:
.unbreakable {
display:inline-block;
}
.unbreakable:after {
content: '';
display:block;
height:0px;
visibility: hidden;
}
I can't get the css fixes from ximi or tacone to work with my layouts. The odd thing is the page is cutting _correctly_ when rendered in Safari 7.0.1 (9537.73.11) and printed, but not in Phantom JS 1.9.7. Any ideas?
+1. We have hit this problem too. Really affects PhantomJS viability for doing PDF output of dynamic content. We will use the display: inline-block hack for now, thanks @tacone.
+1. Would love to see this fixed
+1 the various page splitting issues are the only problems I have with PhantomJS
+1. Please fix the issue. It is quite difficult to print Charts to PDF.
Reproduced 1.9.7 and UbuntuServer 12.04
+1 Please fix this, can't make highcharts work. I've changed my css for media type print, so when i press control+p chrome shows page breaks where needed, but phantomjs doesnt...
Just built from source and its fixed :)
@j040p3d20 I've tried the build on windows. My issue was not fixed. Would you please send me the build if you were on windows too?
@shuaishuai I built it today for windows for the same reason. Here is the link. Just make sure you pack it with something like UPX or that nature because now it's 19Mb
@AndrX thanks for the help! I've tried your build and still bugged. Then I did some research and found out that PhantomJS used a hardcoded ppi of 72. It was where a lot of bugs came from on Windows. I've hardcoded it to 96 and build it myself and it works.
@shuaishuai Thanks, I'll try it.
Don't work, I've tried the build on ubuntu 12.04 !!
+1 :grinning:
MacOS 10
phantomjs 1.9.7
casperjs 1.1.0-beta3
Just to clarify, compiling the head version did get me some improvements on some situations, but not in others... this sees to be a work in progress.
tacone + ximi's css tricks worked for me. Thanks!
@ariya is 2.0 release actualy fix this issue ?
houston, we have a problem.. any idea when this will be fixed? :8ball:
Seriously? Why is it broken here but fixed in chrome?
Can we recompile phantomjs with a newer webkit or is it not that simple somehow?
I was having issues with page breaks in a table with many rows and the problem for me was that I had overflow set to visible.
Changed
* {
overflow: visible;
}
to
* {
overflow: hidden;
}
and the problem seems to go away, no more content cut-off at the margins.
I'm using Phantom v 1.9.7
Ximi works great!!
Thank you so much
What's the status of this in 2.0 ?
Using examples/rasterize.js and the test html file from @gabehollombe, this appears to be fixed in PhantomJS 2.0. 2.0 includes a major update to Webkit, so that's consistent with this having been fixed there in 2010.
(We are painfully aware of how hard it is to update PhantomJS to newer Webkit and we are looking into solutions.)
@zackw good news ! let's wait for 2.0.1 and this will be fixed in CasperJS ;)
Any solution for v2? It's making things unusable.
The unbreakable css hack didn't work for me. But changing it to this did.
.unbreakable {
display: table;
}
the display inline block did not work for me, I am using phantomjs 2.0. Also, do you still need to set page.paperSize in phantomjs script even when you are setting page breaks in css? I really appreciate it if somebody could help me. I am trying to generate pdf reports and this is the last bit of the puzzle!
@tacone solution works for me
Good hack "The reasoning behind is that webkit already tries to preserve images from breaking. And images are inline-blocks."
Thought i would add another solution just until a fix makes its way into a binary.
I managed to get page-break-before/after and inside to work in conjunction with _CSS3 Regions_. The browser support is pretty terrible, however by chance PhantomJS supports this.
The bread and butter of CSS3 Regions are the following CSS statements.
-webkit-flow-from: flow-1-test;
-webkit-flow-into: flow-1-test;
You will need to look into css3 regions documentation for how these work (although its not particularly difficult).
This approach is tricky with dynamic content because we don't know how many pages we are going to need. The good news is i have already spent hours for you guys checking compatibility with different aspects of the CSS3 Regions Specification.
In my implementation i created more regions than i will possibly need, and then i used javascript to remove the ones that were empty. However i have also included some code to show you how to implement a solution where you can dynamically create new regions as they are needed. I decided not to do this as i needed the pdf to generate as fast as possible and it seemed logical that the removal option is faster (however i did not test this).
I used markup similar to this in order to add regions (you want to ensure you have _MORE_ pages than needed).
<section class="rendered_to_page container">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</section>
.rendered_to_page div {
-webkit-flow-from: flow-1-test;
height: 363mm;
page-break-inside:avoid;
}
This css was used to style the regions to fit on a page (this will need modification based on your individual needs).
I then used this javascript in my config.js (phantomjs) to remove additional pages.
page.evaluate(function () {
// Cull extra pages :)
var flow = document.webkitGetNamedFlows()['flow-1-test'];
var offset = flow.firstEmptyRegionIndex+1;
var regions = document.querySelectorAll('.rendered_to_page div:nth-child(n+'+offset+')');
for (i = 0; i < regions.length; i++) {
regions[i].style.display = 'none';
}
});
Alternatively you could do the opposite and create pages if there is overflowing content (this is untested).
As you can see in this implementation method we start with 1 regions. This is going to be a preferable method when an educated guess _cannot_ be made about how many pages there are likely to be in your document.
In contrast, in this solution we only start with 1 div (At minimum you will always have 1 page).
<section class="rendered_to_page container">
<div></div>
</section>
The Javascript will be almost the same as the above section. However you would do something similar to the following to detect when more regions are needed.
while (flow.firstEmptyRegionIndex == -1) {
var region_container = document.querySelector('.rendered_to_page');
var newRegion = document.createElement('div');
region_container.appendChild(newRegion);
}
I can also forsee you would need to remove the last region (this is a guess as i did not test this method).
.rendered_to_page div:last-child {
display: none;
}
I found this solution had less issues than the above suggested solutions for very large documents where more control over page breaks were required.
For either solution, your probably going to need some sort of delay to allow PhantomJS to completely finish all of this logic before creating a pdf. You will not have enough time for the script to run before the render (please experiment with these values until they work).
setTimeout(function() {
page.render(output);
phantom.exit();
}, 10);
Ensure your main content is
display: block;
as only block elements can have page-break-* styles applied.
Hope this helps someone :)
ps. this was tested on PhantomJS 2.1.1
I had the same issue. I was fixed by the display: inline-block
method. But keep in mind, that if the elements you want to break to new pages has a parent that's also inline-block
then it won't work. Cost me some time to realize :)
phantomj 2.1 - had the same issue with page-break-inside:avoid, fixed it by creating the table dnamicly and calculate the height each row with dynamicly add page-break-after on new div table
phantomjs-2.1.1-linux-x86_64 in centos still not work (both inline-block & page-break-inside: avoid;)
I have a table with large amount of data. I tried using the css suggested by @tacone :
.unbreakable
{
/* page-break-inside: avoid !important; <-- doesn't work*/
display:inline-block;
}
.unbreakable:after
{
display:block;
height:0px;
visibility: hidden;
}
I tried defining the class=unbreakable over table, tr and td. But did not work.
+1 This seems to still be an issue in v2.1.1 on Ubuntu 16.04 and Ubuntu 14.04. I attempted the the ".unbreakable" CSS suggested by @tacone with no luck.
+1 Using phantomjs-2.1.1-linux-x86_64.tar.bz2 .unbreakable class does not help.
+1 I'm using phantom v2.1.1 and still getting weird splits on a Mac.
:+1: Still having this issue
Thanks @drdla I changed your code a bit so that the final layout actually stays the same without being distorted:
body > * { width: 99.999%; zoom: .999; }
After adding the snippet above, I added the snippet below to all elements that should be unbreakable.
.unbreakable { page-break-inside: avoid !important; }
This issue still exists on 2.1.1. page-break-inside
seems to have no effect on tables.
any update o page-break-inside on tables?
@skylarmb did you end up with a workaround?
@juergengunz I did not. :/ still waiting
any update about that?
Why is this issue closed? It hasn't been fixed, has it?
+1 Why was this closed? This is not fixed.
page-break-inside
seems to have no effect on tables.
FWIW, a workaround the helped me was to wrap the td content with a div:
css:
.avoid-break {
page-break-inside: avoid;
margin: 0;
padding: 0;
}
html:
<table>
<tr>
<td>
<div class="avoid-break">
<!-- content goes here -->
</div>
</td>
</tr>
</table>
How is it now?
@54huige Still an issue as far as I know. I've been migrating to Puppeteer implementations for document generation.
Most helpful comment
I came up with a much simpler method than @jkz88 's:
The reasoning behind is that webkit already tries to preserve images from breaking. And images are inline-blocks.
After transforming your block into an inline-block the only thing you need is to force a carriage return.
update: the newline forcing doesn't work, but you get the point :)