How are the page-break properties in CSS supposed to work? - css

Modern browsers are supposed to support the CSS page-break properties to some degree. However I haven't been able to get any browser to print any differently when I use avoid, widows, or orphans. Am I doing it wrong, or is the browser support just not as solid as advertised?
h2 {
page-break-after: avoid;
}
p {
page-break-inside: avoid;
orphans: 2;
widows: 2;
}

Browser support for printing sucks. Not just a little bit, but completely totally and without compare. About once every other year (for the past 10), I've played around with this and I always come back to the same conclusion: don't depend on the browser to be able to handle good printing.
If it absolutely must be positioned correctly, create a pdf file on the fly and let the user print that.

If you are wanting to do a page break I know that this is the way it works at least in Firefox and IE. Last time I checked this worked in IE7.
Page 1
<br style="page-break-after:always" />
Page 2
It should print the pages on separate pieces of paper, totally depending on the browser.

I know this will go against everything everyone says about html development, but use tables. Put content that needs to stay together into a table, and then the page will not be split in the middle of the table. If the table is longer than one page, then it will be split somewhere in the middle of the table, but using tables is a good way to keep content together when printing.

Related

Predictable and consistent cross-browser printing from HTML

I'm trying to figure out if there's a way to achieve sane printing straight from HTML. Our users often want to print a few pages for their own records. The printouts contain Google Charts and the grid is handled by bootstrap. Very frequently we want a set of content per page and thus page breaks are very much required.
Traditionally we've used print media queries, but it's been nigh impossible to achieve consistent results across browsers, say Firefox, Chrome and Mobile Safari etc. Pieces will spill over, page breaks will be ignored etc.
Some companies like Amazon and Newegg provide customers with the ability to print out invoices and other pages. It seems that usually that involves having a separate print-only version of the content that's either all tables or very simplified -based markup that looks extremely basic when printed out. Generally there's little to no styling, few if any images, definitely no and no page breaks as far as I can tell.
Another option is to just convert everything to PDF, but that has its own pitfalls and expenses. Now you have to re-generate the same content in a second format for every page that needs to be printed, and perfectly styling PDF is non-trivial as well.
Is there anything out there can can help with this? Any commonly accepted solutions?
We use wkhtmltopdf and PrinceXML to get consistent styling. Both are command line tools that can take a URL plus a custom CSS file. They generate consistent output, and are browser independent, because they are the rendering engine.
We used to use wkhtmltopdf, but we're starting to move to PrinceXML because it supports margin-boxes and two-column layout. (The main caveat with PrinceXML is the price.)
Perfectly styling PDF doesn't seem any worse or harder than styling for web display. My experience is that it takes an hour or two to get a print page styled correctly. I've never tried to handle Google Charts.
All of the popular desktop browsers now support the CSS #page rule for setting page margins, and the CSS properties page-break-inside, page-break-before, and page-break-after for handling page breaks. These will generally provide enough control to achieve consistent cross-platform printing, but there are a few things that only one or two of the browsers can do. Some examples are:
page numbering
running page headers and footers
orphan/widow control
control of background colors
If you need any of those things, PDF might be your best option; otherwise, it might be overkill. A PDF converter isn't going to automatically determine the ideal way to paginate whatever content you throw at it; human judgement will still be required.
That doesn't mean you need to explicitly declare the location of every page break, though. It's usually a lot easier to prevent bad pagination than to force good pagination. In other words, instead of telling the browser where you do want page breaks, tell it where you don't want them.
Examples of places you might want to prevent page breaks:
between a section title and the first line of section text
between a table's column headers and the first row of data*
between closely-related form fields.
The go-to CSS declaration in these situations is page-break-inside: avoid;**. It would be easier to use page-break-after: avoid; in the first two examples, but Firefox only supports the always and auto values for that property. So instead, you have to create an unbreakable div that contains or overlaps the stuff you want to keep together. Here's one way to do it:
<style>
.section {
line-height: 1.25em;
}
.title {
page-break-inside: avoid;
padding-bottom: 1.25em;
font-weight: bold;
}
.overlap {
margin-bottom: -1.25em;
}
</style>
<div class="section">
<div class="title">
Title of This Section
</div>
<div class="overlap">
</div>
This is the section text. It could be any length, so we have to
allow page breaks in it. However, we don't want the first line to
be separated from the section title. The title is unbreakable, so
we just need to add some bottom padding to it and make it overlap
the first line of text.
</div>
*Tables are probably the most challenging thing to print consistently across browsers, but it is possible.
**Old versions of Firefox, Chrome, and Safari don't support the CSS declaration page-break-inside: avoid;, but you can achieve the same effect with display: inline-block;, if needed.

CSS Compatibility IE7 - IE8 problem

Problem:
Thanks for taking the time to read this. I'm having a problem which I need to solve as simple as possible. There's a website I'm re-developing, but since I updated to IE8, I've totaly forgotten about IE7, but ofcourse, there are still people using it.
I need to know what specific things I should change for this site to display the same way as it does in IE8. But I don't know where to start. Is there anyone with experience in this, who can give me a guideline? Are there scripts for doing so?
URL: http://www.testsite.c-tz.nl/
If you view this with IE8 it looks perfect.
But if you view it with IE7, things are not where they supposed to be, very ugly.
As the other said, your question is to broad. You'll need to break it down in smaller problems - which will possibly help you solve it yourself along the way.
One thing I did notice: IE has problems with display: inline-block on elements, which were orignally block elements. Either use span (only possible if it doesn't contain block elements), or use another method to places blocks side by side such as float.
BTW, you have far too many divs in your HTML. It's not necessary to wrap every img, every ul, etc. in it's own div. Usually any styles you apply to the div can just as well be applied you the "wrapped" element directly.
This is not a cool idea... But you can try when you are sick with very old browsers like ie6 or ie5 ...
1.use javascript to detect the browser and version..
2.later use the similar way to redirect the visitor to download the IE 8..
<script>
if(''+browserName+''+fullVersion+'' == "Microsoft Internet Explorer6.0" )
{
alert("You're using an Old Browser.Update the browser to view the website.(or) Try Latest Google Chrome , Firefox , Safari, Opera")
window.location = "http://www.microsoft.com/download/en/details.aspx?id=43"
}
//document.write(''+browserName+''+fullVersion+'');
</script>

CSS: Explicitly declaring position, padding, margin, and overflow for every item?

I've been working for a guy whose been teaching me css. I made a website based on his designs which I'm pretty proud of, but he got back to me saying that I need to explicitly declare the padding, margin, position, and overflow (specifically every item should have "overflow:hidden") on every item. Is there any basis to this at all? Is there anything I can use to refute this? I thought that declaring something like div,span,h1,[...] {padding:0;margin:0;postion:static;overflow:hidden} would take care of everything due to the cascade.
Another resource, that I think is better for resetting CSS is YUI Reset (from Yahoo!). It has a great reset CSS file with additional files you can add on the end to make everything look consistent cross-browser (including fonts which can get very annoying very fast in CSS)
Here are the links
http://developer.yahoo.com/yui/reset/
http://developer.yahoo.com/yui/base/
http://developer.yahoo.com/yui/fonts/
I use the Reset, Base and Font stylesheets (in that order) in ALL my web projects.
Using a reset stylesheet that consists of "* { margin: 0; padding: 0; }" will create even worse cross-browser issues. You need to reset everything and THEN declare a base that all the browsers can start from (the purpose of reset.css and base.css).s
Except for increasing the CSS file size, there is no reason to explicitly declare common properties down a cascade if already declared on a generic item. The browser should take care of properly rendering the items, taking the cascade structure into account.
Blindly applying styles to every element will surely give you unwanted results, but you could nail everything with
* { margin: 0; padding:0; etc }
I would recommend using a reset stylesheet instead to reduce browser inconcistencies, this one is pretty popular: http://meyerweb.com/eric/tools/css/reset/
Note that reset stylesheets have their own (usually minor) issues with IE7. I usually create a separate IE7 only stylesheet.
I think you should use a CSS reset instead.
He is overly paranoid about cross browser differences. You do not need to do this.

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

I'm trying to use the page-break-inside CSS directive, the class of which is to be attached to a div tag or a table tag (I think this may only work on block elements, in which case it would have to be the table).
I've tried all the tutorials that supposedly describe exactly how to do this, but nothing works. Is this an issue of browser support or has anyone actually gotten this working, the exact bit of CSS looks like this:
#media print {
.noPageBreak {
page-break-inside : avoid;
}
}
Safari 1.3 and later (don't know about 4) do not support page-break-inside (try it, or see here: http://reference.sitepoint.com/css/page-break-inside). Neither do Firefox 3 or IE7 (don't know about 8).
In a practical sense, support for this attribute is SO spotty, it doesn't make sense to use it at all at this point. You'd be lucky if even 10% of your visitors have browsers that can support this.
The solution I used was to add
page-break-after:always
to certain divs, or add a "page-breaker" div in where you want breaks. This is quite ham-handed, I know, because it doesn't do quite what you want, and causes content to not reach the bottom of the printed page, but unfortunately there isn't a better solution (prove me wrong!).
Another approach is to create a stylesheet that removes all extraneous elements (display:none) and causes the main content to flow in one main column. Basically, turn it into a single column, text-only document.
Finally, avoid floats and columns when styling for printers, it can make IE (and FF) act wacky.
Safari 1.3+, Opera 9.2+, Konquerer, and IE8 all support it, at least to some degree.
Firefox apparently still does not.
Firefox does not support this as of 2010-11-30, and thus won't in Firefox 4.
IE8 does support page-break-inside: avoid - but when I tried this on IE9, it's not very successful at avoiding page-breaks (this may be a regression, or perhaps IE8 is also only capable of avoiding page breaks in very simple cases).
AFAIK it doesn't work in any webkit browser; certainly not in chrome.
It actually works in Opera, even on real sites.
Safari 1.3 and later support page-break-inside.
So does Konqueror.
I'm trying to use the page-break-inside CSS directive, the class of which is to be attached to a div tag or a table tag (I think this may only work on block elements, in which case it would have to be the table).
Firstly, there's no need to guess. Just look at the specification, and you'll see that it does indeed only apply to block-level elements.
Secondly, <div> elements are usually block-level elements, so there's no problem applying page-break-inside to a <div> element.
Finally, you don't need to wrap it in #media. You only need #media if you want to apply media-independent rules to only one medium, for instance, if you want to use display: block only for one medium. In this case, you don't need to hide those rules from other media, because they'll only apply to paged media anyway.
From preliminary searches, it's hard to find up-to-date statistics on browser support for this, but it seems that Firefox 4beta6 supports it and Chrome 7 does not. Chrome also breaks pages halfway through a line of text, so that part of the text appears on one page and part appears on the next. Uncharacteristic lack of attention to detail, but I guess neither Google nor Apple care about printing things.
Firefox 4 also adds some nice headers and footers to your prints with url, page title, site title, number of pages, and time. Nice.
As a bit more information further to Eamon Nerbonne's answer on the IE rendering (IE8+), you need to make sure the browser is in standards mode. This article on MSDN shows what is necessary - including a meta tag in your html to force the issue:
<meta http-equiv="X-UA-Compatible" content="IE=8" />
Feels kludgy, but there you have it... seems to work more consistently.

How to split a string (e.g. a long URL) in a table cell using CSS?

Here's the situation: I'm trying my hand at some MySpace page customisations. If you've ever tried [stackoverflow], I'm sure you understand how frustrating it can be.
Basically it can be all customised via CSS, within a certain set of rules (e.g. the '#' character is not allowed...how useful!).
Have a look at this blog if you want more info, I used it as the basis for my customisations
So the only problem is with the comments section, where 'friends' post whatever they feel like.
It already has...
max-width:423px;
...set on the table, but I've discovered if long URLs are posted in the comment section, it blows out the table width, regardless of the max setting!
Question: Is there a way to manage text that is going to push the width of the table?
Perhaps splitting/chopping the string? Or is there more I should be doing..?
The URLs are posted as text, not hrefs.
Using Firefox and Firebug btw.
Edit: Also javascript is not allowed ;)
Another edit Just checked with IE7, and it seems to work.. so firefox is being the hassle in this case..
Have you tried the various values for the "overflow" css property? I think that may do what you need in some permutation.
a few browsers support word-wrap
ex.
<div style="width: 50px; word-wrap: break-word">insertsuperlongwordhereplease</div>
browser support currently is IE / Safari / Firefox 3.1 (Alpha)
Your options are pretty limited, if you are using only CSS. You can try
overflow: hidden
to hide the offending parts. CSS 3 supports text-wrap, but support for it is probably non-existent. IIRC there is an IE-only css-property for doing the same thing, but I can't remember it at the moment and my Google-Fu fails me.

Resources