Critical Section

of nested CSS selectors

Friday,  01/09/15  11:04 PM

<rant nerdlevel="11">

Today I actually used this selector in a style sheet:

table:not([bordercolor="#C0C0C0"]) > tbody > tr[bgcolor="#ffff99"]
  { display: block; border-radius: 15px; box-shadow: 2px 2px 4px #a0a0a0 }

Figuring out I needed to do this took me deep into the arcana of CSS selectors.  As you know, with CSS you specify the object(s) you want to style, and then what you want to do with them.  The specification of objects(s) is accomplished via selectors.  I had used the three most simple selectors before: specification by tag type (<tag>), specification by class (.<class>), and specification by id (#<id>).  For this case I wanted to style specific <tr>s unless they were inside a specific <table>s.

The <tr>s to be styled could be identified via their background color, hence, tr[bgcolor="#ffff99"].  The <table>s to be excluded could be identified via their border color, hence table[bordercolor="#C0C0C0"], specified with the :not property.  So at first* I tried this:

table:not([bordercolor="#C0C0C0"]) tr[bgcolor="#ffff99"]
  { display: block; border-radius: 15px; box-shadow: 2px 2px 4px #a0a0a0 }

But no joy in Mudville, it didn't work.  Huh?

The tr[bgcolor="#ffff99"] selector selects the <tr>s I want (I experimented to verify), and the table:not([bordercolor="#C0C0C0"]) selector selects all tables except the ones I want to exclude (I experimented to verify).  But no workey.  The <tr>s inside the <table> s were *still* selected and styled.

After a lot of extended messing around, I figured it out.  Turns out the <tr>s in question were inside the <table>s in question, but those tables were themselves nested inside a table which was not excluded.  Separating two selectors by a space only requires nesting, not immediate nesting.  Aha!

So next I tried this: 

table:not([bordercolor="#C0C0C0"]) > tr[bgcolor="#ffff99"]
  { display: block; border-radius: 15px; box-shadow: 2px 2px 4px #a0a0a0 }

The ">" means immediate nesting, the first selector must be the direct parent of the second.  But that didn't work either.  One more insight later, I realized that all <table>s actually have a <tbody>, even if it isn't explicitly specified, and so the <tr>s are actually nested inside a <tbody>, which in turn is inside the <table>.  Hence the selector shown at top, which worked (yay!).

You can see the result here.  I'm quite proud of myself :)


* The "at first" part of this is a lie; understanding attribute selectors and :not required a lot of Googling.

this date in:
About Me

Greatest Hits
Correlation vs. Causality
The Tyranny of Email
Unnatural Selection
On Blame
Try, or Try Not
Books and Wine
Emergent Properties
God and Beauty
Moving Mount Fuji
The Nest
Rock 'n Roll
IQ and Populations
Are You a Bright?
Adding Value
The Joy of Craftsmanship
The Emperor's New Code
Toy Story
The Return of the King
Religion vs IQ
In the Wet
solving bongard problems
visiting Titan
unintelligent design
the nuclear option
estimating in meatspace
second gear
On the Persistence of Bad Design...
Texas chili cookoff
almost famous design and stochastic debugging
may I take your order?
universal healthcare
triple double
New Yorker covers
Death Rider! (da da dum)
how did I get here (Mt.Whitney)?
the Law of Significance
Holiday Inn
Daniel Jacoby's photographs
the first bird
Gödel Escher Bach: Birthday Cantatatata
Father's Day (in pictures)
your cat for my car
Jobsnotes of note
world population map
no joy in Baker
vote smart
exact nonsense
introducing eyesFinder
to space
where are the desktop apps?
still the first bird
electoral fail
progress ratches
2020 explained