Reputation: 23
I am using an element that can appear multiple times on a page in various positions. Depending on the use of the page, it can be interrupted by another element. In my example below, I would like to achieve that the order of red, blue, red, blue ... background stays the same - no matter how many other elements I insert. Is that possible?
.test:nth-child(odd) {
background: #ff0000;
}
.test:nth-child(even) {
background: #0000ff;
}
<h1>This is a heading</h1>
<p class="test">The first paragraph.</p>
<p class="test">The second paragraph.</p>
<p class="test">The third paragraph.</p>
<p class="test">The first paragraph.</p>
<p class="test">The second paragraph.</p>
<p class="test">The third paragraph.</p>
<p><b>Note:</b> Internet Explorer 8 and earlier versions do not support the :nth-child() selector.</p>
<p class="test">The first paragraph.</p>
<p class="test">The second paragraph.</p>
<p class="test">The third paragraph.</p>
Upvotes: 2
Views: 396
Reputation: 8136
Hold onto your butts, it's time to get hacky:
Using the (deep breath) ~
general sibling combinator, we can change how elements AFTER a certain element are displayed.
.test:nth-child(odd) { background: #933C96; }
.test:nth-child(even) { background: #EB811C; }
.interrupt ~ .test:nth-child(odd) { background: #EB811C; }
.interrupt ~ .test:nth-child(even) { background: #933C96; }
<h1>This is a heading</h1>
<p class="test">The first paragraph.</p>
<p class="test">The second paragraph.</p>
<p class="test">The third paragraph.</p>
<p class="test">The first paragraph.</p>
<p class="test">The second paragraph.</p>
<p class="test">The third paragraph.</p>
<p class="interrupt"><b>Note:</b> Internet Explorer 8 and earlier versions do not support the :nth-child() selector.</p>
<p class="test">The first paragraph.</p>
<p class="test">The second paragraph.</p>
<p class="test">The third paragraph.</p>
Here, we've applied your initial styling, and then added an additional cascading rule for any rows that come AFTER .interrupt
which swaps the colors. .interrupt
can be anything, you could even do some fancy work with :not()
to make it way more general, but the idea is the same.
But what if you have more than one interrupting element?! Still possible! but a bit (way) more rigged:
.test:nth-child(odd) { background: #933C96; }
.test:nth-child(even) { background: #EB811C; }
.interrupt ~ .test:nth-child(odd) { background: #EB811C; }
.interrupt ~ .test:nth-child(even) { background: #933C96; }
.interrupt ~ .interrupt ~ .test:nth-child(odd) { background: #933C96; }
.interrupt ~ .interrupt ~ .test:nth-child(even) { background: #EB811C; }
.interrupt ~ .interrupt ~ .interrupt ~ .test:nth-child(odd) { background: #EB811C; }
.interrupt ~ .interrupt ~ .interrupt ~ .test:nth-child(even) { background: #933C96; }
.interrupt ~ .interrupt ~ .interrupt ~ .interrupt ~ .test:nth-child(odd) { background: #933C96; }
.interrupt ~ .interrupt ~ .interrupt ~ .interrupt ~ .test:nth-child(even) { background: #EB811C; }
<h1>This is a heading</h1>
<p class="test">The first paragraph.</p>
<p class="interrupt"><b>Note:</b> Internet Explorer 8 and earlier versions do not support the :nth-child() selector.</p>
<p class="test">The second paragraph.</p>
<p class="test">The third paragraph.</p>
<p class="test">The first paragraph.</p>
<p class="test">The second paragraph.</p>
<p class="test">The third paragraph.</p>
<p class="interrupt"><b>Note:</b> Internet Explorer 8 and earlier versions do not support the :nth-child() selector.</p>
<p class="test">The first paragraph.</p>
<p class="test">The second paragraph.</p>
<p class="interrupt"><b>Note:</b> Internet Explorer 8 and earlier versions do not support the :nth-child() selector.</p>
<p class="test">The third paragraph.</p>
By stacking general sibling combinators on top of each other, we can prepare for any number of interrupting elements, so long as we can be sure that there won't be beyond the number we've specified in the CSS.
Upvotes: 3
Reputation: 207943
With pure CSS there's no way to do this unless you wrap each section of elements within another element (like a div) or use a different pseudo class and a different structure so that the row you want to exclude isn't the same type of element.
The reason for this is that nth-child
is a pseudo class that matches elements (not classes), so in your example all the paragraphs are considered and counted together as children, even the one without the test class. That particular paragraph is still a child (so it meets the nth-child criteria and is counted, but the styling isn't applied because it fails to meet the restriction of it having the test class). I tend to think of using a class with a pseudo class selector as a filter, so something like .test:nth-child(odd)
is saying apply the following rules to all elements that are a child, but only if they have the class test.
If you are able to wrap the groups of elements you wish to apply the styling to within a container element (see below), then they become children of that new container, and the number is restarted on each container.
.test:nth-child(odd) {
background: #ff0000;
}
.test:nth-child(even) {
background: #0000ff;
}
<h1>This is a heading</h1>
<div>
<p class="test">The first paragraph.</p>
<p class="test">The second paragraph.</p>
<p class="test">The third paragraph.</p>
<p class="test">The first paragraph.</p>
<p class="test">The second paragraph.</p>
<p class="test">The third paragraph.</p>
</div>
<p><b>Note:</b> Internet Explorer 8 and earlier versions do not support the :nth-child() selector.</p>
<div>
<p class="test">The first paragraph.</p>
<p class="test">The second paragraph.</p>
<p class="test">The third paragraph.</p>
</div>
Another option is to use JavaScript.
Upvotes: 0