Forum Moderators: not2easy
The alternative would be to use a child selector which would select only the top level <td>s, but won’t work in IE5 or 6:
table#one>tr>td { border-bottom: 1px solid black; } or, if you’re using XHTML:
table#one>tbody>tr>td { border-bottom: 1px solid black; } On a different note, are you sure you need to use nested tables? They can pose a fairly severe accessibility issue.
Using that advice I made my nested table. The inheritance does NOT break. The top table has a border-bottom, the nested table shouldn't but still does. Even more annoyingly I made a test page which WORKS! So, here is the code that works, you might want to replace the indents to see it properly:
#one TD {border: 1px solid black;}
#one TR.title { font-weight: bold; }#two { border: 1px solid blue; }
#two TD {border: 0;}<table id='one'>
<tr class='title'>
<td>Cell 1</td>
</tr><tr>
<td>
<table id='two'>
<tr><td>Cell 2</td><td>Cell 3</td></tr>
</table>
</td>
</tr>
</table>
The 2 cells in table 1 have a black border, fine. Table 2 has it's blue border, and the cells have none, also fine. Great.
Now the code that doesn't work (I've cut out the irrelevant bits):
TABLE#pagelayout { width: 100%; height: 100%; }
TABLE#pagelayout TD { border-bottom: 1px solid black; }
TABLE#pagelayout TR.title { height: 100px; background: lightblue; }
TABLE#pagelayout TR.title TD { padding: 1.5em; }
TABLE#pagelayout TR.navTR { height: 3em; background: lightcyan; }
TABLE#pagelayout TR.navTR TD { padding: 0.5em 1.5em; }
TABLE#pagelayout TR.footer { height: 9%; background: gainsboro; }
TABLE#pagelayout TR.footer TD { padding: 0; text-align: center; }TABLE#info { background: lightblue; border: 1px solid blue; }
TABLE#info TH { font-weight: bold; }
TABLE#info TD { border: 0; }<table id="pagelayout">
<tr class='title'><td>Text</td></tr>
<tr class='navTR'><td>Text</td></tr>
<tr>
<td>
<div class='container scroll'>
<div id='screenstuff'>
<table id='info'>
<tr><th></th><th>Width</th><th>Height</th><th>Aspect</th></tr>
<tr><td>Screen</td><td>#*$!</td><td>#*$!</td><td>#*$!</td></tr>
<tr><td>Client Area</td><td>#*$!</td><td>#*$!</td><td>#*$!</td></tr>
</table></div>
</div>
</td>
</tr>
<tr class='footer'><td>Text</td></tr>
</table>
Again you'll want to indent it. As you can see by the nested table's content this is JS generated, but that's a copy of the markup it generates.
Please please find the error!
* { margin: 0; padding: 0; border: 0; }
TABLE { border-collapse: collapse; }
The only other difference is the nested table is written by JS and inserted after the page has loaded, but other styles still apply so I don't think this is it. I also tried that in my test file anyway.
Can I send you a URI so you can have a proper look at the full code?
Both of your rules have the same specificity. Therefore, whichever is defined LAST will be the one used. In your case, you are defining the rules for your inner table first in your CSS source, and then defining the rules for the outer table after that. Since they have the same specificity, the one defined later in the source code will get used.
To fix this, just move the rules for your inner table below the rules for your outer table. Alternatively (and probably a better option), you could increase the specificity of the inner table rules so that it will be "more specific". For example, instead of this:
TABLE#info { background: lightblue; border: 1px solid blue; }
TABLE#info TH { font-weight: bold; }
TABLE#info TD { border: 0; }
You could do this:
TABLE TABLE#info { background: lightblue; border: 1px solid blue; }
TABLE TABLE#info TH { font-weight: bold; }
TABLE TABLE#info TD { border: 0; }
Thus, any table with the id of info that also has a table anscestor will have rules of higher specificity, so it won't matter where they are placed in the CSS file.
Hope that helps.
PS- Here's the part in the CSS spec that talks about specificity:
[w3.org...]
[edited by: Fotiman at 6:58 pm (utc) on April 11, 2007]
I can't believe it was that simple, I didn't realise CSS accounted for order of definition. I have read the basics on the specs, but more than a few paragraphs I have to admit I tune out.
Using this, if I did this:
TABLE TABLE TD { basic TD defaults }
Would it then set a precedent for any nested table in any order? Obviously this would go at the top of the CSS?
Using this, if I did this:TABLE TABLE TD { basic TD defaults }
Would it then set a precedent for any nested table in any order? Obviously this would go at the top of the CSS?
Yes it would... however, that rule has a very low specificity.
0,0,0,3
A rule that uses an id like:
TABLE#pageLayout TD
will have a specificity of:
0,1,0,2
Which is a much higher specificity, so it would override your generic rule. That means that even nested tables would use the rules defined by this style because it has a higher specificity.
I see now that my 3 storm troopers are no match for a sith, so I modify my scenario as follows:
TABLE#pagelayout would always be the root, so really any table would be nested inside this, so
TABLE#pagelayout TABLE TD { defaults }
would be the answer? As now we have our sith and 3 storm troopers on the same side?
this is the bit where the ID (your sith) truly comes into its own - BUT! although specificity is one of my favourite topics you do know what CSS stands for?
the C in CSS stands for "Cascading" so that should be your first point of attack use the Cascade, i.e. apply the styles in order of the cascade start at the top and work down .. you should only need to use specificity if there is no other way to target your prey (e.g. a cms or a template file has set defaults) . If you then discover like this thread suggests that you need to "lock on" to a target then ID will be your friend
Unfortunately, you can read as many specs as you like but this doesn't teach you how to actually use the stuff in real life. I came to the conclusion that you give everything an ID, and use classes below that. I assume from this exercise this is not a good way to do it.
If I use 'TABLE#pagelayout TABLE TD' Then I can't override with 'TABLE#info TD' cos I've not got enough storm troopers.
So, ignoring the CSS I already have, how would you use the selectors to get over this problem? I basically want any TABLE inside the #pagelayout to reset to some defaults, in this case removing the border, but then can be overridden as normal.
#pagelayout td { border-bottom: 1px solid black; }
#pagelayout td td { border-bottom: 0; } One sith and two stormtroopers narrowly beat one sith and one stormtrooper, causing <td>s within <td>s (nested table situation) to reset to no borders.