cbmtrx
cbmtrx

Reputation: 610

Select first, next sibling :not() matching a class

I've looked through other Q&As but didn't find this particular example. (Please point me to it if I missed it)

I have no control over the HTML which looks like this:

<table>
<tbody>
<tr class="group open"><td>stuff</td></tr>
  <tr class="child"><td>stuff</td></tr>
  <tr class="child"><td>stuff</td></tr>
  ditto
<tr class="group"><td>stuff</td></tr> //Style this one only
<tr class="group"><td>stuff</td></tr>
//etc.
</tbody>
</table>

(Yes, the ".child" name is not really accurate here; not my code.)

Is it possible to style the first next tr.group sibling that isn't a tr.child? There could be any number of tr.child elements after the tr.open one.

I tried this with no success:

div.mystuff table tr.group.open + tr:not(.child)

The only thing I can add is that the tr.child elements are set to display:none on load. But this shouldn't affect styling on display:block.

Upvotes: 5

Views: 408

Answers (3)

ScottS
ScottS

Reputation: 72261

Not Possible By CSS Alone

If you were dealing with only one open element, then it could work: see this fiddle for a demo of this code:

.mystuff table .open ~ .group { /* select all */
    background: #ffff00;    
}
.mystuff table .open ~ .group ~ .group { /* revert all but first */
    background: #aaaaaa;    
}

But with multiple .open elements, or with not overriding the code even if there were only one, the issue is that you will still have other .child elements in the code, but undisplayed. However, them being undisplayed has no bearing on selection (see Adrift's answer with hidden children and my answer failing with multiple children). It is this usage of the undisplayed .child elements still for selecting that is the "superseding" behavior you are seeing in your actual case of many rows (and many hidden children); it has nothing to do with javascript overriding (as your comments indicate you suspect), its just the way CSS adjacent and general sibling selectors work.

I believe your only solution will be through javascript, here is a jquery solution (changing background color):

$('.open').each(function(index) {             
    $(this).nextAll('.group:not(.open)').first().css('background', '#ff0') 
});

Upvotes: 1

Adrift
Adrift

Reputation: 59779

You could also use:

div.mystuff table tr.group.open ~ tr.child + tr.group {
   color: sky;
}

http://jsfiddle.net/emtZC/4/

Upvotes: 1

kalley
kalley

Reputation: 18462

You can try this:

div.mystuff table tr.child + tr.group { /* your styles */ }

fiddle

Upvotes: 1

Related Questions