Conrad.Dean
Conrad.Dean

Reputation: 4421

Not understanding the Child Selector

I have some legacy layouts with nested tables.

I'd like the parent table's <td>s to have borders of one color, while the inner tables have none.

Here:

<html>
  <head>
    <style>
      table tr td{
    border:none;
      }
      table.listTable tr  td
      {
    border:1px solid red;
      }
    </style>
  </head>
  <body>
    <table class="listTable">
      <tr>
    <td>
      left
    </td>

    <td>
      <table style="width:100%;">
        <tr>
          <td>
        1
          </td>
          <td>
        2
          </td>
        </tr>
      </table>
    </td>

    <td>
      right
    </td>
      </tr>
      <tr>
    <td>
      left
    </td>
    <td>
      doubles
    </td>
    <td>
      right
    </td>
      </tr>
    </table>
  </body>
</html>

How do I get the subcells labeled 1 and 2 in the top middle cell to not have the red CSS applied to them by modifying the .listTable css selector?

This seems like what I want:

table.listTable > tr td

But it breaks the selector entirely.

Could someone explain what selector I need, and also why the selector I've tried breaks the layout?

This on jsfiddle: http://jsfiddle.net/nvZbq/

Upvotes: 1

Views: 142

Answers (3)

Mark Schultheiss
Mark Schultheiss

Reputation: 34178

The issue is the specificity of the selector with the borders. It is MORE specific than the one without.

There are several ways to accomplish this.

One way would be to ADD specificity to the innner table selector:

table.listTable table tr td

EDIT NOTE: the "child" vs "direct child" comes into play with the '>' in your selector when some browsers add the tbody, and some not.

table.listTable tr  td       {     border:1px solid red;       } 
table.listTable table tr td{     border:none;       } 

example: http://jsbin.com/oyihop/edit#javascript,html,live

Upvotes: 0

KP.
KP.

Reputation: 13730

table.listTable > tbody > tr > td{
    border:1px solid red;
}

Add the > between tr and td. Remember it signifies a direct child, so table.listTable > tbody > tr > td is describing a table cell (td) that is a direct child of a table row (tr) that is a direct child of a table with the class listTable. The nested table within should not pick up the style now.

Your original style of table.listTable > tr td has two issues. First it signifies ANY td that is nested ANYWHERE below a table row that is a direct child of a table with class listTable. That's why the original style applies the red top border to the sub table. It would do the same for any <td> tag nested below the root table. Second as Matt corrected me below, the browser will insert a <tbody> tag in the table so you need to include it in the CSS selector chain or the direct descendants rules won't work. (Thanks Matt)

Hope this helps.

Upvotes: 1

Matt Ball
Matt Ball

Reputation: 359856

Look at the generated markup in Firebug or other browser dev tool of your choice. You'll see that <tr>s aren't actually child elements of <table>s. If you don't use a <tbody>, the browser will add one for you.

So here's the selector to use:

table.listTable > tbody > tr > td

Upvotes: 4

Related Questions