Search code examples
htmlcsstwitter-bootstrapprintingpage-break

HTML/CSS printing page-break with float not working (eg: bootstrap)


NOTE: Asking and answering it myself because I've spent 3 days trying different methods to find a solution, hoping this helps someone. The question has been asked before but they are old and the answers are unclear or unsatisfactory.

Trying to add a page-break when printing with elements that have float, eg: using bootstrap grid, doesn't work. The page-break is ignored.

<div style="float:right;">floating div</div>

<div class="col-xs-12">
  <div class="row">
    <div class="col-xs-12 break-after">
      Add page break after this element when printing
    </div>
    <div class="col-xs-12">
      This should be printed on next page
    </div>
  </div>
</div>

<style type="text/css">
.break-after {
  page-break-after: always;
}
</style>

Solution

  • Firstly, page-break doesn't work inside absolutely positioned elements so make sure your page-break isn't inside one.

    Now, since float is causing the page-break to be ignored, we need to clear the float.

    The problem is that clear: both; doesn't work if the element with page-break-after: always; is a float (eg: .col-xs-12 in bootstrap).

    The trick is to add 2 new divs with the clear and page-break after the div you want to add the page-break to:

    <div class="page-break-clear"></div>
    <div class="page-break">&nbsp;</div>
    
    <style type="text/css">
    .page-break-clear { 
      clear: both;
    }
    .page-break {
      page-break-after: always; /* depreciating, use break-after */
      break-after: page;
      height: 0px;
      display: block!important;
    }
    </style>
    

    Putting it together:

    <div style="float:right;">floating div</div>
    
    <div class="col-xs-12">
      <div class="row">
        <div class="col-xs-12 break-after">
          Add page break after this element when printing
        </div>
        <!-- These 2 new added divs will clear float and add the page break -->
        <div class="page-break-clear"></div>
        <div class="page-break">&nbsp;</div>
    
        <div class="col-xs-12">
          This should be printed on next page
        </div>
      </div>
    </div>
    
    <style type="text/css">
    .page-break-clear { 
      clear: both;
    }
    .page-break {
      page-break-after: always; /* depreciating, use break-after */
      break-after: page;
      height: 0px;
      display: block!important;
    }
    </style>
    

    as a side-note: I recommend removing the page-break-after css for .break-after class that was supplied in the question to prevent doubling up on page-breaks incase the floats are removed and it actually works.

    Also, to make your life easier if you are using jquery and don't want to manually add those 2 page-break divs, just run the following code which will automatically add them after all elements with the class .break-after:

    $('.break-after').after('<div class="page-break-clear"></div><div class="page-break">&nbsp;</div>');