5

I have this simple HTML:

<body>
  <a>
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
  </a>
</body>

The divs are children of <a>.

From jQuery:

:last-child Selector — Selects all elements that are the last child of their parent.

However, when running this code in JSBin:

 $("div:last-child" ).css('background-color','red')

It yields this rendered output:

enter image description here

Even if we remove <a> so that divs will be direct children of <body>:

<body>
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
</body>

The result is that nothing is painted: (http://jsbin.com/kamepu/4)

Those divs are children of <body>, so why isn't it working?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Royi Namir
  • 144,742
  • 138
  • 468
  • 792
  • 1
    http://stackoverflow.com/questions/4612794/how-to-select-last-child-element-in-jquery – Smile0ff Nov 23 '14 at 12:32
  • 2
    @Smile0ff Does it answer my *question* ? (BODY pov) – Royi Namir Nov 23 '14 at 12:33
  • Royi: it works me fine, in Chrome, can it be dependent on browser (and version)? http://jsfiddle.net/gg4mpsx3/ – pavel Nov 23 '14 at 12:37
  • @panther wtf ? could it be jsbin problem ? – Royi Namir Nov 23 '14 at 12:38
  • @RoyiNamir: sure, it could :-) It should work correctly. – pavel Nov 23 '14 at 12:38
  • @panther nope , look here , same jsfiddle, : http://jsfiddle.net/gg4mpsx3/2/ – Royi Namir Nov 23 '14 at 12:39
  • 1
    Doesn't (interestingly enough) work in Stack Snippets either (`$('div:last-child')`, `$('body div:last-child')` and `$('body :last-child')` all return a `length` of `0`). – David Thomas Nov 23 '14 at 12:40
  • @RoyiNamir: it's in linking scripts, it depends if you link them in ``, before `` or after `

    `.

    – pavel Nov 23 '14 at 12:45
  • @David Thomas: `body :last-child` should have a nonzero length - the script is always inserted even if the body is marked up empty. – BoltClock Nov 23 '14 at 12:56
  • @BoltClock: true; I was using the given selectors with the `.css('color','red')` method-call from the original question. As ` – David Thomas Nov 23 '14 at 12:59

2 Answers2

10

If you look at the DOM, JS Bin inserts some script elements before the closing </body> tag, which prevents any of the divs from matching div:last-child. Remember that although script elements are (usually) not rendered, they do exist in the DOM just like any other HTML element, and as a result will affect selector matching.

The last div is in fact the last of its type, even if it isn't the very last child of body; you can verify this by switching to :last-of-type and it will match.

As mentioned in the comments, Stack Snippets does this as well:

div:last-child { text-decoration: underline; }
div:last-of-type { color: red; }
<body>
  <div>Red but no underline</div>
</body>
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • Yes that's the answer :-). dam* those online tools – Royi Namir Nov 23 '14 at 12:41
  • 1
    With `div:last-child` you select the `
    ` *that is* (and only *if it is*) the `:last-child` of its parent element.
    – David Thomas Nov 23 '14 at 12:44
  • 1
    @nicael `last-child` and `last-of-type` are different things. – Etheryte Nov 23 '14 at 12:45
  • @Nit confusing things :) – nicael Nov 23 '14 at 12:47
  • 2
    Well, you were a minute faster. Enjoy hitting your rep-cap that much sooner...sigh. Also: welcome back! It's been odd, having CSS, HTML and JavaScript questions lying around not being answered authoritatively this past couple of months... – David Thomas Nov 23 '14 at 12:47
  • 1
    @David Thomas: Thanks! I was wondering if we were gonna bump into each other today. I figured answering a question or two would make it very certain. It's good to be back, although how active I'll be now that I am remains to be seen. – BoltClock Nov 23 '14 at 12:57
  • Yeah, I'm predictably present most days (especially weekends); today is, I think, my 2000th-day anniversary. So, y'know, cupcakes all round! Also, espresso. :) – David Thomas Nov 23 '14 at 12:59
2

:last-child returs true is the very last child is of this type (div in this case).

JSBin links scripts at the bottom of the page (before </body>), so :last-child can works with script element only.

Solution is to move scripts into head section using document.ready or after </body>.

pavel
  • 26,538
  • 10
  • 45
  • 61