Reputation: 502
I have a number of divs of a particular class .box for which I want to set an alternating background color. However, some of the divs are placed inside another div .inner-container:
<div class="container">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="inner-container">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>
So using nth-of-type(even) or nth-child(even) to change the color for every second .box does not work here. Is it possible to achieve the alternating background anyhow with using CSS only?
Note: I dont know how many boxes will be direct children of .container and how many will be inside the .inner-container.
Upvotes: 10
Views: 10412
Reputation: 723628
I basically need a selector that counts the boxes as if they were all direct children of the same parent .container (as if the .inner-container would not exist).
Assuming there will only be exactly one inner container — and no other elements besides .box
and .inner-container
— you'll need to use :nth-child()
on the inner container to determine its position relative to its .box
siblings (not its .box
children), and thus determine whether to alternate the background on its contents one way or the other:
.container > .box:nth-child(even) {
background-color: #bb3333;
}
.container > .inner-container:nth-child(odd) > .box:nth-child(even),
.container > .inner-container:nth-child(even) > .box:nth-child(odd) {
background-color: #bb3333;
}
Here's a demo with the boxes appropriately labeled so you can see how each selector works.
Note that if you have any boxes that could appear after the inner container, you'll need to be able to count the number of children the inner container has before you can determine how to start counting from that point. This will not be possible with just CSS because selectors cannot ascend from inner elements to outer elements. There are workarounds using JavaScript, but I suspect this is outside the scope of the question at hand.
Upvotes: 6
Reputation: 1335
You can still apply an alternating background with CSS only here. Here's a Fiddle of it in action.
There's 2 ways you can do it:
Method 1:
Target the each level of <div>
s directly.
.container > .box:nth-child(even) {
/* stuff */
}
The method above targets only the first level children of the parent .container
. This won't effect the <div>
s inside .inner-container
.
To target the <div>
s inside .inner-container
separately, we use the same trick again, but start with a different parent container:
.inner-container > .box:nth-child(even) {
/* stuff */
}
Method 2:
Add a second class for the nested <div>
s and target them that way:
<div class="container">
<div class="box">a div</div>
<div class="box">a div</div>
<div class="box">a div</div>
<div class="inner-container">
<div class="another-box">a nested div</div>
</div>
</div>
Upvotes: 2