Select the nth following sibling

2019-04-21 14:16发布

问题:

I wondered if there is a better solution than to what I found without changing the html-structure

The HTML structure looks like this

<div class="wrap">
  <div class="divider"></div>
  <div class="block"></div>
  <div class="block"></div>
  <div class="divider"></div>
</div>

So there's various DIVs on the same level, what I want to do is to color every fourth block differently, until a divider appears, then it'd have to recount.

I thought something like .block:nth-child(4n) would do the trick, but it actually counts the elements based on the parent, not based on the class.

Here's the JSFiddle to try out. Block #4 and #8 in each row should be differently colored http://jsfiddle.net/SKgdH/3/

And this is how I made it sort-of work: http://jsfiddle.net/SKgdH/1/

What I did was to look for the 4th sibling of the .divider like this .divider + .block + .block + .block + .block

It works, however, I'd have to write the same for the 8th, 12th, 16th, .. block, which doesn't make it automatic anymore.

Is there something like .divider + .block:nth-sibling(4) or .divider + .block:nth-of-class(4)?

Maybe one of you got an idea on how to solve this without changing the source code or using javascript.

回答1:

Such a pseudo-class would not work because you are expecting it to match elements relative to a different compound selector, which is not how simple selectors work. For example, if you wrote a complex selector that only had a single compound selector with that pseudo-class (and no sibling combinators):

.block:nth-sibling(4n)

Would you expect this to match .block:nth-child(4n), match nothing at all, or be invalid?

It'd be nice to be able to abridge + .block + .block + .block + .block and make it repeat somehow, but unfortunately due to how the selector syntax is designed, it's just not possible.

You'll have to use JavaScript and/or add extra classes to the appropriate elements instead.



回答2:

As explained by BoltClock, you can't do this without JavaScript. If you choose that route (even though you explicitly say without JavaScript), it can be done with jQuery like this:

var counter = 0;
$('.wrap > div').each(function() {
    if ($(this).hasClass('divider')) {
        counter = 0;
    }
    else if ($(this).hasClass('block')) {
        counter++;
        if (counter % 8 == 4) {
            $(this).css('background-color','#ff0');
        }
    }
});

That will color the 4th column in every row yellow.



回答3:

The issue here is that :nth-of-type refers to the type of element and both .divider and .block are elements of type <div>.

What you really need is for .divider to be a different type of element from .block.


On that basis, if the only two child elements of <div class="wrap"> are:

  1. <div class="divider">
  2. <div class="block">

I'd be tempted to swap out <div class="divider"> for <hr> - the thematic break element.

Then you can use:

 .wrap div:nth-of-type(4)

to style .block.