Enforce Print Page Breaks with CSS - css

I have a page that basically displays all work orders for a given day. I have tried to create the HTML so that I can use page-break-after: always to create a logical print page break and continue on. However when the user prints the page, there are often overlaps, multiple work orders on the same page, etc. I simply want to enforce a hard page break that Firefox, Safari, and Chrome will listen to.
My HTML looks like this
<div class="WOPrint">
<div class="WOHeader">
<h1>Header stuff</h1>
</div>
<!-- content -->
</div>
<div class="WOPageBreak"></div>
<div class="WOPrint">
<div class="WOHeader">
<h1>Header stuff</h1>
</div>
<!-- content -->
</div>
<div class="WOPageBreak"></div>
<!-- repeat N times -->
<div class="WOPrint">
<div class="WOHeader">
<h1>Header stuff</h1>
</div>
<!-- content -->
</div>
<div class="WOPageBreak"></div>
and my CSS is basically like so:
.WOPrint
{
max-width: 100%;
padding-bottom: 3em;
}
.WOHeader
{
display: block;
page-break-inside: avoid;
}
.WOPageBreak
{
height: 1px;
width: 100%;
float: left;
page-break-after: always;
display: block;
}
EDIT
In a hackish attempt I have played around with setting the WOPrint class min-height. Changing it to 9 inches seems to give me enough margin room for printing from all Safari, Firefox, and Chrome when I have it set to a standard US paper size. This is certainly not the way I would like to fix it, but I also don't want to have to render to PDF.
.WOPrint
{
max-width: 100%;
padding-bottom: 3em;
min-heihgt: 9in
}

short answer. You can't it's not consistetly supported across all browsers. there is slightly better support for page-break-before than page-break-after though...
see page-break-before compatibility and page-break-after compatibility
you could also try embedding a Ctrl-L in the page at those points thought I'm pretty sure a lot of printer drivers are gonna ignore that.

By setting the min-height in the WOPrint CSS class I'm able to fake an approximate page break for a standard height page:
.WOPrint
{
max-width: 100%;
padding-bottom: 3em;
min-height: 9in;
}

All you need is
.WOPageBreak
{
page-break-before: always;
}
However, you'll also want to add "overflow:visible" to the body tag because without it Firefox will only print the first page.
You may also get more consistent results if you set margin:0 on the body when printing, like so:
#media print{body{margin:0}}

Related

My media queries are not working as expected

This is the markup of a web page I'm working on right now:
<section style="background-image: url(img/about-banner.jpg); height: 100vh; position: relative; background-size: cover;">
<div class="container" style="width: 90%;">
<div class="display-table">
<div class="table-cell" style="vertical-align: bottom;">
<div class="content about-header" style="margin-bottom: 20vh; margin-left: -2vw;">
<h1 class="text-white other-header-h1" style="font-size: 3.5vw;">Title Text</h1>
</div>
</div>
</div>
</div>
</section>
The two main areas of interest are
<div class="content about-header" style="margin-bottom: 20vh; margin-left: -2vw;"
and
<h1 class="text-white other-header-h1" style="font-size: 3.5vw;">Title Text
For screen sizes below 1025x I'm trying to make the font-size 5vw and margin-bottom: 30vh;
These are the media queries I put in responsive.css:
#media (max-width: 1024px) {
.header_section_fix {
font-size: 1.5vw;
}
.header_fix_links a {
margin-right: 3%;
}
.about-header {
margin-bottom: 30vh;
margin-left: -2vw;
}
.other-header-h1 {
font-size: 5vw;
}
In the above css, both .header_section_fix and .header_fix_links are working.
However the media queries for .about-header and .other-header-h1 do not work on the webpage.
Below are a few ways to isolate this issue for the fix:
Firstly get rid of all your inline styles, and put them in the external style-sheet. Your going to have a hard time getting your media queries to override inline styles.
Secondly, double check that your meta view-port is being defined properly in the head of your document.
Thirdly make sure there is no conflicts with these selectors and styles being defined elsewhere in the application. ie. If you are defining margin-top: with a selector somewhere else, then use margin-bottom: in your media queries; stuff like that (make sure you are consistent with css properties and not creating conflicts).
Fourthly, make sure your CSS is valid and there is no syntax errors. Also, try to match the order of the CSS selectors in the stylesheet with how they appear in the HTML.
Your last resort scenarios would be using !important; or enclosing in a separate, second media query instance; or rearranging where these selectors are being called in the stylesheet. These may work, but ultimately would be a reach around for some conflict.
Normal specificity rules apply.
The inline style has a higher specificity than the ruleset in the media query, so it overrides the value you want.
Move the value in the style attribute into the stylesheet.

How do I get rid of this horizontal scrollbar in Chrome and Safari?

How do i get rid of the horizontal scrollbar on this code: codepen? I'm seeing it in Safari and Chrome, but not Firefox.
I'm using bootstrap, and I've got roughly the following markup:
<div class="container">
<div class="row">
<div class="messages span6 offset1">
<table class="table">
<tbody>
<tr>
<td class=timestamp>[2:22 PM]</td>
<td>echo|</td>
<td>zot: Got a paste or gist of the code?</td>
</tr>
<!-- many more rows… -->
</tbody>
</table>
</div>
</div>
</div>
And styling:
.messages {
height: 200px;
overflow: auto;
}
.messages .timestamp {
min-width: 75px;
}
The problem seems to be the min-width constraint, but I need that to keep the first column from wrapping. I also need to limit the height of messages to 200 pixels. I can't set overflow-x: hidden on .messages because it'll cut off content.
How about this:-
Use word-break on the last column to avoid it cut off.
word-break
Demo
.messages {
height: 200px;
overflow-y: auto;
}
.messages .timestamp {
min-width: 75px;
}
.messages td:nth-child(3) {
word-break:break-all; /* or use word-break:normal; if you don't want to get the word cut in between*/
}
This will adjust the word-break based on the width available, without hiding the contents.
Use the following css:
.messages {
height: 200px;
overflow-y: scroll;
overflow-x: hidden;
}
.messages .timestamp {
min-width: 75px;
}
You could change the height property for .messages to "auto" instead of 200px.
You could increase the width of the table by changing its span6 to a span7, or use a span class to force a width on the message tds that is consistent with the Twitter bootstrap grid structure context.
I couldn't tell you exactly why this is necessary; I actually don't know much about how tables get laid out. But this seems like a solution you could deploy.
A completely alternate thought: why are you using tables to do this? You're not laying out tabular data; you have some semantically related pieces, but they're not tabular in their relationship. Given that, you're breaking one of the cardinal rules: don't use tables for layout! It looks to me like you could probably make this work much more sensibly using div elements, using either float or inline-block with specified widths on them. In that case, your markup would look something like this:
<div class="container">
<div class="row">
<div class="messages span6 offset1">
<div class="message">
<span class="timestamp">[2:22 PM]</div>
<span class="author">echo|</div>
<span class="messageContent">zot: Got a paste or gist of the code?</div>
</div>
<!-- many more rows… -->
</div>
</div>
</div>
Then, your CSS would be fairly straightforward, since you've defined the width value for the span6 (I looked at the actual CSS on the CodePen):
.message {
display: block;
clear: both;
}
.timestamp, .author, .messageContent {
display: inline-block;
vertical-align: top;
}
.timestamp, .author {
width: 75px;
}
.messageContent {
400px; /* You'd obviously need to tweak this down to account for any padding */
}
You shouldn't have the nasty overflow problems, and the divs should fill up their heights in perfectly normal ways. You can also bound them. And there's no overflow issue anymore.
(Perhaps you're where you are because it's something that bootstrap defaults to, in which case: UGH. Break it, or do whatever is necessary to get away from using tables for layout. It will always, always be more pain than it's worth, and it's unsemantic to boot.)

page-break-* doesn't work on Google chrome

I just like the divs under .wp_left_col div be placed in separate pages. This is my css code.
.wpi_left_col > div {
page-break-after: always !important;
page-break-inside: avoid !important;
}
It works on Firefox. How come it doesn't work on Google Chrome?
So, after some frustration, I found a solution. It's a hack, but Chrome doesn't support page breaks properly, so.. You have to set all of the parent elements to explicitly float: none. In this example, I'm printing tabbed content.
<body>
<main role="main">
<section class="tabs">
<div class="tabbed-content">
<div class="tab">print page 1</div>
<div class="tab">print page 2</div>
<div class="tab">print page 3</div>
</div>
</section>
</main>
</body>
Then your CSS looks similar to this.
html, body, .main-content, .tabs, .tabbed-content { float: none; }
.tab {
display: block; /* unhide all tabs */
break-before: always;
page-break-before: always;
}
It's July 2014, and as of today doing float: none; for all parent elements is what worked for me:
#media print {
table {float: none !important; }
div { float: none !important; }
.page-break { page-break-inside: avoid; page-break-before: always; }
.dont-print { display: none; }
}
This solution works on Firefox, Chrome and Safari. I have the !important in there because I'm using Bootstrap, and bootstrap does a float: left by default on divs.
3 years later float:none !important for div was the solution for getting the break working in chrome. Not necessary to float:none all parents (body or html)
#media print {
div {
float: none !important;
}
}
<div style="display: inline-block; "> has been reported as a way to avoid page-breaking in the middle of something, YMMV. Also, try removing borders, and ensure there are no floats. See also CSS Page-Break Not Working in all Browsers.
here's an easier solution for setting all parent elements to not float on print:
#media print {
* {
float: none !important;
}
.tab {
display: block;
break-before: always;
page-break-before: always;
}
}
Chrome has problems processing page-break-after, and page-break-inside this is a known bug and Google has said a few times to avoid using this type of styling since not only Chrome but many more browsers run into problems using it.
You should consider styling the tables thought DIV's rather than the tables themselves. Personally in this day and age its normally best to avoid using tables as they are not as flexible as DIV styling.
DIV styling as mentioned is more flexible and easy to work with and looks almost the same on all browsers since browsers tend to render tables differently across browers.
Here is a simple example of how to style the first table you have in DIV and is by far pixel perfect but should give you an idea. Almost the same with some improvement but without the font you use doesn't look as good, doesnt use image as the background which is ++ :P
CSS
#page {margin:0 auto;width:960px;padding:20px;background:#99deea;}
.myblock {background:#c1ebf2;padding:20px;border-radius:10px;}
.innerblock {width:33.3%;float:left;}
.innerblock h3 {font-size:20px;text-align:center;color:#424242;font-weight:bold;text-shadow:0 0 3px #FFFFFF;}
.innerblock h4 {font-size:14px;padding:10px 0 0 0;color:#778A2C;text-shadow:0 0 3px #FFFFFF;}
.innerblock p {font-size:16px;color:#7A8634;font-weight:bold;padding:0 0px 15px 75px;text-shadow: 0 1px 1px #FFFFFF;}
HTML
<div id="page">
<div class="myblock">
<div class="innerblock">
<h3>Spencer Hill</h3>
<h4>Recent Work:</h4>
<p>Example Work Number 1</p>
<p>Example Work Number 2</p>
<p>Example Work Number 3</p>
</div>
<div class="innerblock">
<h3>Becca Ward $500</h3>
<h4>Recent Work:</h4>
<p>Example Work Number 1</p>
<p>Example Work Number 2</p>
<p>Example Work Number 3</p>
</div>
<div class="innerblock">
<h3>Rachel Tourville $150</h3>
<h4>Recent Work:</h4>
<p>Example Work Number 1</p>
<p>Example Work Number 2</p>
<p>Example Work Number 3</p>
</div>
<div style="clear:both;"></div>
</div>
</div>
I've saved this code online for you to see and test, take a look at http://jsfiddle.net/tsd4V/
Again this is just a better method you can use table styling but don't use page-break if you want good cross browser compatibility.

equally spaced divs. Multiple rows

I have a list of video thumbnails displayed on page. Of course they don't fit in one line, so multiple lines are used and I would like them to be spaced equally (in other case layout look broken). My current markup is
.thumbs {
width: 76%;
float: left;
margin: 0px 1em;
text-align: justify;
background-color: #DEE;
}
.thumb {
display: inline-block;
text-align: left;
}
markup is:
<div class="thumbs">
<div class="thumb">
<img src="http://placehold.it/160x120">
<div class="title">Test</div>
</div>
<div class="thumb">
<img src="http://placehold.it/160x120">
<div class="title">Test</div>
</div>
<!-- and so forth... -->
</div>
Same in JsFiddle: http://jsfiddle.net/cPm9f/
Everything is ok except the last row: I expect it to be spaced as previous rows, but space differs :( I can't use a table or just stuff a bunch of invisible stub elements because this is a foundation for responsive design so amount of columns displayed will be dependent
on width of device screen.
Any ideas how to make the last row space equally to previous ones?
UPD: There's opinion by cimmanon that what I want should be implemented differently. If so then how?
Your problem is the interpretation of text-align: justify. The last line is commonly not justified, because if the last line is rather short, the letters would need to have an absurd spacing.
Workaround:
text-align: justify;
text-align-last: justify;
But to my knowledge text-align-last is only supported by IE [EDIT: and Mozilla with -moz-text-align-last], so let us just fake another line of justifiable text for the others:
.thumbs:after { display: inline-block; width: 100%; content: ""; }
http://jsfiddle.net/TWgDh/
.thumb:last-child {
float:right;
}
​
? :)
http://jsfiddle.net/cPm9f/1/
As mentioned above, you can use that but just be aware that the last-child CSS pseudo-class isn't supported in any IE browsers below IE9. I don't know what you plan on supporting but it's worth knowing. The first-child pseudo-class, however, has some support in earlier versions of IE.

How do I Achieve this layout without fighting CSS

I understand that there are several questions here about this problem, but I have a rather unique predicament. I'm working on a template that has to include certain tags, and has to work with other elements that are added to the template after I upload the code. I wouldn't worry about this, but I am having a time trying to get the footer to display at the bottom of the page. I can't alter anything about the footer, and it displays at the bottom of the div I'm using as a wrapper. The problem is if I set the height to a fixed value, there can only be so many comments made before the comment div overlaps the footer. I've tried several different solutions including setting the container div's height to auto, overflow to auto, bottom margin to 65 (height of the footer), and setting the overflow to scroll for the Comments div (resulted in very loose comments).
Here is an example of the problem and the template as it stands.
Here is the CSS styling for the container div (div id=Main)
#Main {
margin: 0px auto auto auto;
background-color: #808080;
font-family: Verdana, Geneva, Tahoma, sans-serif;
font-size: medium;
font-variant: normal;
color: #FFFFFF;
width: 900px;
position: relative;
}
Here's the CSS styling for the Comments div
#Comments {
background-color: #008080;
width: 450px;
height: auto;
top: 1750px;
left: 450px;
position: absolute;
overflow: auto;
}
And here's how the divs are stacked in the body
<div id="Main">
...
<div id="Comment_Form">
<!--[COMMENT_FORM=400,200]-->
</div>
<div id="Comments">
<!--[COMMENTS=400]-->
Comments
</div>
</div>
Since the page is going to be image heavy, I'm trying to keep the code lightweight (and probably failing at it pretty badly).
Thank you for your help and I'll post the template as of now if anyone needs it.
EDIT:
Okay, it's occurred to me that a) I need to redo the CSS and the divs that I have down, and b) I have no clue how to do it using pure CSS, or at least with out fighting it as one of you has said. What I'm trying to achieve is this:
I have no clue How to do this. and any help would be greatly appreciated (as well as any way to avoid having each and every element in its own div)
You seem to be really fighting your CSS on that page. Most of your elements are positioned absolutely within your #Main class. This will force you to specify a lot more layout than you really want to. It also means that if you have a variable quantity of comments or dynamic content, you'll find it that much harder to expand your content containers without others getting in the way.
I would strongly urge you to look at CSS frameworks or approaches that take advantage of grid layouts such as Nicole Sullivan's OOCSS framework.
You'll find that the structure (which has plenty of good, workable examples) is easy to follow and lends itself much more readily to the sorts of layouts that you're trying to achieve.
I hope this is helpful.
Here is a very basic layout that you can use.
In your CSS:
#header, #content, #comments{
margin: 0 auto;
width: 960px;
overflow: hidden;
}
#author-comments{
width: 100%;
}
#comment-box{
float: left;
width: 50%;
}
#comment-list{
float: right;
width: 50%;
}
In your markup:
<div id="header">
Header
</div>
<div id="content">
Contents
<div>
<div id="comments">
<div id="author-comments">
Author comments
</div>
<div id="comment-box">
Comment box
</div>
<div id="comment-list">
Comment list
</div>
</div>
It's really important that you use markup that makes sense without the styles. Don't see divs as plain boxes but as actual content containers that give structure to your document.
On a side note, you mentioned that you were concerned about the ammount of divs to keep your file light, compensating for the amount of images you're using. Don't worry about this. Text documents (such as HTML) are nothing compared to images in terms of file size. However, his doesn't mean you should throw markup as if it was free ;)
One last thing. I noticed that you are using <img> elements to render your decoration images. Try using CSS to set them as background images in the corresponding <div>s. This not only will help you to make cleaner and easier to implement structures, but also will draw a line between the images that represent content and those that represent decoration.
I'll write without any testing how I would code the layout on your image:
HTML:
<div id="header" class="centered"></div>
<div id="content" class="centered">
<div id="navigation"></div>
<div id="content"></div>
</div>
<div id="comments" class="centered">
<div id="author-comments" class="centered"></div>
<div class="centered">
<div id="comment-field"></div>
<div id="user-comments"></div>
</div>
</div>
CSS:
* { margin:0px; padding:0px }
html { height:100% }
body { height:100% }
.centered { position:relative; margin:0 auto; width:960px }
#header { height:100px; background:#333 }
#content { overflow:hidden }
#author-comment { overflow:hidden; margin:30px auto }
#comment-field { position:relative; float:left; width:480px; overflow:hidden }
#user-comments { position:relative; float:left; width:480px; overflow:hidden }
Sorry, got no time to test now, but on first view, I don't see any problems with this code - write comments, if something doesn't work

Resources