Reputation:
I am attempting to figure out a nth-child selection rule that will select the "remainder" of division by three. To explain here is a visual diagram.
EDIT: Providing more examples for clarity.
div1 (should select div1) div1 div2 (should select div1 and div2) div1 div2 div3 (should select nothing) div1 div2 div3 div4 (should select div4) div1 div2 div3 div4 div5 (should select div4 and div5) div1 div2 div3 div4 div5 div6 (should not select anything) div1 div2 div3 div4 div5 div6 div7 (should select div7)
etc...
I believe that this may be possible, but am unable to figure it out.
Upvotes: 1
Views: 659
Reputation:
I believe I have solved it to my satisfaction, despite having to write two different groupings of css. The trick is that you can use multiple selectors in the same line, which is the equivalent of making Unions between the set selections.
Working example at http://jsfiddle.net/MY4cD/
A more complete solution (and expandable to other multiples besides three is below.
Given the following HTML ( and for any number of )
<div class="container">
<div class="cell">1</div>
<div class="cell">2</div>
<div class="cell">3</div>
<div class="cell">4</div>
<div class="cell">5</div>
<div class="cell">6</div>
<div class="cell">7</div>
<div class="cell">8</div>
</div>
The following CSS would create rows of three with the "remainder" divs highlighted red.
.cell {
width: 33.33%;
}
.cell:nth-last-child(-n+2):nth-child(3n+1):nth-last-child(1){
background:red;
}
.cell:nth-last-child(-n+2):nth-child(3n+1):nth-last-child(2){
background:red;
}
.cell:nth-last-child(-n+2):nth-child(3n+2):nth-last-child(1){
background:red;
}
If you wanted to have 4 divs per row and select the remainder again you could use the following CSS
.cell {
width: 25%;
}
/* accounts for when there is 1 remainder */
.cell:nth-last-child(-n+3):nth-child(4n+1):nth-last-child(1){
background:red;
}
/* accounts for the first of 2 remainders */
.cell:nth-last-child(-n+3):nth-child(4n+1):nth-last-child(2){
background:red;
}
/* accounts for the second of 2 remainders */
.cell:nth-last-child(-n+3):nth-child(4n+2):nth-last-child(1){
background:red;
}
/* accounts for the first of 3 remaidners */
.cell:nth-last-child(-n+3):nth-child(4n+1):nth-last-child(3){
background:red;
}
/* accounts for the second of 3 remainders */
.cell:nth-last-child(-n+3):nth-child(4n+2):nth-last-child(2){
background:red;
}
/* accounts for the third of 3 remainders */
.cell:nth-last-child(-n+3):nth-child(4n+3):nth-last-child(1){
background:red;
}
In this way, you can see the pattern will grow ever more complex the higher you go, but it is certainly possible for any number.
I have used this pattern along with media queries to simulate the effects of the new CSS flex-flow: row wrap; command with using floats for cross browser compatability. You can see the full demo of this here : http://codepen.io/msorrentino/full/chHnu/
Upvotes: 0
Reputation: 123453
:nth-child()
:nth-last-child()
, and the general sibling selector (~
) can be combined to match elements following the last group of 3.
div:nth-child(3n):nth-last-child(-n+3) ~ div {
/* ... */
}
With the 3rd example of 7 divs:
nth-child(3n)
matches every 3rd <div>
-- matching 3
and 6
.nth-last-child(-n+3)
matches the last 3 siblings -- matching 5
, 6
, and 7
.6
.Then ~ div
matches any siblings that follow (7
).
To match the 1st and 2nd when there isn't a 3rd, you can also match the :first-child
if it's one of the last 2 and :last-child
if it's one of the first 2:
div:nth-child(3n):nth-last-child(-n+3) ~ div,
div:first-child:nth-last-child(-n+2),
div:last-child:nth-child(-n+2) {
/* ... */
}
Upvotes: 4
Reputation: 114989
As far as I can tell there is no single selector that will let you do this.
However a combination of nth-last-child
and an overide with nth-child
will get you there.
CSS
li:nth-last-child(-n+2) {color:red;}
li:nth-child(3n) {color:black;}
li:nth-child(1),
li:nth-child(2),
li:nth-child(3) {color:black;}
Upvotes: 1
Reputation: 4431
This can be the solution for your problem:
div:not(:nth-child(3n)):not(:nth-child(1)):not(:nth-child(2)) {
background-color: #38f;
}
Upvotes: 0