Search code examples
htmlcssprintingcss-grid

HTML/CSS: Page break between grid rows


I used HTML to create a document that is meant for print (as PDF). The general layout of the document features: a header with title, a side bar with comments and the main text, separated into sections. A minimum reproductive example:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>MRE</title>
    <style>
        body {
            display: grid;
            grid-template: "head head" max-content
                   "main side"
                   / auto 20%;
        }

        header {
            grid-area: head;
            break-after: avoid;
        }

        main {
            grid-area: main;
        }

        aside {
            grid-area: side;
        }

        section {
            padding: .5rem 0;
            break-after: auto;
        }
    </style>
</head>
<body>
<header><h1>Lorem Ipsum</h1></header>
<main>
    <section>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce interdum elementum metus, in accumsan lacus tristique eu. Aenean quam justo, gravida ac lectus sit amet, mattis sodales ipsum. Etiam commodo libero nulla, nec hendrerit justo maximus eget. Proin imperdiet venenatis arcu nec iaculis. Ut porttitor placerat odio, tincidunt ullamcorper ante auctor id. Aenean urna est, ornare non tellus id, sagittis ultrices est. Duis diam enim, aliquam eget mauris at, porttitor dictum urna. Donec tempor accumsan nibh, id aliquam velit blandit vel. Integer sit amet nibh et lectus euismod iaculis.
    </section>
    <section>
        Nunc rhoncus at dolor quis dignissim. Praesent eu nisi finibus tellus commodo tincidunt. Morbi at massa eget diam blandit varius. Proin ac ullamcorper erat. Suspendisse eget nibh nec mauris pharetra aliquet sit amet eu lectus. Aliquam enim nisi, facilisis non turpis et, ultrices ultrices sapien. Vivamus maximus magna sit amet urna laoreet, quis pellentesque nibh aliquam. Quisque maximus nulla at fringilla convallis. Sed euismod congue pellentesque. Donec sit amet gravida tortor, ut blandit risus. Mauris vel aliquet odio, sit amet porta dolor. Nulla semper fermentum quam non egestas. Donec justo tortor, cursus non urna nec, porta consectetur felis. Nullam cursus commodo leo ut sodales. Pellentesque lacinia turpis sed justo placerat convallis.
    </section>
    <section>
        Donec pulvinar tortor a libero dignissim, vel maximus enim condimentum. Quisque sollicitudin risus velit, non porta enim molestie id. Suspendisse sed erat sapien. Nam nunc ligula, hendrerit a blandit et, lobortis at massa. Donec id purus ut magna feugiat luctus tincidunt id augue. Aliquam eu nibh id ligula rutrum interdum eu eget purus. Fusce non metus ac mi facilisis rhoncus quis eget leo.
    </section>
    <section>
        Fusce aliquet blandit enim vitae porttitor. Nunc ante justo, mattis sagittis condimentum vitae, elementum sit amet urna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam tellus orci, efficitur quis interdum et, viverra sit amet magna. Praesent congue lacus malesuada, viverra sapien sit amet, cursus leo. Aliquam posuere tellus sapien, eu facilisis erat ullamcorper a. Maecenas ligula eros, maximus vitae blandit sed, viverra at purus. Phasellus diam ipsum, convallis nec pretium malesuada, dictum non lorem. Duis cursus consequat justo sit amet vehicula. Ut metus leo, pharetra eget metus accumsan, mattis ullamcorper mi. Nulla sem ex, sagittis a orci vitae, lacinia fermentum nibh. Aliquam egestas dui sit amet vehicula consequat.
    </section>
    <section>
        Proin vitae erat diam. Quisque congue commodo enim egestas varius. Quisque id arcu velit. Vestibulum pulvinar mauris eget enim aliquet tempus. Mauris rutrum interdum lacus, in pellentesque nisl. Proin feugiat, est ac ultrices aliquet, odio lectus rhoncus ante, id consectetur lorem orci vel justo. Nunc convallis turpis purus, ut viverra nunc congue in. Nulla a nisi velit. Pellentesque in mauris quis erat dapibus dignissim non sit amet velit. Fusce id vestibulum justo. Proin non nisl eu lectus sodales pretium eu in felis. Nam quis dignissim nulla, vel venenatis magna. Donec odio risus, eleifend vel ornare non, cursus ut turpis.
    </section>
    <section>
        Proin vitae erat diam. Quisque congue commodo enim egestas varius. Quisque id arcu velit. Vestibulum pulvinar mauris eget enim aliquet tempus. Mauris rutrum interdum lacus, in pellentesque nisl. Proin feugiat, est ac ultrices aliquet, odio lectus rhoncus ante, id consectetur lorem orci vel justo. Nunc convallis turpis purus, ut viverra nunc congue in. Nulla a nisi velit. Pellentesque in mauris quis erat dapibus dignissim non sit amet velit. Fusce id vestibulum justo. Proin non nisl eu lectus sodales pretium eu in felis. Nam quis dignissim nulla, vel venenatis magna. Donec odio risus, eleifend vel ornare non, cursus ut turpis.
    </section>
    <section>
        Proin vitae erat diam. Quisque congue commodo enim egestas varius. Quisque id arcu velit. Vestibulum pulvinar mauris eget enim aliquet tempus. Mauris rutrum interdum lacus, in pellentesque nisl. Proin feugiat, est ac ultrices aliquet, odio lectus rhoncus ante, id consectetur lorem orci vel justo. Nunc convallis turpis purus, ut viverra nunc congue in. Nulla a nisi velit. Pellentesque in mauris quis erat dapibus dignissim non sit amet velit. Fusce id vestibulum justo. Proin non nisl eu lectus sodales pretium eu in felis. Nam quis dignissim nulla, vel venenatis magna. Donec odio risus, eleifend vel ornare non, cursus ut turpis.
    </section>
</main>
<aside>Here are some side-notes</aside>
</body>
</html>

When I print this document, the first page only contains header part, while the main content starts at the second page. The text is broken in the middle of a section (the last line is even cut horizontally in half). The aside part is, as it should be, next to the text.

I want the page breaks be inserted between the sections and the first page should contain the header as well as the first few sections.

Apparently, the CSS property break-after has no effect in this case. And answers to similar questions hint that CSS grids and printing don't work together well. How else would it be possible to achieve the above layout?

A possible solution to this would be using flexbox layout instead. However, is there any possibility to use grid layout?


Solution

  • Do not treat screen and print media the same. On screen you can have menu bar, floating headers, animated stuff. You can't show these things on printed pages. The @media rule lets us specify different styles for different media.

    How else would it be possible to achieve the above layout?

    If the grid layout is giving trouble while printing, then we can use different CSS for printing, inside the @media print {} rule:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8" />
      <title>@media print demo</title>
      <style>
        /* normal style rules */
        body {
          display: grid;
          grid-template: 'head head' max-content 'main side' / auto 20%;
        }
        
        header {
          grid-area: head;
          break-after: avoid;
        }
        
        main {
          grid-area: main;
        }
        
        aside {
          grid-area: side;
        }
        
        section {
          padding: 0.5rem 0;
          break-after: auto;
        }
    
        /* override the rules for printing */
        @media print {
          @page {
            margin: 2cm;
          }
          body {
            /* no grid layout */
            font-size: 6mm;
            font-family: 'Times New Roman', Times, serif;
          }
          header {
            break-after: avoid;
          }
          main {
            width: 148mm;
            float: left;
          }
          aside {
            float: right;
            font-size: 5mm;
            font-style: italic;
            margin-left: 5mm;
          }
        }
      </style>
    </head>
    
    <body>
      <header>
        <h1>Lorem Ipsum</h1>
      </header>
      <main>
        <section>
          1 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce interdum elementum metus, in accumsan lacus tristique eu. Aenean quam justo, gravida ac lectus sit amet, mattis sodales ipsum. Etiam commodo libero nulla, nec hendrerit justo maximus eget.
          Proin imperdiet venenatis arcu nec iaculis. Ut porttitor placerat odio, tincidunt ullamcorper ante auctor id. Aenean urna est, ornare non tellus id, sagittis ultrices est. Duis diam enim, aliquam eget mauris at, porttitor dictum urna. Donec tempor
          accumsan nibh, id aliquam velit blandit vel. Integer sit amet nibh et lectus euismod iaculis.
        </section>
        <section>
          2 Nunc rhoncus at dolor quis dignissim. Praesent eu nisi finibus tellus commodo tincidunt. Morbi at massa eget diam blandit varius. Proin ac ullamcorper erat. Suspendisse eget nibh nec mauris pharetra aliquet sit amet eu lectus. Aliquam enim nisi, facilisis
          non turpis et, ultrices ultrices sapien. Vivamus maximus magna sit amet urna laoreet, quis pellentesque nibh aliquam. Quisque maximus nulla at fringilla convallis. Sed euismod congue pellentesque. Donec sit amet gravida tortor, ut blandit risus.
          Mauris vel aliquet odio, sit amet porta dolor. Nulla semper fermentum quam non egestas. Donec justo tortor, cursus non urna nec, porta consectetur felis. Nullam cursus commodo leo ut sodales. Pellentesque lacinia turpis sed justo placerat convallis.
        </section>
        <section>
          3 Donec pulvinar tortor a libero dignissim, vel maximus enim condimentum. Quisque sollicitudin risus velit, non porta enim molestie id. Suspendisse sed erat sapien. Nam nunc ligula, hendrerit a blandit et, lobortis at massa. Donec id purus ut magna feugiat
          luctus tincidunt id augue. Aliquam eu nibh id ligula rutrum interdum eu eget purus. Fusce non metus ac mi facilisis rhoncus quis eget leo. Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloribus, voluptatibus!
        </section>
        <section>
          4 Fusce aliquet blandit enim vitae porttitor. Nunc ante justo, mattis sagittis condimentum vitae, elementum sit amet urna. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam tellus orci, efficitur quis
          interdum et, viverra sit amet magna. Praesent congue lacus malesuada, viverra sapien sit amet, cursus leo. Aliquam posuere tellus sapien, eu facilisis erat ullamcorper a. Maecenas ligula eros, maximus vitae blandit sed, viverra at purus. Phasellus
          diam ipsum, convallis nec pretium malesuada, dictum non lorem. Duis cursus consequat justo sit amet vehicula. Ut metus leo, pharetra eget metus accumsan, mattis ullamcorper mi. Nulla sem ex, sagittis a orci vitae, lacinia fermentum nibh. Aliquam
          egestas dui sit amet vehicula consequat. Abcd asome abckd efg.
        </section>
        <section>
          5 Proin vitae erat diam. Quisque congue commodo enim egestas varius. Quisque id arcu velit. Vestibulum pulvinar mauris eget enim aliquet tempus. Mauris rutrum interdum lacus, in pellentesque nisl. Proin feugiat, est ac ultrices aliquet, odio lectus rhoncus
          ante, id consectetur lorem orci vel justo. Nunc convallis turpis purus, ut viverra nunc congue in. Nulla a nisi velit. Pellentesque in mauris quis erat dapibus dignissim non sit amet velit. Fusce id vestibulum justo. Proin non nisl eu lectus sodales
          pretium eu in felis. Nam quis dignissim nulla, vel venenatis magna. Donec odio risus, eleifend vel ornare non, cursus ut turpis.
        </section>
        <section>
          6 Proin vitae erat diam. Quisque congue commodo enim egestas varius. Quisque id arcu velit. Vestibulum pulvinar mauris eget enim aliquet tempus. Mauris rutrum interdum lacus, in pellentesque nisl. Proin feugiat, est ac ultrices aliquet, odio lectus rhoncus
          ante, id consectetur lorem orci vel justo. Nunc convallis turpis purus, ut viverra nunc congue in. Nulla a nisi velit. Pellentesque in mauris quis erat dapibus dignissim non sit amet velit. Fusce id vestibulum justo. Proin non nisl eu lectus sodales
          pretium eu in felis. Nam quis dignissim nulla, vel venenatis magna. Donec odio risus, eleifend vel ornare non, cursus ut turpis. Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptatem voluptatibus voluptates repellat enim? Similique
          tenetur minus ad. Totam molestias numquam esse harum, molestiae aspernatur. Asperiores, aliquam odit esse illum praesentium eos. Nobis ullam a doloremque quaerat molestiae veritatis eaque quidem. Odio quae corrupti, praesentium, sed quibusdam incidunt
          ipsum harum asperiores in magni fugit nulla. Culpa eligendi natus distinctio dignissimos, facilis consequuntur, possimus repellat tenetur ipsam dolores sint. Ratione, ducimus itaque. Itaque doloribus dolores quasi quae repellendus voluptate inventore
          aliquam beatae harum, sed, sit perspiciatis? Eveniet nostrum ipsam sunt modi ex quas nisi praesentium ad exercitationem, excepturi molestiae. Magni quaerat vel pariatur sint quo necessitatibus consequatur repellendus. Consectetur hic veniam natus,
          deleniti distinctio tempora ipsam incidunt cum autem aspernatur tempore. A neque quaerat placeat cum consequuntur doloribus, officia quo explicabo nisi molestias, iure ipsam repellat pariatur commodi maiores ex magni in natus perferendis minima
          corporis molestiae odit voluptatum fugiat? Quaerat explicabo nulla labore, odio eos iusto optio omnis quis, quidem expedita reprehenderit rerum itaque saepe natus nemo dolore! Adipisci sint sunt laudantium temporibus in illum explicabo sed dolorem,
          similique possimus cumque cum eveniet et unde ducimus eaque nemo reprehenderit nisi? Omnis impedit ducimus totam nostrum quos praesentium ipsa earum facilis deleniti.
        </section>
        <section>
          7 Proin vitae erat diam. Quisque congue commodo enim egestas varius. Quisque id arcu velit. Vestibulum pulvinar mauris eget enim aliquet tempus. Mauris rutrum interdum lacus, in pellentesque nisl. Proin feugiat, est ac ultrices aliquet, odio lectus rhoncus
          ante, id consectetur lorem orci vel justo. Nunc convallis turpis purus, ut viverra nunc congue in. Nulla a nisi velit. Pellentesque in mauris quis erat dapibus dignissim non sit amet velit. Fusce id vestibulum justo. Proin non nisl eu lectus sodales
          pretium eu in felis. Nam quis dignissim nulla, vel venenatis magna. Donec odio risus, eleifend vel ornare non, cursus ut turpis.
        </section>
      </main>
      <aside>Here are some important side-notes. Which are very useful.</aside>
    </body>
    
    </html>

    Copy the code in a separate HTML file and run it in a browser.

    Here is how it looks on Chrome: (open the image in new tab) print

    Here, I've avoided using grid layout for printing. And achieved similar result using different rules. Dimensions used for printing are considering A4 size page.

    Inside the @media print rule you can have different layouts for print. Choose not to print some content etc.


    A few tips:

    • For printing use serif fonts.
    • Use CSS units like in, cm, mm.
    • To do complex printing stuff you can use opensource library like PagedJs. Here is a demo using the library.