Mathieu De Keyzer's face

 Handle page margin with CSS

HTTP enthusiasts

Print CSS and Page layout

I started from this article The Ultimate Print HTML Template with Header & Footer. It's a pretty good solution. I still faced some issues.

Table spacing and padding

Introduce a table in the dom will also introduce table's spacing and padding. But we can remove table's spacings easily.

<table id="page-layout" cellpadding="0" cellspacing="0">

Aria for footer and header

It's also a good pratice to specify to screen-reading to not read the header nor the footer.

<div class="page-header" aria-hidden="true">Header content</div>

Force page break

Time to time it's useful to force a page break. There is a trick to avoid weird issue. You always need to specify at least an unbreakable space in the page break:

<div class="page-break" aria-hidden="true">&nbsp;</div>
.page-break {
    display: none;
}

@media print {
    .page-break {
        page-break-before: always;
        display: block;
    }
}`

Table's width 100%

To avoid to your content shrink to the left:

table#page-layout {
  width: 100%;
}

Ensure that the footer and header are not visible in scree mode

.page-header, .page-header-space,
.page-footer, .page-footer-space {
  display: none;
}

@media print {
    .page-header, .page-header-space,
    .page-footer, .page-footer-space {
      display: block;
      height: $page-margin-header;
      width: 100%;
    }
}

Force the browser's margins

You must specify the page's size and the page's orientation. Otherwize @Page margin information won't be taken into account:

@media print {
    @page {
        size: A4 portrait;
        margin: 0;
    }
}

Margin left and right

table#page-layout {
  & > tbody > tr > td {
      padding-left: $page-margin-side;
      padding-right: $page-margin-side;
  }
}

Ultimate Solution

How it looks.

Here is the code of that example:

<table id="page-layout" cellpadding="0" cellspacing="0">
    <thead><tr><td>
        <div class="page-header-space" aria-hidden="true">&nbsp;</div>
    </td></tr></thead>
    <tbody><tr><td>
        <div class="page-content">
            {%- block page_content %}{% endblock page_content -%}
        </div>
    </td></tr></tbody>
    <tfoot><tr><td>
        <div class="page-footer-space" aria-hidden="true">&nbsp;</div>
    </td></tr></tfoot>
</table>


<div class="page-header" aria-hidden="true"></div>
<div class="page-footer" aria-hidden="true">
    {%- block print_footer -%}
        Footer
    {%- endblock print_footer -%}
</div>

_page.scss

//$page-height: 297mm;
//$page-width: 210mm;
$page-margin-header: 10mm;
$page-margin-side: 10mm;
$page-margin-footer: 20mm;

.page-header, .page-header-space,
.page-footer, .page-footer-space {
  display: none;
}

table#page-layout {
  width: 100%;
}

.page-break {
  display: none;
}

@media print {
  @page
  {
    size: A4 portrait;
    margin: 0;
  }

  body {
    margin: 0;
  }

  .page-break {
    page-break-before: always;
    display: block;
  }

  .page-content {
    background-color: #fff;
  }

  table#page-layout {
    & > tbody > tr > td {
      padding-left: $page-margin-side;
      padding-right: $page-margin-side;
    }
  }

  .page-header, .page-header-space,
  .page-footer, .page-footer-space {
    display: block;
    height: $page-margin-header;
    width: 100%;
  }

  .page-footer, .page-footer-space {
    height: $page-margin-footer;
  }

  .page-header {
    padding-top: 2mm;
    text-align: center;
    position: fixed;
    top: 0;
  }
  .page-footer {
    padding-top: 2mm;
    text-align: center;
    position: fixed;
    bottom: 0;
  }

}