csshtml-tablecellstickyfixed-header-tables

position:sticky is not working on merged cell


I want to fix the first and second columns of a table in left when the table scrolls horizontally. I used position:sticky for column fixation and it works fine on normal columns. However, I have merged cells in my table and sticky does not work properly on these merged cells.

enter image description here

Here's a reproduction link.

Could someone kindly share insights into the cause of this issue and propose potential solutions to resolve it? Thank you.

body {
                background-color: #f7f7f7;
            }
            .container {
                margin: 0 auto;
                margin-top: 100px;
                width: 500px;
                overflow: auto;
                background-color: #fff;
            }

            table {
                width: 800px;
                border-collapse: collapse;
                border-spacing: 0;
                text-align: left;

                td,
                th {
                    border-bottom: 1px solid #000;
                    padding: 8px 12px 8px 16px;
                }

                .sticky {
                    position: sticky;
                    left: 0;
                    z-index: 1;
                    background-color: #fff;
                }

                .sticky-tow {
                    left: 80px;
                }

                .sticky-tow::after {
                    position: absolute;
                    top: 0;
                    right: 0;
                    bottom: -1px;
                    width: 15px;
                    transition: background 0.3s;
                    content: '';
                    pointer-events: none;
                    background-image: linear-gradient(
                        to right,
                        rgba(0, 0, 0, 0.08) 0%,
                        rgba(0, 0, 0, 0) 100%
                    );
                }
            }
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Table</title>
    </head>
    <body>
        <div class="container">
            <table style="table-layout: fixed">
                <colgroup>
                    <col width="80" />
                    <col width="160" />
                    <col width="80" />
                    <col width="80" />
                </colgroup>
                <thead>
                    <tr>
                        <th class="sticky">Id</th>
                        <th class="sticky sticky-tow">Name</th>
                        <th>Age</th>
                        <th>Sex</th>
                        <th>Address</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td colspan="5" class="sticky">SEX: Male</td>
                    </tr>
                    <tr>
                        <td class="sticky">1</td>
                        <td class="sticky sticky-tow">John Doe</td>
                        <td>25</td>
                        <td>male</td>
                        <td>123 Main St, Springfield, IL</td>
                    </tr>
                    <tr>
                        <td class="sticky">2</td>
                        <td class="sticky sticky-tow">John Doe</td>
                        <td>25</td>
                        <td>male</td>
                        <td>123 Main St, Springfield, IL</td>
                    </tr>
                    <tr>
                        <td class="sticky">3</td>
                        <td class="sticky sticky-tow">John Doe</td>
                        <td>25</td>
                        <td>male</td>
                        <td>123 Main St, Springfield, IL</td>
                    </tr>
          <tr>
                        <td colspan="5" class="sticky">SEX: Female</td>
                    </tr>
                    <tr>
                        <td class="sticky">4</td>
                        <td class="sticky sticky-tow">John Doe</td>
                        <td>25</td>
                        <td>male</td>
                        <td>123 Main St, Springfield, IL</td>
                    </tr>
                    <tr>
                        <td class="sticky">5</td>
                        <td class="sticky sticky-tow">John Doe</td>
                        <td>25</td>
                        <td>male</td>
                        <td>123 Main St, Springfield, IL</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </body>
</html>

I try to change colpan="5" to colspan="1" on merged cell,and sticky is back to working properly.

I expect sticky to work fine on merged cells.


Solution

  • Sticky functionality works well even with merged cells. However, when a row has a colspan of 5, it occupies the entire width, which prevents the sticky behavior from functioning as expected.

    To resolve this, you can reduce the colspan to 2, matching the other columns, and add an empty <td colspan="3"></td>. This approach will allow the sticky behavior to work as intended while maintaining the correct layout.

    Working Screenshot

    body {
      background: #6e28d9;
      height: 100vh;
    }
    
    .container {
        margin: 0 auto;
        margin-top: 100px;
        width: 500px;
        overflow: auto;
        background-color: #fff;
    }
    
    table {
        width: 800px;
        border-collapse: collapse;
        border-spacing: 0;
        text-align: left;
    
        td,
        th {
            border-bottom: 1px solid #000;
            padding: 8px 12px 8px 16px;
        }
    
        .sticky {
            position: sticky;
            left: 0;
            z-index: 1;
            background-color: #fff;
        }
    
        .sticky-tow {
            left: 80px;
        }
    
        .sticky-tow::after {
            position: absolute;
            top: 0;
            right: 0;
            bottom: -1px;
            width: 15px;
            content: '';
            pointer-events: none;
            background-image: linear-gradient(
                to right,
                rgba(0, 0, 0, 0.08) 0%,
                rgba(0, 0, 0, 0) 100%
            );
        }
    }
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <link rel="stylesheet" href="src/style.css" />
      </head>
      <body>
        <div class="container">
          <table style="table-layout: fixed">
            <colgroup>
              <col width="80" />
              <col width="160" />
              <col width="80" />
              <col width="80" />
            </colgroup>
            <thead>
              <tr>
                <th class="sticky">Id</th>
                <th class="sticky sticky-tow">Name</th>
                <th>Age</th>
                <th>Sex</th>
                <th>Address</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td colspan="2" class="sticky">SEX: Male</td>
                <td colspan="3"></td>
              </tr>
    
              <tr>
                <td class="sticky">1</td>
                <td class="sticky sticky-tow">John Doe</td>
                <td>25</td>
                <td>male</td>
                <td>123 Main St, Springfield, IL</td>
              </tr>
              <tr>
                <td class="sticky">2</td>
                <td class="sticky sticky-tow">John Doe</td>
                <td>25</td>
                <td>male</td>
                <td>123 Main St, Springfield, IL</td>
              </tr>
              <tr>
                <td class="sticky">3</td>
                <td class="sticky sticky-tow">John Doe</td>
                <td>25</td>
                <td>male</td>
                <td>123 Main St, Springfield, IL</td>
              </tr>
    
              <tr>
                <td colspan="2" class="sticky">SEX: Female</td>
                <td colspan="3"></td>
              </tr>
    
              <tr>
                <td class="sticky">4</td>
                <td class="sticky sticky-tow">John Doe</td>
                <td>25</td>
                <td>male</td>
                <td>123 Main St, Springfield, IL</td>
              </tr>
              <tr>
                <td class="sticky">5</td>
                <td class="sticky sticky-tow">John Doe</td>
                <td>25</td>
                <td>male</td>
                <td>123 Main St, Springfield, IL</td>
              </tr>
            </tbody>
          </table>
        </div>
      </body>
    </html>