18

I have a large HTML document with headers (h1, h2, h3...) and paragraphs. When I print the document, I want that, automatically, headers at bottom of document go to next page:

enter image description here

How can I do? I use "orphans: 3" CSS with paragraphs and works with "p" tags, but with h1 or h2 don't work.

@page {
  size: A4;
}

p {
  orphans:3;
}

h1, h2 {
  orphans:3
}

Full example on action where:

  • 1-2 page: paragraphs orphan works fine.
  • 2-3 page: headers don't works.

Requirements:

  • HTML have one main div container.
  • Don't alter HTML.
  • Browser support isn't important (on my specific job).
  • I need some trick in CSS (no JS or Jquery, preferably)
  • I can't use page-break-before:always because I want that headers only go to next page when appears at bottom of page.
Manz
  • 948
  • 12
  • 26
  • Too much theory.. can we get some code in action? – Mr. Alien Jan 15 '16 at 10:11
  • Questions seeking code help must include the shortest code necessary to reproduce it **in the question itself**. See [**How to create a Minimal, Complete, and Verifiable example**](http://stackoverflow.com/help/mcve) – Paulie_D Jan 15 '16 at 10:11
  • You should be aware, that print-specific styles such as `orphans`, `break-after` etc. have notoriously bad support by browsers, so there will always be cases where these things don't work. Generally printing and page based styles are still a weak point for HTML/CSS, so if you need good quality print-outs, you seriously should look at alternatives such as PDF. – RoToRa Jan 15 '16 at 11:16
  • @RoToRa for me, browser support isn't important. I want translate information to PDF without manual layout tasks. With one support-browser is enough. – Manz Jan 16 '16 at 00:31

2 Answers2

15

In typography an orphan is:

A paragraph-opening line that appears by itself at the bottom of a page or column, thus separated from the rest of the text.

However in HTML <h1> and <p> are different paragraphs then what you have to use is break-after property to tell layout engine to do not put a page break after that paragraph (with the side effect to move next paragraph up to previous page - if fit - or to move header to next page.

h1, h2 {
    break-after: avoid-page;
}

Note about compatibility: break-after setting is a true working draft and even basic features are not widely supported (notably Internet Explorer 10 does). To workaround this you may use another property with similar meaning:

h1, h2 {
    page-break-after: avoid;
}

Note that page-break-after applies to both page and columns. page-break-after isn't well supported by FF (it is a bug) then if compatibility is important and paragraph won't span across multiple pages you can workaround wrapping <h1> and <p> inside a container (let's say <section>) and then apply page-break-inside like this:

section {
    page-break-inside: avoid;
}

IMO you should combine page-break-after and page-break-inside using page-break-inside with -moz prefix until it will fix that bug.

Adriano Repetti
  • 65,416
  • 20
  • 137
  • 208
  • Your answer is perfect, I understand and know this points, but the theory don't work (or I do some incorrect). Could give some code (or modify codepen example for "Select all text" / Print) and show how works? In my example, I don't get "Blah blah" header go to next page. – Manz Jan 16 '16 at 00:38
  • Don't try inside CodePen, using a standalone file it works. Of course browser compatibility is aleatory (at best, typography isn't so well supported). Most _compatible_ way is last described one, it slightly change how output is rendered (because it'll try to keep all section together, possibly even without breaking paragraphs and adding - when required - a page break before first title). With this difference it's only one I saw rendered correctly in every browser I tried. – Adriano Repetti Jan 18 '16 at 11:04
  • does it work for any one? i tried but not worked for me? any suggestions? – macha devendher May 28 '18 at 09:23
  • @macha it depends on the browser, second one compatibility is good but you definitely should try. Which browser? What's the exact code? – Adriano Repetti May 28 '18 at 10:01
  • currently i am using chrome latest version @Adriano Repetti – macha devendher May 28 '18 at 11:14
  • What's the code? 2 years ago chrome worked pretty well with last snippet – Adriano Repetti May 28 '18 at 12:04
  • Please add https before url – macha devendher May 28 '18 at 14:38
0

This question is a duplicate of this older one: How do I avoid a page break immediately after a heading

The best working solution is code like this:

h1, h2, h3, h4, h5 {
  break-inside: avoid;
}
h1::after, h2::after, h3::after, h4::after, h5::after {
  content: "";
  display: block;
  margin-bottom: -4rem;
  height: 4rem;
}