Malaiselvan
Malaiselvan

Reputation: 1121

Margin and padding issue when doing window.print

I am trying with Javascript window.print to print a content inside the div container. The div container is managed by angular js.

CSS file

@media print
{
    body, html, #wrapper {
        width: 100%;
        margin:0px;
        padding:0px;
        border: 1px solid red;
    }
    .no-print, .no-print * {
        display: none !important;
    }
    .col-sm-12 {
        width: 100%;
   }
}

HTML containing the DIV

<div ng-show="views.invoice">
    <div class="row col-sm-12" style="margin:0px; padding:0px; width:100%">
        test
    </div>

    <div class="row no-print">
        <div class="col-12">
            <button class="btn btn-success btn-default" onclick="window.print();"><i class="fa fa-print"></i> {{phrase.Print}}</button>
        </div>
    </div>
</div>

This is how it is shown in the browser

enter image description here

When I do the print it is printing to PDF as below

enter image description here

I see a big margin around the text 'test'. How can I print without any margin or padding?

Upvotes: 0

Views: 3104

Answers (1)

Richard
Richard

Reputation: 7443

The Problem

It's most likely because you've set the visibility your drawer and your navbar (the left-side navigation and the top-side navigation) to hidden. When something's visibility is set to hidden, it is still in the layout and preserves its height, width, margin, and padding. This is why you're seeing the space of your drawer and navbar, respectively causing the space on the left side and the top side.

You can run and try printing the below screen. You'll see the problem I mentioned (the space caused by the preserved sizes [height, width, padding, margin]).

@media print {
  body,
  html,
  #wrapper {
    width: 100%;
    margin: 0px;
    padding: 0px;
    border: 1px solid red;
  }
  #drawer {
    visibility: hidden;
  }
  #navbar {
    visibility: hidden;
  }
  .no-print {
    display: none;
  }
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html,
body {
  position: relative;
  width: 100%;
  height: 100%;
}

#wrapper {
  display: flex;
  flex-direction: row;
  height: 100%;
  width: 100%;
}

#navbar {
  width: 100%;
  background: blue;
  color: white;
  padding: 20px;
}

#section--right {
  flex-grow: 1;
}

#drawer {
  height: 100%;
  width: 100px;
  background: red;
  color: white;
  padding: 20px;
}

#navbar .text {
  display: inline-block;
  height: 50px;
  background: #121212;
}
<div id="wrapper">
  <div id="drawer">Some drawer</div>

  <div id="section--right">
    <div id="navbar"><span class="text">Some navbar</span></div>
    <div id="print__section">
      test
    </div>

    <button id="print__button" class="no-print" onclick="window.print()">Print now</button>
  </div>
</div>


Solution

My suggestion is to set a special id or class to the printable region. Then, set all the other elements' visibility inside body that have no such special id or class to hidden. Furthermore, because setting visibility to hidden still allows the elements to preserve their dimensions, set their sizes (height, width, margin, and padding) to 0 too. Note that you can't use display: none because your printable region will also not be displayed.

Here's a working example that will solve your problem.

@media print {
  body,
  html,
  #wrapper {
    width: 100%;
    margin: 0px;
    padding: 0px;
    border: 1px solid red;
  }
  
  /* Makes all divs that are not inside the print region invisible */
  /* Then, set the size to 0 by setting everything (height, width, margin, and padding) to 0 */
  body *:not(#print__section) {
    visibility: hidden;
    height: 0;
    width: 0;
    margin: 0;
    padding: 0;
  }
  
  /* Parents' visibility cascade to children's visibility */
  /* Make the print region visible again to override parent's visibility */
  #print__section {
    visibility: visible;
  }
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html,
body {
  position: relative;
  width: 100%;
  height: 100%;
}

#wrapper {
  display: flex;
  flex-direction: row;
  height: 100%;
  width: 100%;
}

#navbar {
  width: 100%;
  background: blue;
  color: white;
  padding: 20px;
}

#section--right {
  flex-grow: 1;
}

#drawer {
  height: 100%;
  width: 100px;
  background: red;
  color: white;
  padding: 20px;
}

#navbar .text {
  display: inline-block;
  height: 50px;
  background: #121212;
}
<div id="wrapper">
  <div id="drawer">Some drawer</div>

  <div id="section--right">
    <div id="navbar"><span class="text">Some navbar</span></div>
    <div id="print__section">
      test
    </div>

    <button id="print__button" class="no-print" onclick="window.print()">Print now</button>
  </div>
</div>

Upvotes: 1

Related Questions