2

I am not fully understanding the behaviour of some css pseudo class selectors.

Looking at this simple html template:

 <body>

  <div>
   <p>One</p>
   <p>Two</p>
  </div>

  <div>
   <p>Three</p>
   <p>Four</p>
  </div>

  <div>
   <p>Five</p>
   <p>Six</p>
  </div>

  <div>
   <p>Seven</p>
   <p>Eight</p>
  </div>

 </body>

I do not understand why the following css would actually apply the style to the first div:

div:nth-child(1){
 color: red;
}

and the following css won't apply the style to the last div:

div:nth-last-child(1){
 color: red;
}

As far as I understand the nth-child selector will find the target, look for his parent and select the nth-child corresponding to the target.

Thanks for your help.

Andrea

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • `div:nth-last-child(1)` why would it select the second to last div ? why not the last ? is the same as `last-child`. `nth-last-child(1)` it reads the first child from the end. – Mihai T Oct 24 '19 at 13:34
  • Yes sorry, it should select the last div but it does not... – Andrea MeAndy Fiorucci Oct 24 '19 at 13:35
  • 1
    Make sure the DOM matches _exactly_ what you have written in your HTML in terms of element structure, otherwise this won’t work. If you put the whole thing into a jsfiddle for example, that automatically inserts a script element at the end of body - making _that_ one the actual last child. The code you have shown works as expected, _if_ the resulting DOM doesn’t get muddied by outer factors. – 04FS Oct 24 '19 at 13:37

2 Answers2

2

The problem with div:nth-last-child(1) is that the last div is not the last child.

Some IDEs, such as jsFiddle, insert a script element in the document tree.

enter image description here

That script element is being targeted by :nth-last-child(1), which doesn't care about element type. It only looks at siblings.

You have to either:

  1. get rid of the script element

  2. use div:nth-last-child(2)

  3. use div:nth-last-of-type(1)

jsFiddle demo

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • 1
    Exactly right, I am using vscode live server, and it does actually inject a script tag at the end. Thanks for the solution. – Andrea MeAndy Fiorucci Oct 24 '19 at 13:45
  • @AndreaMeAndyFiorucci (4) consider your own container where you will put your elements. The solution (2)(3) may not work as some tools add more than one element like SO snippet for example – Temani Afif Oct 24 '19 at 14:43
0

It does select the last div. But the HTML structure you posted is not a ' real ' one.

Where you test i bet there are some other elements that are siblings to those divs. Like <script> <footer> etc. So there is no nth-last-child(1) with the tag div inside body

So this works.

div:nth-child(1) {
  color: red;
}

div:nth-last-child(1) {
  color: red;
}
 <section>
   <div>
     <p>One</p>
     <p>Two</p>
   </div>

   <div>
     <p>Three</p>
     <p>Four</p>
   </div>

   <div>
     <p>Five</p>
     <p>Six</p>
   </div>

   <div>
     <p>Seven</p>
     <p>Eight</p>
   </div>
 </section>

But if you have another element after the last div, it won't work because now the div is the second to last element, not the last.

div:nth-child(1) {
  color: red;
}
/* this doesn't work */
div:nth-last-child(1) {
  color: red;
}
/* this works */

div:nth-last-child(2) {
  color: red;
}
 <section>
   <div>
     <p>One</p>
     <p>Two</p>
   </div>

   <div>
     <p>Three</p>
     <p>Four</p>
   </div>

   <div>
     <p>Five</p>
     <p>Six</p>
   </div>

   <div>
     <p>Seven</p>
     <p>Eight</p>
   </div>
   <h1>
     Hello there
   </h1>
 </section>
Mihai T
  • 17,254
  • 2
  • 23
  • 32