2

Basically, what I am trying to is to spread a table to fill the rest of the page in print mode. I've surfed the internet, examined this post, and yet after two hours can't figure out what I am doing wrong. The idea is that the table should take up the rest of the page

document.querySelector("#print").addEventListener("click", function() {
  //var html = "<div>Test assignment</div>";
  //$('.test').html(html);
  window.print();
});
@media print {
  body * {
    visibility: hidden;
  }
 
  #print-wrapper * {
    visibility: visible;
  }
  .my-table {
    width: 100%;
    height: 100%;
    border: solid;
table-layout: fixed;
  }
  
}
<input type="button" value="print" id="print">
<div id="print-wrapper">
  <div class="print-heading">My table
  </div>
  <div>
    <div class="print-week-heading">Some heading</div>
    <table class="my-table">
      <tr>
        <td>
          A
        </td>
        <td>
          B
        </td>
      </tr>
      <tr>
        <td>
          C
        </td>
        <td>
          D
        </td>
      </tr>

    </table>
  </div>
</div>
Edgar Navasardyan
  • 4,261
  • 8
  • 58
  • 121

2 Answers2

3

You can use vh units to adjust the table's height.

@media print {
  .my-table {
    height: 90vh; 
  }
}

90vh equates to 90% of the height of the page, so adjust this as necessary.

Added code snippet:

document.querySelector("#print").addEventListener("click", function() {
  //var html = "<div>Test assignment</div>";
  //$('.test').html(html);
  window.print();
});
@media print {
  body * {
    visibility: hidden;
  }
 
  #print-wrapper * {
    visibility: visible;
  }
  .my-table {
    width: 100%;
    height: 90vh;
    border: solid;
    table-layout: fixed;
  }
  
}
<input type="button" value="print" id="print">
<div id="print-wrapper">
  <div class="print-heading">My table
  </div>
  <div>
    <div class="print-week-heading">Some heading</div>
    <table class="my-table">
      <tr>
        <td>
          A
        </td>
        <td>
          B
        </td>
      </tr>
      <tr>
        <td>
          C
        </td>
        <td>
          D
        </td>
      </tr>

    </table>
  </div>
</div>
wiiiiilllllll
  • 630
  • 6
  • 11
  • 2
    I tried `100vh` and the table didn't resize so I dropped that line of thought. Surprised to see `90vh` work. While experimenting with this answer I found that `height: 100vh;` and `page-break-before: always` shows the table entirely on the new page. – Richard Parnaby-King Jul 16 '18 at 14:57
  • Could you do a code snippet showing a "working" solution? – Richard Parnaby-King Jul 16 '18 at 14:58
  • Added a code snippet. This works for me in Chrome and Firefox, depending on your definition of "works". Admittedly there's some ambiguity in the question - should the table take up 100% of a page's height (as per the question title) or should it fill "the rest of" the page (as mentioned in the description)? My answer assumes the former; the latter is much more tricky. – wiiiiilllllll Jul 16 '18 at 15:09
1

Sadly, the only approach is to use position: absolute on the table. As long as every parent element has height: 100% then the table will be able to stretch to the full page height.

However, using position: absolute means it is now OVER the rest of the content. I have tried every combination of page-break-* on the table and sibling elements but cannot get the table on its own page at full height.

document.querySelector("#print").addEventListener("click", function() {
  //var html = "<div>Test assignment</div>";
  //$('.test').html(html);
  window.print();
});
@media print {
  body,
  html,
  #print-wrappe {
    height: 100%;
  }
  body * {
    visibility: hidden;
  }
  #print-wrapper * {
    visibility: visible;
    height: 100%;
  }
  .my-table {
    border: solid;
    width: 100%;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    position: absolute;
  }
}
<input type="button" value="print" id="print">
<div id="print-wrapper">
  <div class="print-heading">My table
  </div>
  <div>
    <div class="print-week-heading">Some heading</div>
    <table class="my-table">
      <tr>
        <td>
          A
        </td>
        <td>
          B
        </td>
      </tr>
      <tr>
        <td>
          C
        </td>
        <td>
          D
        </td>
      </tr>

    </table>
  </div>
</div>

A possible solution to the table being over the content, is to replace print-weekly-heading with a <caption>Some Heading</caption> as the first child of the table? This snippet shows what I'm trying to achieve, but would require further CSS to make the caption a usable title.

document.querySelector("#print").addEventListener("click", function() {
  //var html = "<div>Test assignment</div>";
  //$('.test').html(html);
  window.print();
});
@media print {
  body,
  html,
  #print-wrappe {
    height: 100%;
  }
  body * {
    visibility: hidden;
  }
  #print-wrapper * {
    visibility: visible;
    height: 100%;
  }
  .my-table {
    border: solid;
    width: 100%;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    position: absolute;
  }
}
<input type="button" value="print" id="print">
<div id="print-wrapper">
  <div class="print-heading">My table
  </div>
  <div>
    <table class="my-table">
      <caption>Some heading</caption>
      <tr>
        <td>
          A
        </td>
        <td>
          B
        </td>
      </tr>
      <tr>
        <td>
          C
        </td>
        <td>
          D
        </td>
      </tr>

    </table>
  </div>
</div>

Edit

A third option, is to display: block the table cells and float them. This requires prior knowledge of the number of tds in the table so you know what width to it as. I've also set the table page-break-before:always on so that the table takes up a whole page to itself. You can remove this and give the table a height of calc(100% - 3em); so that it fits with the headings on the same page as well.

document.querySelector("#print").addEventListener("click", function() {
  //var html = "<div>Test assignment</div>";
  //$('.test').html(html);
  window.print();
});
@media print {
  html,
  body,
  #print-wrapper {
    height: 100%;
  }
  body * {
    visibility: hidden;
  }
  #print-wrapper * {
    visibility: visible;
  }
  #print-wrapper>div:nth-child(2) {
    height: 100%;
  }
  .my-table {
    page-break-before: always;
    border: solid;
    width: 100%;
    height: calc(100% - 3em);
  }
  .my-table td {
    display: block;
    float: left;
    width: 50%;
    height: 50%;
    padding: 0;
    margin: 0;
  }
}
<input type="button" value="print" id="print">
<div id="print-wrapper">
  <div class="print-heading">My table
  </div>
  <div>
    <div class="print-week-heading">Some heading</div>
    <table class="my-table">
      <tr>
        <td>
          A
        </td>
        <td>
          B
        </td>
      </tr>
      <tr>
        <td>
          C
        </td>
        <td>
          D
        </td>
      </tr>

    </table>
  </div>
</div>
Community
  • 1
  • 1
Richard Parnaby-King
  • 14,703
  • 11
  • 69
  • 129