I'm generating A4
invoice using HTML
, CSS
and JS
. This looks fine in normal mode but the width
goes beyond 100%
and horizontal scroll bar starts to appear in print preview.
Here is my code snippet:
<html>
<head>
<style type="text/css">
#section-to-print {
position: absolute;
left: 0;
top: 0;
}
body {
font-family: Calibri, monospace;
font-size: 0.8rem;
margin: 1rem;
border: 1px solid;
}
body ol {
list-style: none;
padding-left: 0;
margin: 0.5rem 0;
}
table {
width: 100%;
height: 100%;
border-collapse: collapse;
page-break-inside: auto;
}
td section div {
page-break-inside: avoid;
}
thead {
display: table-header-group;
}
tfoot {
display: table-footer-group;
}
header {
display: flex;
flex-direction: column;
align-items: center;
font-weight: normal;
padding: 0 0.5rem;
position: relative;
}
header h1 {
font-size: 2rem;
font-weight: bold;
margin: 0;
}
header h2 {
font-size: 1.5rem;
font-weight: bold;
margin: 0;
}
header h3 {
font-size: 1rem;
font-weight: normal;
margin: 0;
}
header ul {
list-style: none;
padding-left: 0;
margin: 0.5rem 0;
}
header #brand {
border-bottom: 1px solid;
padding: 0.25rem 0.5rem;
text-transform: uppercase;
width: 100%;
}
header #phone {
position: absolute;
text-align: right;
top: 0;
right: 0.5rem;
}
header #invoicedetails {
display: grid;
grid: "customer-billed customer-shipped invoice";
grid-template-columns: repeat(3, 1fr);
padding: 0 0.5rem;
border-bottom: 1px solid;
width: 100%;
}
header #customer-billed {
text-align: left;
}
header #customer-shipped {
border: 1px solid;
border-top: 0;
border-bottom: 0;
padding-left: 0.5rem;
text-align: left;
}
header #invoice {
text-align: right;
}
table tbody td {
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
main {
display: flex;
flex-direction: column;
height: 100%;
}
#invoiceitems {
display: block;
height: 100%;
text-transform: uppercase;
}
#itemscontent {
height: 100%;
display: grid;
/*Below line is added as inline style in A4 invoice component*/
/*grid: "sno description hsn scale scale2 unit price unitprice";*/
/*grid-template-rows: repeat(2, minmax(1rem, max-content)) auto repeat(2, minmax(1rem, max-content));*/
/*grid-template-columns: minmax(min-content, max-content) minmax(min-content, auto) max-content max-content max-content max-content max-content max-content;*/
grid-auto-rows: minmax(1rem, max-content);
grid-column-gap: 1px;
align-items: center;
}
#itemscontent>div {
display: flex;
align-items: center;
border: 1px solid;
height: 100%;
border-top: 0;
border-right: 0;
padding: 0 0.25rem;
}
.border-left-0 {
border-left: 0 !important;
}
.border-bottom-0 {
border-bottom: 0 !important;
}
.border-top-1 {
border-top: 1px solid black !important;
}
.span-2 {
grid-column-start: span 2;
}
.span-3 {
grid-column-start: span 3;
}
.span-4 {
grid-column-start: span 4;
}
.span-5 {
grid-column-start: span 5;
}
.span-7 {
grid-column-start: span 7;
}
.text-darkgreen {
color: darkgreen;
}
.text-red {
color: red;
}
.bg-yellow {
background-color: yellow;
}
.flex-end {
justify-content: flex-end;
}
footer {
display: flex;
flex-direction: column;
margin-top: 10px;
}
#itemsfooter {
text-transform: uppercase;
border-left: 0 !important;
}
#itemsfooter>div {
align-self: stretch;
display: flex;
align-items: center;
padding: 0 0.5rem;
}
#amountinwords {
flex: 75%;
}
#totalamount {
flex: 25%;
text-align: right;
border-left: 1px solid black;
}
#totalamount ol {
width: 100%;
}
#totalamount ol li:last-child {
font-size: x-large;
}
#invoiceinformation {
text-transform: none;
border-left: 0 !important;
display: grid !important;
grid: "note" "bankdetails" "signature";
grid-template-columns: minmax(min-content, 40%) minmax(min-content, 35%) minmax(min-content, 25%);
padding: 0 0.5rem;
}
#invoiceinformation div {
align-self: stretch;
align-items: center;
padding: 0 0.5rem;
}
/* #note {
flex: 40%;
} */
#bankdetails {
/* flex: 35%; */
border: 1px solid;
border-top: 0;
border-bottom: 0;
}
#signature {
display: flex;
/* flex: 25%; */
border-left: 0 !important;
padding-right: 0.5rem !important;
}
#message {
display: flex;
justify-content: space-between;
border-left: 0 !important;
border-bottom: 0 !important;
padding: 0 0.5rem !important;
}
</style>
<style type="text/css">
@media print {
@page {
size: A4;
}
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>
<header>
<section id="brand">
<h1>BRAND</h1>
<h2>CAPTION</h2>
<h3>TAG LINE</h3>
<div>Address</div>
<div><b>TAX Invoice</b></div>
<section id="phone">
<ul>
<li>Phone: </li>
<li></li>
</ul>
</section>
</section>
<section id="invoicedetails">
<section id="customer-billed">
<ol>
<li>Billed To</li>
<li><b>ABC </b></li>
<li>Mobile: </li>
<li>Address: </li>
</ol>
</section>
<section id="customer-shipped">
<ol>
<li>Shipped To</li>
<li><b>ABC </b></li>
<li>Mobile: </li>
<li>Address: </li>
</ol>
</section>
<section id="invoice">
<ol>
<li>Invoice Details</li>
<li>Invoice No: <b>2/2024-25</b></li>
<li>DC No: <b>2102</b></li>
<li>Invoice Date: <b>01 Apr 2024</b></li>
<li>Payment Mode: <b>Credit</b></li>
<li>Payment Status: <b>Due</b></li>
</ol>
</section>
</section>
</header>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<main style="padding-bottom: 0">
<section id="invoiceitems">
<section id="itemscontent"
style="grid: 'sno description hsn scale price unit unitprice'; grid-template-columns: minmax(min-content, max-content) minmax(min-content, auto) max-content max-content max-content max-content max-content; grid-template-rows: repeat(2, minmax(1rem, max-content));">
<div class="border-left-0">S.No</div>
<div>Description</div>
<div><b></b></div>
<div>Days</div>
<div>Unit</div>
<div>Price</div>
<div>Unit Price</div>
<div id="invoiceinformation" class="span-7">
<div id="note">
<small>NOTE</small>
<br>
<text>Certified that the particulars
given above are true and correct</text>
</div>
<div id="bankdetails">
<small>COMPANY BANK DETAILS</small>
<br>
<text>BANK:
ABC BANK, A/C. NO: 1111111111111111, IFSC: IABC0000000, Branch: DEF
Road, GHI</text>
</div>
<div id="signature">
<text><b>for ABC</b>
<br>
<br>
<br>Authorized Signatory</text>
</div>
</div>
</section>
</section>
</main>
</td>
</tr>
</tbody>
</table>
</body>
</html>
In normal mode: All looks good.
In Print Preview or when Printed:
Horizontal scroll bar appears in print. I'm checking this by setting Emulate CSS media type
to print
.
This breaks the layout when I print to PDF
However I noticed a strange behavior when I remove the content inside my nested grid #invoiceinformation
. I commented the <text>
node inside #note
and #bankdetails
and then horizontal scroll bar disappeared.
Emulate CSS media type
to Print
after commenting <text>
node:
Print to PDF after commenting <text>
node.
The above output is the expected one even when I have data inside <text>
node. So I tried to set width:100%
to #invoiceinformation
grid but its not working.
Please assist me on what I'm missing?
It’s this grid definition which is causing the problem.
<section id="itemscontent" style="grid: sno description hsn scale price unit unitprice; grid-template-columns: minmax(min-content, max-content) minmax(min-content, auto) max-content max-content max-content max-content max-content; grid-template-rows: repeat(5, minmax(1rem, max-content)) auto repeat(3, minmax(1rem, max-content));">
Reset it so that all widths and heights are auto
, then just tweak from there using percentages or fractions.
#section-to-print {
position: absolute;
left: 0;
top: 0;
}
body {
font-family: Calibri, monospace;
font-size: 0.8rem;
margin: 1rem;
border: 1px solid;
}
body ol {
list-style: none;
padding-left: 0;
margin: 0.5rem 0;
}
table {
width: 100%;
height: 100%;
border-collapse: collapse;
page-break-inside: auto;
}
td section div {
page-break-inside: avoid;
}
thead {
display: table-header-group;
}
tfoot {
display: table-footer-group;
}
header {
display: flex;
flex-direction: column;
align-items: center;
font-weight: normal;
padding: 0 0.5rem;
position: relative;
}
header h1 {
font-size: 2rem;
font-weight: bold;
margin: 0;
}
header h2 {
font-size: 1.5rem;
font-weight: bold;
margin: 0;
}
header h3 {
font-size: 1rem;
font-weight: normal;
margin: 0;
}
header ul {
list-style: none;
padding-left: 0;
margin: 0.5rem 0;
}
header #brand {
border-bottom: 1px solid;
padding: 0.25rem 0.5rem;
text-transform: uppercase;
width: 100%;
}
header #phone {
position: absolute;
text-align: right;
top: 0;
right: 0.5rem;
}
header #invoicedetails {
display: grid;
grid: "customer-billed customer-shipped invoice";
grid-template-columns: repeat(3, 1fr);
padding: 0 0.5rem;
border-bottom: 1px solid;
width: 100%;
}
header #customer-billed {
text-align: left;
}
header #customer-shipped {
border: 1px solid;
border-top: 0;
border-bottom: 0;
padding-left: 0.5rem;
text-align: left;
}
header #invoice {
text-align: right;
}
table tbody td {
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
main {
display: flex;
flex-direction: column;
height: 100%;
}
#invoiceitems {
display: block;
height: 100%;
text-transform: uppercase;
}
#itemscontent {
height: 100%;
display: grid;
/*Below line is added as inline style in A4 invoice component*/
/*grid: "sno description hsn scale scale2 unit price unitprice";*/
/*grid-template-rows: repeat(2, minmax(1rem, max-content)) auto repeat(2, minmax(1rem, max-content));*/
/*grid-template-columns: minmax(min-content, max-content) minmax(min-content, auto) max-content max-content max-content max-content max-content max-content;*/
grid-auto-rows: minmax(1rem, max-content);
grid-column-gap: 1px;
align-items: center;
}
#itemscontent>div {
display: flex;
align-items: center;
border: 1px solid;
height: 100%;
border-top: 0;
border-right: 0;
padding: 0 0.25rem;
}
.border-left-0 {
border-left: 0 !important;
}
.border-bottom-0 {
border-bottom: 0 !important;
}
.border-top-1 {
border-top: 1px solid black !important;
}
.span-2 {
grid-column-start: span 2;
}
.span-3 {
grid-column-start: span 3;
}
.span-4 {
grid-column-start: span 4;
}
.span-5 {
grid-column-start: span 5;
}
.span-7 {
grid-column-start: span 7;
}
.text-darkgreen {
color: darkgreen;
}
.text-red {
color: red;
}
.bg-yellow {
background-color: yellow;
}
.flex-end {
justify-content: flex-end;
}
footer {
display: flex;
flex-direction: column;
margin-top: 10px;
}
#itemsfooter {
text-transform: uppercase;
border-left: 0 !important;
}
#itemsfooter>div {
align-self: stretch;
display: flex;
align-items: center;
padding: 0 0.5rem;
}
#amountinwords {
flex: 75%;
}
#totalamount {
flex: 25%;
text-align: right;
border-left: 1px solid black;
}
#totalamount ol {
width: 100%;
}
#totalamount ol li:last-child {
font-size: x-large;
}
#invoiceinformation {
text-transform: none;
border-left: 0 !important;
display: grid !important;
grid: "note" "bankdetails" "signature";
grid-template-columns: minmax(min-content, 40%) minmax(min-content, 35%) minmax(min-content, 25%);
padding: 0 0.5rem;
}
#invoiceinformation div {
align-self: stretch;
align-items: center;
padding: 0 0.5rem;
}
/* #note {
flex: 40%;
} */
#bankdetails {
/* flex: 35%; */
border: 1px solid;
border-top: 0;
border-bottom: 0;
}
#signature {
display: flex;
/* flex: 25%; */
border-left: 0 !important;
padding-right: 0.5rem !important;
}
#message {
display: flex;
justify-content: space-between;
border-left: 0 !important;
border-bottom: 0 !important;
padding: 0 0.5rem !important;
}
@media print {
@page {
size: A4;
}
}
<table>
<thead>
<tr>
<th>
<header>
<section id="brand">
<h1>BRAND</h1>
<h2>CAPTION</h2>
<h3>TAG LINE</h3>
<div>Address</div>
<div><b>TAX Invoice</b></div>
<section id="phone">
<ul>
<li>Phone: </li>
<li></li>
</ul>
</section>
</section>
<section id="invoicedetails">
<section id="customer-billed">
<ol>
<li>Billed To</li>
<li><b>ABC </b></li>
<li>Mobile: </li>
<li>Address: </li>
</ol>
</section>
<section id="customer-shipped">
<ol>
<li>Shipped To</li>
<li><b>ABC </b></li>
<li>Mobile: </li>
<li>Address: </li>
</ol>
</section>
<section id="invoice">
<ol>
<li>Invoice Details</li>
<li>Invoice No: <b>2/2024-25</b></li>
<li>DC No: <b>2102</b></li>
<li>Invoice Date: <b>01 Apr 2024</b></li>
<li>Payment Mode: <b>Credit</b></li>
<li>Payment Status: <b>Due</b></li>
</ol>
</section>
</section>
</header>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<main style="padding-bottom: 0">
<section id="invoiceitems">
<section id="itemscontent"
style="grid: sno description hsn scale price unit unitprice; grid-template-columns: repeat(7, auto); grid-template-rows: repeat(9, auto)">
<div class="border-left-0">S.No</div>
<div>Description</div>
<div><b></b></div>
<div>Days</div>
<div>Unit</div>
<div>Price</div>
<div>Unit Price</div>
<div id="invoiceinformation" class="span-7">
<div id="note">
<small>NOTE</small>
<br>
<text>Certified that the particulars
given above are true and correct</text>
</div>
<div id="bankdetails">
<small>COMPANY BANK DETAILS</small>
<br>
<text>BANK:
ABC BANK, A/C. NO: 1111111111111111, IFSC: IABC0000000, Branch: DEF
Road, GHI</text>
</div>
<div id="signature">
<text><b>for ABC</b>
<br>
<br>
<br>Authorized Signatory</text>
</div>
</div>
</section>
</section>
</main>
</td>
</tr>
</tbody>
</table>
PS. I advise you to use a grid instead of a table for the overall layout as well.