Home > OS >  How to Fix the TD elements of first column of the table body while the rows are scrolling?
How to Fix the TD elements of first column of the table body while the rows are scrolling?

Time:05-08

The title is not clear, I know. Let me explain what I mean:

First column has td elements which have varying rowspans. What I want is to keep the td text in first column 'fixed' at the top while scrolling down. But only as long as the rest of the td elements in the remaining columns are in scope. Once all the rows (which the first column cell is spanning) is out of table view, the td element should scroll out of the view and the next td should now start fixing.

Initial Table

After Scrolling a bit:

Headers are already fixed, but no the td in first column which as rowspan=9 is also fixed

And after All the animal rows are scrolled out, the fixed 'Animal' td would also go up and then 'Cars' would be fixed and then Hats would be fixed like this:

enter image description here

CodePudding user response:

I got it working by setting vertical-align: top; for the element and created a div under the td element which contains the actual value for the cell

then applied position: sticky; top:0; z-index: 1; to the div.

Working fiddle: https://jsfiddle.net/ankitkraken/yw0jhzpu/1/

HTML:

<td  rowspan="3">
    <div >
       "Cars"
    </div>
</td>

CSS:

.td-class-names{
    vertical-align: top;
}

.level-1{
    
    position: sticky ;
    top: 80px;
    z-index: -1;    
}

I had to use top: 80px;, top:0; was putting the td contents BEHIND the sticky table header.

CodePudding user response:

You can acheive this result with the sticky positioning:

thead tr:first-of-type {
  position: sticky;
  top: 0px;
  z-index: 10;
}

thead tr:first-of-type th {
  background: yellow;
}

th {
  border: 1px solid;
  padding: 6px;
}

td {
  border: 1px solid;
  padding: 6px;
}

th[rowspan]>.box {
  vertical-align: top;
  position: sticky;
  top: 34px;
}

th[rowspan][data-order='first'] {
  background: orange;
}

th[rowspan][data-order='second'] {
  background: green;
}

th[rowspan][data-order='third'] {
  background: indianred;
}

th[rowspan][data-order='fourth'] {
  background: lightblue;
}

.main-container {
  position: relative;
}

.table-container {
  position: static;
  max-height: 180px;
  max-width: 350px;
  ;
  overflow-y: scroll;
}

.fake {
  width: 100%;
  height: 100px;
}
<div >
  <div class='table-container'>
    <table>
      <thead>
        <tr>
          <th>CATEGORY</th>
          <th>TYPE</th>
          <th>NAME</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <th data-order='first' rowspan='5'>
            <div class='box'>Animals</div>
          </th>
          <td>Dog</td>
          <td>Bob</td>
        </tr>
        <tr>
          <td>Dog</td>
          <td>Flash</td>
        </tr>
        <tr>
          <td>Cat</td>
          <td>Mimi</td>
        </tr>
        <tr>
          <td>Dog</td>
          <td>Casper</td>
        </tr>
        <tr>
          <td>Horse</td>
          <td>Wind Lady</td>
        </tr>

        <tr>
          <th data-order='second' rowspan='5'>
            <div class='box'>Cars</div>
          </th>
          <td>Chrysler</td>
          <td>Ann</td>
        </tr>
        <tr>
          <td>Dodge</td>
          <td>Christine</td>
        </tr>
        <tr>
          <td>Ford</td>
          <td>Foo</td>
        </tr>
        <tr>
          <td>Ferrari</td>
          <td>Dandy</td>
        </tr>
        <tr>
          <td>Mercedes</td>
          <td>A200</td>
        </tr>

        <tr>
          <th data-order='third' rowspan='5'>
            <div class='box'>Food</div>
          </th>
          <td>Apple</td>
          <td>George</td>
        </tr>
        <tr>
          <td>Banana</td>
          <td>Rocco</td>
        </tr>
        <tr>
          <td>Strawberry</td>
          <td>Liza</td>
        </tr>
        <tr>
          <td>Ananas</td>
          <td>Ted</td>
        </tr>
        <tr>
          <td>Avocado</td>
          <td>Gary</td>
        </tr>

        <tr>
          <th data-order='fourth' rowspan='5'>
            <div class='box'>Phones</div>
          </th>
          <td>Iphone XXI</td>
          <td>ObiWan</td>
        </tr>
        <tr>
          <td>Nokia 8110</td>
          <td>Neo</td>
        </tr>
        <tr>
          <td>Ericsson</td>
          <td>Dr. Who</td>
        </tr>
        <tr>
          <td>Huawei Mate 40</td>
          <td>Dead or Alive</td>
        </tr>
        <tr>
          <td>Xiaomi</td>
          <td>Ping</td>
        </tr>
      </tbody>
    </table>

    <div class='fake'>
    </div>
  </div>
</div>

Sticky positioning is not always straightforward, expecially when dealing with overflow properties and display: table. Here are some useful resources about these topics:

  • Related