Search code examples
javascriptcss

Alternating rows background - updating dynamically when hiding/showing rows with css only?


I have a table ".report" and it should have alternating background for its rows. The UI allows users to hide and show rows dynamically and I want the background of the rows to keep the pattern at all times. I implemented the solution where I add the ".hidden" class to the hidden rows and set the background-color attr to shown rows only and then set the background to "nth-of-type" accordingly. But it doesn't work. It seen the nth-of-type doesn't take the ":not(.hidden)" rule into consideration. Is it possible to resolve this with CSS only? I know I can change the background with JS but I'd rather avoid it and use css only if possible.

restoreRow: function(key) {
    let row = $("#" + key);
    row.show();
    row.removeClass("hidden");
},

removeRow: function(key) {
    let row = $("#" + key)
    row.hide();
    row.addClass("hidden");
},
.report tbody tr:not(.hidden):nth-of-type(even) {
    background-color: $white;
}

.report tbody tr:not(.hidden):nth-of-type(odd) {
    background-color: red;
}

Solution

  • Yes, with the new nth-child(n-of-x) selector

    tr:nth-child(odd of :not(.hidden)) {
      background: lightgreen;
    }
    
    tr:nth-child(even of :not(.hidden)) {
      background: lightblue;
    }
    

    table {
      border: 1px solid grey;
      margin-bottom: 2em;
    }
    td {
      border: 1px solid red;
    }
    
    .hidden {
      display: none;
    }
    
    tr:nth-child(odd of :not(.hidden)) {
      background: lightgreen;
    }
    
    tr:nth-child(even of :not(.hidden)) {
      background: lightblue;
    }
    <p>No rows hidden</p>
    
    <table>
      <tr>
        <td>Item 1</td>
        <td>Item 2</td>
        <td>Item 3</td>
        <td>Item 4</td>
      </tr>
      <tr>
        <td>Item 1</td>
        <td>Item 2</td>
        <td>Item 3</td>
        <td>Item 4</td>
      </tr>
      <tr>
        <td>Item 1</td>
        <td>Item 2</td>
        <td>Item 3</td>
        <td>Item 4</td>
      </tr>
      <tr>
        <td>Item 1</td>
        <td>Item 2</td>
        <td>Item 3</td>
        <td>Item 4</td>
      </tr>
    </table>
    
    <p>2nd row is hidden</p>
    
    <table>
      <tr>
        <td>Item 1</td>
        <td>Item 2</td>
        <td>Item 3</td>
        <td>Item 4</td>
      </tr>
      <tr class="hidden">
        <td>Item 1</td>
        <td>Item 2</td>
        <td>Item 3</td>
        <td>Item 4</td>
      </tr>
      <tr>
        <td>Item 1</td>
        <td>Item 2</td>
        <td>Item 3</td>
        <td>Item 4</td>
      </tr>
      <tr>
        <td>Item 1</td>
        <td>Item 2</td>
        <td>Item 3</td>
        <td>Item 4</td>
      </tr>
    </table>