Search code examples
htmlcsscss-selectorspseudo-class

Styling odd/even rows of a table differently


I have the following HTML:

<table id="price-table">
            <tr><th>Price</th><th>Value</th></tr>
            <tr class="price-row">
                <td>0</td>
                <td>1</td>
            </tr>

            <tr><th>Price</th><th>Value</th></tr>
            <tr class="price-row">
                <td>1</td>
                <td>2</td>
            </tr>
</table>

I am trying to style every odd row with the class price-row using the following:

#price-table tr.price-row:nth-child(odd) {
    color: green;
}

And every even row using:

#price-table tr.price-row:nth-child(even) {
    color: blue;
}

However only the even rows are being styled, and the odd rows are being completely ignored. I don't understand why this is? Doesn't the first row have the id of 1 which would be styled as odd, and the second row have an id of 2 being styled as even?

I should mention that I do expect for this table to be expandable such that further rows are able to be added and correctly styled.

Very confused I have no idea what else to try, this doesn't seem complicated unless I'm making a very silly mistake.

Edit full HTML:

<table id="price-table">
  <tr>
    <th>Price</th>
    <th>Value</th>
  </tr>
  <tr class="price-row">
    <td>0</td>
    <td>1</td>
  </tr>
  <tr>
    <th>Price</th>
    <th>Value</th>
  </tr>
  <tr class="price-row">
    <td>1</td>
    <td>2</td>
  </tr>
   <tr>
    <th>Price</th>
    <th>Value</th>
  </tr>
  <tr class="price-row">
    <td>0</td>
    <td>1</td>
  </tr>
  <tr>
    <th>Price</th>
    <th>Value</th>
  </tr>
  <tr class="price-row">
    <td>1</td>
    <td>2</td>
  </tr>
</table>

Solution

  • You need to remove the selector in the tr, otherwise it only select the tr with that class, which are always even in your HTML structure

    tr:nth-child(odd) {
      background-color: green;
    }
    
    tr:nth-child(even) {
      background-color: blue;
    }
    <table id="price-table">
      <tr>
        <th>Price</th>
        <th>Value</th>
      </tr>
      <tr class="price-row">
        <td>0</td>
        <td>1</td>
      </tr>
      <tr>
        <th>Price</th>
        <th>Value</th>
      </tr>
      <tr class="price-row">
        <td>1</td>
        <td>2</td>
      </tr>
    </table>

    UPDATE (based on op comment)

    Thank you for the reply, but my aim is to not style the rows containing "price value"

    Use the sibling selector (+ and ~) then

    /* this will select every .price-row that has a TR as immediate previous sibling*/
    
    tr+.price-row {
      background-color: green;
    }
    
    
    /*this will select every .price-row after the other .price-row */
    
    .price-row~.price-row {
      background: blue
    }
    <table id="price-table">
      <tr>
        <th>Price</th>
        <th>Value</th>
      </tr>
      <tr class="price-row">
        <td>0</td>
        <td>1</td>
      </tr>
      <tr>
        <th>Price</th>
        <th>Value</th>
      </tr>
      <tr class="price-row">
        <td>1</td>
        <td>2</td>
      </tr>
    </table>


    UPDATE2 (based on op comment)

    Thanks for the updated answer. However this only appears to style the first row after the first "price-row" row. After that no other odd rows which have the class "price-row" are styled as odd, only even?

    You can use the nth-child() like below

    tr:nth-child(2n+2) {
      background: red
    }
    
    
    tr:nth-child(4n+2) {
      background: blue
    }
    <table id="price-table">
      <tr>
        <th>Price</th>
        <th>Value</th>
      </tr>
      <tr class="price-row">
        <td>0</td>
        <td>1</td>
      </tr>
      <tr>
        <th>Price</th>
        <th>Value</th>
      </tr>
      <tr class="price-row">
        <td>1</td>
        <td>2</td>
      </tr>
      <tr>
        <th>Price</th>
        <th>Value</th>
      </tr>
      <tr class="price-row">
        <td>0</td>
        <td>1</td>
      </tr>
      <tr>
        <th>Price</th>
        <th>Value</th>
      </tr>
      <tr class="price-row">
        <td>1</td>
        <td>2</td>
      </tr>
      <tr>
        <th>Price</th>
        <th>Value</th>
      </tr>
      <tr class="price-row">
        <td>1</td>
        <td>2</td>
      </tr>
    <tr>
        <th>Price</th>
        <th>Value</th>
      </tr>
      <tr class="price-row">
        <td>1</td>
        <td>2</td>
      </tr>
    </table>