Search code examples
cssz-indexsticky

Sticky column creates stacked stacking contexts


I have a table with a sticky column. When I view at this table in a 3d viewer, I can see every column has a higher z-index than the column before. So when I want to use a dropdown in this column, it is always covered by the column on the next line.

td {
  white-space: nowrap;
}

.fixed-column {
  position: fixed;
  right: 0;
  background-color: white;
  padding: .5rem;
}

.dropdown-menu {
  position: fixed;
  right: 0;
  background: #0080ff;
}
<table>
  <thead>
    <tr>
      <th>Col 1</th>
      <th>Col 2</th>
      <th>Col 3</th>
      <th>Col 4</th>
      <th>Col 5</th>
      <th>Col 6</th>
      <th>Col 7</th>
      <th>Col 8</th>
      <th>Col 9</th>
      <th class="fixed-column">Col 10</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Cell 1 content with a lot of text ...</td>
      <td>Cell 2 content with a lot of text ...</td>
      <td>Cell 3 content with a lot of text ...</td>
      <td>Cell 4 content with a lot of text ...</td>
      <td>Cell 5 content with a lot of text ...</td>
      <td>Cell 6 content with a lot of text ...</td>
      <td>Cell 7 content with a lot of text ...</td>
      <td>Cell 8 content with a lot of text ...</td>
      <td>Cell 9 content with a lot of text ...</td>
      <td class="fixed-column">
        <button type="button">Menu</button>
        <div class="dropdown-menu">
          <ul>
            <li>Option 1</li>
            <li>Option 2</li>
            <li>Option 3</li>
            <li>Option 4</li>
            <li>Option 5</li>
            <li>Option 6</li>
          </ul>
        </div>
      </td>
    </tr>
    <!-- ... -->
  </tbody>
</table>

Here is a plnkr with an example: http://plnkr.co/plunk/CqqeSWIQrSsSVJB3

Here you can see a screenshot of the 3d viewer: enter image description here

Is there any way to prevent the browser to stack all these sticky cells on the z-axis so that the dropdown menu (the blue div-container) will show on top of all these cells?


Solution

  • One way to achieve that, provided you can dynamically set a class on the cell that's displaying the menu, is to set a z-index for this particular cell, which will have it rendered over the next ones:

    td {
      white-space: nowrap;
    }
    
    .fixed-column {
      position: fixed;
      right: 0;
      background-color: white;
      padding: .5rem;
    }
    
    .dropdown-menu {
      position: fixed;
      right: 0;
      background: #0080ff;
    }
    
    .withmenu {
      z-index: 1;
    }
    <table>
      <thead>
        <tr>
          <th>Col 1</th>
          <th>Col 2</th>
          <th>Col 3</th>
          <th>Col 4</th>
          <th>Col 5</th>
          <th>Col 6</th>
          <th>Col 7</th>
          <th>Col 8</th>
          <th>Col 9</th>
          <th class="fixed-column">Col 10</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Cell 1 content with a lot of text ...</td>
          <td>Cell 2 content with a lot of text ...</td>
          <td>Cell 3 content with a lot of text ...</td>
          <td>Cell 4 content with a lot of text ...</td>
          <td>Cell 5 content with a lot of text ...</td>
          <td>Cell 6 content with a lot of text ...</td>
          <td>Cell 7 content with a lot of text ...</td>
          <td>Cell 8 content with a lot of text ...</td>
          <td>Cell 9 content with a lot of text ...</td>
          <td class="fixed-column withmenu">
            <button type="button">Menu</button>
            <div class="dropdown-menu">
              <ul>
                <li>Option 1</li>
                <li>Option 2</li>
                <li>Option 3</li>
                <li>Option 4</li>
                <li>Option 5</li>
                <li>Option 6</li>
              </ul>
            </div>
          </td>
        </tr>
        <tr>
          <td>Cell 1 content with a lot of text ...</td>
          <td>Cell 2 content with a lot of text ...</td>
          <td>Cell 3 content with a lot of text ...</td>
          <td>Cell 4 content with a lot of text ...</td>
          <td>Cell 5 content with a lot of text ...</td>
          <td>Cell 6 content with a lot of text ...</td>
          <td>Cell 7 content with a lot of text ...</td>
          <td>Cell 8 content with a lot of text ...</td>
          <td>Cell 9 content with a lot of text ...</td>
          <td class="fixed-column">
            <button type="button">Menu</button>
          </td>
        </tr>
        <tr>
          <td>Cell 1 content with a lot of text ...</td>
          <td>Cell 2 content with a lot of text ...</td>
          <td>Cell 3 content with a lot of text ...</td>
          <td>Cell 4 content with a lot of text ...</td>
          <td>Cell 5 content with a lot of text ...</td>
          <td>Cell 6 content with a lot of text ...</td>
          <td>Cell 7 content with a lot of text ...</td>
          <td>Cell 8 content with a lot of text ...</td>
          <td>Cell 9 content with a lot of text ...</td>
          <td class="fixed-column">
            <button type="button">Menu</button>
          </td>
        </tr>
        <tr>
          <td>Cell 1 content with a lot of text ...</td>
          <td>Cell 2 content with a lot of text ...</td>
          <td>Cell 3 content with a lot of text ...</td>
          <td>Cell 4 content with a lot of text ...</td>
          <td>Cell 5 content with a lot of text ...</td>
          <td>Cell 6 content with a lot of text ...</td>
          <td>Cell 7 content with a lot of text ...</td>
          <td>Cell 8 content with a lot of text ...</td>
          <td>Cell 9 content with a lot of text ...</td>
          <td class="fixed-column">
            <button type="button">Menu</button>
          </td>
        </tr>
        <tr>
          <td>Cell 1 content with a lot of text ...</td>
          <td>Cell 2 content with a lot of text ...</td>
          <td>Cell 3 content with a lot of text ...</td>
          <td>Cell 4 content with a lot of text ...</td>
          <td>Cell 5 content with a lot of text ...</td>
          <td>Cell 6 content with a lot of text ...</td>
          <td>Cell 7 content with a lot of text ...</td>
          <td>Cell 8 content with a lot of text ...</td>
          <td>Cell 9 content with a lot of text ...</td>
          <td class="fixed-column">
            <button type="button">Menu</button>
          </td>
        </tr>
        <tr>
          <td>Cell 1 content with a lot of text ...</td>
          <td>Cell 2 content with a lot of text ...</td>
          <td>Cell 3 content with a lot of text ...</td>
          <td>Cell 4 content with a lot of text ...</td>
          <td>Cell 5 content with a lot of text ...</td>
          <td>Cell 6 content with a lot of text ...</td>
          <td>Cell 7 content with a lot of text ...</td>
          <td>Cell 8 content with a lot of text ...</td>
          <td>Cell 9 content with a lot of text ...</td>
          <td class="fixed-column">
            <button type="button">Menu</button>
          </td>
        </tr>
        <tr>
          <td>Cell 1 content with a lot of text ...</td>
          <td>Cell 2 content with a lot of text ...</td>
          <td>Cell 3 content with a lot of text ...</td>
          <td>Cell 4 content with a lot of text ...</td>
          <td>Cell 5 content with a lot of text ...</td>
          <td>Cell 6 content with a lot of text ...</td>
          <td>Cell 7 content with a lot of text ...</td>
          <td>Cell 8 content with a lot of text ...</td>
          <td>Cell 9 content with a lot of text ...</td>
          <td class="fixed-column">
            <button type="button">Menu</button>
          </td>
        </tr>
        <tr>
          <td>Cell 1 content with a lot of text ...</td>
          <td>Cell 2 content with a lot of text ...</td>
          <td>Cell 3 content with a lot of text ...</td>
          <td>Cell 4 content with a lot of text ...</td>
          <td>Cell 5 content with a lot of text ...</td>
          <td>Cell 6 content with a lot of text ...</td>
          <td>Cell 7 content with a lot of text ...</td>
          <td>Cell 8 content with a lot of text ...</td>
          <td>Cell 9 content with a lot of text ...</td>
          <td class="fixed-column">
            <button type="button">Menu</button>
          </td>
        </tr>
      </tbody>
    </table>

    Another solution would be to take the menu out of the <td> and assign a z-index to it, but then it would require dynamic positioning... So not a better solution.