0

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

Ankit Singh
  • 117
  • 1
  • 7

2 Answers2

1

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 class="td-class-name" rowspan="3">
    <div class="level-1">
       "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.

Ankit Singh
  • 117
  • 1
  • 7
0

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 class="main-container">
  <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:

cheesyMan
  • 1,494
  • 1
  • 4
  • 13