CSS Last Odd Child?

CssCss Selectors

Css Problem Overview


I have an unordered list, which can contain either an even or odd number of items. I'm looking for a CSS-only way to remove the border from the last 2 li tags if the number of lis is even. The :last-child pseudo-selector removes the last one regardless.

li {
float: left;
border-bottom: 1px solid #000;
}

li:last-child{
border-bottom: none;
}

###Works for Odd Numbers of lis

+============================================+
+          1          |          2           +
+--------------------------------------------+
+          3          |                      +
+============================================+

###But for even numbers, I need to remove the bottom of cell #3

+============================================+
+          1          |          2           +
+--------------------------------------------+
+          3          |          4           +
+---------------------                       +
+============================================+

So I figured I could use li:nth-last-child() but I can't figure out what should be the equation to grab the last odd child.

It's not 2n+1, 2n-1, n-1, or anything I can think of. Please help.

Css Solutions


Solution 1 - Css

nth-last-child counts backwards from the last child, so to grab the second to last, the expression is:

li:nth-last-child(2)

You can combine pseudo-selectors, so to select the 2nd to last child, but only when it's odd, use:

li:nth-last-child(2):nth-child(odd) {border-bottom: none;}

And so, the whole thing should be:

li:last-child,
li:nth-last-child(2):nth-child(odd) {border-bottom: none;}

In answer to @ithil's question, here's how I'd write it in SASS:

li
  &:last-child,
  &:nth-last-child(2):nth-child(odd)
    border-bottom: none

It's not that much simpler, since the selection of the 'second-to-last odd child' is always going to require the 'two step' selector.

In answer to @Caspert's question, you can do this for arbitrarily many last elements by grouping more selectors (there feels like there should be some xn+y pattern to do this without grouping, but AFAIU these patterns just work by counting backwards from the last element).

For three last elements:

li:last-child,
li:nth-last-child(2):nth-child(odd),
li:nth-last-child(3):nth-child(odd) {border-bottom: none;}

This is a place where something like SASS can help, to generate the selectors for you. I would structure this as a placeholder class, and extend the element with it, and set the number of columns in a variable like this:

$number-of-columns: 3

%no-border-on-last-row
 @for $i from 1 through $number-of-columns
   &:nth-last-child($i):nth-child(odd)
     border-bottom: none

//Then, to use it in your layout, just extend:

.column-grid-list li
  @extend %no-border-on-last-row

Solution 2 - Css

Another alternative:

li:last-child:not(:nth-child(odd))

Here is a fiddle: http://jsfiddle.net/W72nR/

Solution 3 - Css

possibly:

li:nth-child(2n){border:1px dashed hotpink}
li:nth-child(2n-2), li:last-child{border:none;}

Solution 4 - Css

This works for me. Dynamically select the last odd child.

li:nth-last-child(1):nth-child(odd)

Solution 5 - Css

you can use the nth child selector:

li:nth-child(3) { border-bottom: none;}

li:nth-child(4) {border-bottom: none;}

However since this is not supported in IE 8... you should just set a class to those two li elements and use specificity to set the border-bottom to none.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKyleWpppdView Question on Stackoverflow
Solution 1 - CssBen HullView Answer on Stackoverflow
Solution 2 - CssAndrew OdriView Answer on Stackoverflow
Solution 3 - CssPhilipView Answer on Stackoverflow
Solution 4 - Cssuser3225723View Answer on Stackoverflow
Solution 5 - CssMichael RaderView Answer on Stackoverflow