171

I am using a separate style-sheet for printing.

Is it possible to set right and left margins in the style-sheet which set the print margin? (i.e. margin on paper)

TylerH
  • 20,799
  • 66
  • 75
  • 101
kobra
  • 4,853
  • 10
  • 32
  • 33

7 Answers7

301

You should use cm or mm as unit when you specify for printing. Using pixels will cause the browser to translate it to something similar to what it looks like on screen. Using cm or mm will ensure consistent size on the paper.

body
{
  margin: 25mm 25mm 25mm 25mm;
}

For font sizes, use pt for the print media.

Note that setting the margin on the body in css style will not adjust the margin in the printer driver that defines the printable area of the printer, or margin controlled by the browser (may be adjustable in print preview on some browsers)... It will just set margin on the document inside the printable area.

You should also be aware that IE7++ automatically adjusts the size to best fit, and causes everything to be wrong even if you use cm or mm. To override this behaviour, the user must select 'Print preview' and then set the print size to 100% (default is Shrink To Fit).

A better option for full control on printed margins is to use the @page directive to set the paper margin, which will affect the margin on paper outside the html body element, which is normally controlled by the browser. See http://www.w3.org/TR/1998/REC-CSS2-19980512/page.html.
This currently works in all major browsers except Safari.
In Internet explorer, the margin is actually set to this value in the settings for this printing, and if you do Preview you will get this as default, but the user can change it in the preview.

@page  
{ 
    size: auto;   /* auto is the initial value */ 

    /* this affects the margin in the printer settings */ 
    margin: 25mm 25mm 25mm 25mm;  
} 

body  
{ 
    /* this affects the margin on the content before sending to printer */ 
    margin: 0px;  
} 

Related answer: Disabling browser print options (headers, footers, margins) from page?

Community
  • 1
  • 1
awe
  • 21,938
  • 6
  • 78
  • 91
  • 3
    This works now in Chrome 18 and IE9 (didn't test earlier versions). Still not working in Firefox 12, but you could do a server-side detection and add a body class `` so in your css you can do `body.firefox {margin: 0mm; padding: 0.25in;}`, that is actually a 0.75 inch margin because firefox already adds 0.5in. This should work as long as you need >= 0.5 inch margins. – MrFusion May 13 '12 at 21:56
  • 10
    +1 for @page! That's exactly what I needed, since I'm printing multiple pages. – airstrike Dec 07 '12 at 22:39
  • 2
    It now works with Firefox as well. Since Firefox have good auto-update routines, this should not be a problem we need to address anymore. I have tested on IE, Opera, Chrome, Firefox and Safari. The only browser this currently does not work with is Safari (version 5.1.7 for Windows). I have not tested on Mac. – awe Aug 21 '13 at 07:41
  • 1
    This only adds top margin on first page. Better solution for setting same margins on all pages: http://stackoverflow.com/questions/37033766/css-print-a-custom-sized-page-margin-when-the-content-is-on-multiple-pages?answertab=active#tab-top – besimple Feb 02 '17 at 10:27
  • @besimple: See bottom example. Using the ´@page´ directive will add the margin on every page. – awe Feb 02 '17 at 13:27
  • @awe: But it says that you need to create section for each page which is a problem if you just want to print existing web document. – besimple Feb 03 '17 at 14:21
  • 2
    Note that Margins needs to be set to Default in Chrome for the @page directive to take effect. – tschumann Jan 01 '20 at 06:14
  • I have applied padding instead of margin for the body and the internal elements behave way more predictable in Chrome, for example a full width table doesn't slip out from the page when I print it. – Gabor Jan 16 '22 at 22:23
74

Firstly said, I try to force all my users to use Chrome when printing because other browsers create different layouts.

An answer from this question recommends:

@page {
  size: 210mm 297mm; 
  /* Chrome sets own margins, we change these printer settings */
  margin: 27mm 16mm 27mm 16mm; 
}

However, I ended up using this CSS for all my pages to be printed:

@media print 
{
    @page {
      size: A4; /* DIN A4 standard, Europe */
      margin: 0;
    }
    html, body {
        width: 210mm;
        /* height: 297mm; */
        height: 282mm;
        font-size: 11px;
        background: #FFF;
        overflow: visible;
    }
    body {
        padding-top: 15mm;
    }
}


Special case: Long Tables

When I needed to print a table over several pages, the margin:0 with the @page was leading to bleeding edges:

bleeding edges

I could solve this thanks to this answer with:

table { page-break-inside: auto }
tr    { page-break-inside: avoid; page-break-after: auto; }
thead { display: table-header-group; }
tfoot { display: table-footer-group; }

Plus setting the top-bottom-margins for @page:

@page { 
    size: auto;
    margin: 20mm 0 10mm 0;
}
body {
    margin: 0;
    padding: 0;
}

Result:

solved bleeding edges


I would rather prefer a solution that is concise and works with all browser. For now, I hope the information above can help some developers with similar issues.

Avatar
  • 14,622
  • 9
  • 119
  • 198
  • 4
    Your solution proved invaluable when working with reports printing using ERPNext. I was able to develop my own custom print formats with ease and these pointers helped immensely! – Tropicalrambler Feb 09 '19 at 04:32
12

Updated, Simple Solution

@media print {
   body {
       display: table;
       table-layout: fixed;
       padding-top: 2.5cm;
       padding-bottom: 2.5cm;
       height: auto;
   }
}

Old Solution

Create section with each page, and use the below code to adjust margins, height and width.

If you are printing A4 size.

Then user

Size : 8.27in and 11.69 inches

@page Section1 {
    size: 8.27in 11.69in; 
    margin: .5in .5in .5in .5in; 
    mso-header-margin: .5in; 
    mso-footer-margin: .5in; 
    mso-paper-source: 0;
}



div.Section1 {
    page: Section1;
} 

then create a div with all your content in it.

<div class="Section1"> 
    type your content here... 
</div>
falsarella
  • 12,217
  • 9
  • 69
  • 115
Pir Abdul
  • 2,274
  • 1
  • 26
  • 35
  • This is not working for me in Chrome or FF. Also, `class=Section1` should be `class="Section1"`. – nu everest May 06 '15 at 17:21
  • This is a simpler solution: http://stackoverflow.com/questions/37033766/css-print-a-custom-sized-page-margin-when-the-content-is-on-multiple-pages?answertab=active#tab-top – besimple Feb 02 '17 at 10:26
9

I'd personally suggest using a different unit of measurement than px. I don't think that pixels have much relevance in terms of print; ideally you'd use:

  • point (pt)
  • centimetre (cm)

I'm sure there are others, and one excellent article about print-css can be found here: Going to Print, by Eric Meyer.

David Thomas
  • 249,100
  • 51
  • 377
  • 410
  • 1
    You're right that `px` does not have much relevance to print. But the browsers "translates" pixel units so it looks similar to how it looks on screen. It does **not** use the "printer resolution dots" as pixels (thank God...). – awe Oct 22 '13 at 10:31
2

I also recommend pt versus cm or mm as it's more precise. Also, I cannot get @page to work in Chrome (version 30.0.1599.69 m) It ignores anything I put for the margins, large or small. But, you can get it to work with body margins on the document, weird.

ironarm
  • 446
  • 4
  • 11
1

You can also try this one, for using top negative margin

@media print {
 @page {
   /* size: 210mm 297mm;  */
   margin: -110mm 16mm 27mm 16mm; 
 }

}

0

If you know the target paper size, you can place your content in a DIV with that specific size and add a margin to that DIV to simulate the print margin. Unfortunately, I don't believe you have extra control over the print functionality apart from just show the print dialog box.

jonjbar
  • 3,896
  • 1
  • 25
  • 46
  • Thanks. Is it not possible to specify leave x pixels on left and right irrespective of the paper size. Regards – kobra Oct 09 '09 at 07:46
  • 1
    I guess this might be possible if you set your parent DIV's size to 100% and add a x pixels margin to it. – jonjbar Oct 09 '09 at 07:49