Middle Child Pseudo-Class
Asked Answered
S

8

26

Is there a way to use CSS selectors to get the middle child in a list of elements?

I know that there is no literal :middle-child selector, but is there another way without resorting to Javascript?

Sharkskin answered 24/6, 2013 at 3:24 Comment(5)
Does the number of children change?Batrachian
The number of elements is set at page load and may vary user to user.Sharkskin
If you're working in PHP or Ruby or whatever, you could certainly write a function to add a class to the middle element.Batrachian
You're absolutely right, and that's what I'm already doing. I was mostly looking for some sort of CSS trick I wasn't aware of.Sharkskin
Such a pseudo-class wouldn't make sense, because what would be the middle child in an even number of elements? Your code may be able to guarantee an odd number of elements, but not every page can guarantee such a situation.Silvia
E
-6

Javascript is the only way to do this client side.

Expedition answered 24/6, 2013 at 22:30 Comment(1)
There should be sass solutionLegofmutton
P
34

This has been working well for me:

*:not(:first-child):not(:last-child) {
    ...
}

You can see an example of this here: http://codepen.io/bentomas/pen/Gwqoe

The one caveat to this is that it only works in IE 9+: http://caniuse.com/#feat=css-sel3

Pas answered 6/11, 2014 at 20:8 Comment(5)
Wouldn't that only work if there's three items? At the time I was looking for something with more elements than that in it.Sharkskin
Nope, this will select all elements that are not the first child and not the last child. You can see it in action here: codepen.io/bentomas/pen/GwqoePas
Oh, unless you want the exact middle child (i.e. only one element should ever be matched). I was thinking you wanted to select all the children that are in the middle. At least that's what I expected a :middle-child pseudo class to do when I went looking for it and found this thread.Pas
@Pas - Well, you just solved my little problem in a very powerful way. So, thank you. =)Dumpish
unfortunately it does select not only one middle elementKinesiology
A
13

While not elegant, if you know the upper and lower limits of the total number of elements, you could take a brute force approach to select the middle element.

For example, the following rules will select the middle element in a set of 5, 7, or 9 elements.

div:nth-child(3):nth-last-child(3) {
  /* The middle element in a set of 5 is the 3rd element */
}

div:nth-child(4):nth-last-child(4) {
  /* The middle element in a set of 7 is the 4th element */
}

div:nth-child(5):nth-last-child(5) {
  /* The middle element in a set of 9 is the 5th element */
}

Or with Sass:

@for $i from 3 through 5 {
    div:nth-child(#{$i}):nth-last-child(#{$i}) {
        /* The middle element */
    }
}
Agony answered 13/7, 2015 at 19:26 Comment(1)
If there can be an even number of elements, one might include div:nth-child(-1+#{$i}):nth-last-child(#{$i}) and/or div:nth-child(#{$i}):nth-last-child(-1+#{$i}) to select the element just left or right of center, respectively.Beckiebeckley
S
11

You can use the "not first and not last" approach, like so:

CSS

li:not(:first-child):not(:last-child) {
  color:red;
}

HTML

<ul>
    <li>First</li>
    <li>Second</li>
    <li>Third</li>
</ul>

Check the JsFiddle

Stettin answered 27/7, 2015 at 9:42 Comment(3)
what if there is 5 items ?Legofmutton
@Legofmutton this will apply to all middle children. Go to the JsFiddle link provided, add a couple more <li> in the middle and re-run it. You'll see them all turn red!Northnorthwest
OP: "the middle child" meaning oneAlmire
A
1

If you want to apply a style to all elements that are neither first children nor last children, you could use :not(:first-child), apply the style, and then use :last-child to 'take the style away' from the last element. But you'd have to think about what happens when there are less than 3 elements.

Alford answered 16/4, 2014 at 16:29 Comment(1)
If you want to avoid the duplication (of the 'take the style away' section), check my answer, that combines two 'not' selectors, in order to catch all of the middle elements... :-)Stettin
G
1

I've encountered the need to target the middle child on several occasions, and I've taken to using this sass mixin I wrote after referencing many similar questions, and their respective answers.

// Generate a reasonable number rules limited by $n.
@mixin middle-child($n) {
  // There is no middle for nChildren less than 3,
  // so lets just start at 3.
  @for $i from 3 to $n {
    // Find the middle, bias right for odd numbers.
    $mid: math.ceil(math.div($i, 2));
    // Select only those sets of children that number $i.
    &:first-child:nth-last-child(#{$i}) {
      // Select the middle child of that set.
      ~ :nth-child(#{$mid}) {
        @content; // Apply your styles.
      }
    }
  }
}

Usage:

.navigation {
  background-color: #ba0020;

  .nav-item {
    color: white;
    
    @include middle-child( 8 ) {
      font-weight: 900;
    }
  }
}
Grassofparnassus answered 6/4, 2022 at 15:11 Comment(0)
M
0

Have you tried :nth-child(#) ?

Depending on which one you want to select you just replace # with the number.

Mf answered 24/6, 2013 at 3:26 Comment(2)
That only works if the number of elements is known to begin with. I'm looking for something that will work for a list of unknown length.Sharkskin
Well, I suppose if you don't know the total number this won't help either, but in case you DO - take a look at this CSS3-nth-child on SO it's a similar question to yours.Mf
W
0
    /* Selects the single middle element */
.parent :nth-child(odd) {
    /* styles */
}

/* Selects the middle elements if there are multiple */
.parent :nth-child(n) {
    /* styles */
}

middle element when there's an odd number of elements

.parent :nth-child((n+1)/2) {
    /* styles */
}

middle elements when there's an even number of elements

.parent :nth-child(n/2),
.parent :nth-child((n/2)+1) {
    /* styles */
}
Washbasin answered 11/4, 2024 at 12:5 Comment(0)
E
-6

Javascript is the only way to do this client side.

Expedition answered 24/6, 2013 at 22:30 Comment(1)
There should be sass solutionLegofmutton

© 2022 - 2025 — McMap. All rights reserved.