Search code examples
htmlcsshtml-tablecss-grid

Nested CSS Grid overflows horizontally when placed inside HTML table element


I have a css grid in invoice generated dynamically. I know the number of rows and column in advance. I'm also using template rows and template columns and defining column width for each column specifically as I need this in invoice in same format. So I'm not able to use auto values.

To simplify with code sample, lets say I have a grid with exactly 7 columns and 2 rows. The first row has 7 columns. The second row has 1 column which spans to 7 columns. This 1 column in second row has a nested grid with 1 row 3 column. This works as expected when I have this setup in my html as shown below.

enter image description here

Edit: As per first comment I added non working scenario. But then this made me to realise this version is also having problem.

Here is the code snippet:

<html>

<head>
    <style type="text/css">
        body {
            font-family: Calibri, monospace;
            font-size: 0.8rem;
            margin: 1rem;
            border: 1px solid;
        }

        table {
            width: 100%;
            height: 100%;
            border-collapse: collapse;
            page-break-inside: auto;
        }

        td section div {
            page-break-inside: avoid;
        }

        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;
            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;
        }

        .span-7 {
            grid-column-start: span 7;
        }

        #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;
        }

        #bankdetails {
            border: 1px solid;
            border-top: 0;
            border-bottom: 0;
        }

        #signature {
            display: flex;
            border-left: 0 !important;
            padding-right: 0.5rem !important;
        }
    </style>
</head>

<body>
    <main style="padding-bottom: 0">
        <section id="invoiceitems">
            <section id="itemscontent"
                style="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>
</body>

</html>

But this breaks and overflows horizontally when I place the entire setup inside table as shown below.

enter image description here

The reason for using table is that when the invoice goes for multiple pages, thead element will help to place header in all pages. Now I'm confused on what is the difference table brings in that causes horizontal scroll and overflow to appear.

Here is the code snippet.

<html>

<head>
    <style type="text/css">
        body {
            font-family: Calibri, monospace;
            font-size: 0.8rem;
            margin: 1rem;
            border: 1px solid;
        }

        table {
            width: 100%;
            height: 100%;
            border-collapse: collapse;
            page-break-inside: auto;
        }

        td section div {
            page-break-inside: avoid;
        }

        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;
            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;
        }

        .span-7 {
            grid-column-start: span 7;
        }

        #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;
        }

        #bankdetails {
            border: 1px solid;
            border-top: 0;
            border-bottom: 0;
        }

        #signature {
            display: flex;
            border-left: 0 !important;
            padding-right: 0.5rem !important;
        }
    </style>
</head>

<body>
    <table>
        <tbody>
            <tr>
                <td>
                    <main style="padding-bottom: 0">
                        <section id="invoiceitems">
                            <section id="itemscontent"
                                style="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>

Please can you assist me?


Solution

  • It’s nothing to do with being wrapped in a table. Even when it’s not wrapped in a table it still overflows.

            body {
                font-family: Calibri, monospace;
                font-size: 0.8rem;
                margin: 1rem;
                border: 1px solid;
            }
    
            table {
                width: 100%;
                height: 100%;
                border-collapse: collapse;
                page-break-inside: auto;
            }
    
            td section div {
                page-break-inside: avoid;
            }
    
            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;
                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;
            }
    
            .span-7 {
                grid-column-start: span 7;
            }
    
            #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;
            }
    
            #bankdetails {
                border: 1px solid;
                border-top: 0;
                border-bottom: 0;
            }
    
            #signature {
                display: flex;
                border-left: 0 !important;
                padding-right: 0.5rem !important;
            }
        <main style="padding-bottom: 0">
            <section id="invoiceitems">
                <section id="itemscontent"
                    style="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>

    The issue is not the table, it’s your use of max-content, which means “avoid wrapping at all costs: I would rather overflow than wrap!”

    For building an invoice layout, I would have thought you'd want to use percentages for your column widths, something like this:

    grid-template-columns: 10% 25% 25% 10% 10% 10% 10%;
    

    body {
                font-family: Calibri, monospace;
                font-size: 0.8rem;
                margin: 1rem;
                border: 1px solid;
            }
    
            table {
                width: 100%;
                height: 100%;
                border-collapse: collapse;
                page-break-inside: auto;
            }
    
            td section div {
                page-break-inside: avoid;
            }
    
            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;
                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;
            }
    
            .span-7 {
                grid-column-start: span 7;
            }
    
            #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;
            }
    
            #bankdetails {
                border: 1px solid;
                border-top: 0;
                border-bottom: 0;
            }
    
            #signature {
                display: flex;
                border-left: 0 !important;
                padding-right: 0.5rem !important;
            }
    <table>
      <tr>
        <td>
          <main style="padding-bottom: 0">
            <section id="invoiceitems">
              <section id="itemscontent"
                  style="grid-template-columns: 10% 25% 25% 10% 10% 10% 10%;">
    
                  <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>
    </table>