Search code examples
javascriptjqueryhtmlcss-selectorsnoscript

Why is my nth-child selector selecting the wrong element?


I have this element tree (stolen from Stack Overflow's 404 page):

When we look at it, the highlighted <div> is supposed to be the fourth element. However, doing $('body > div:nth-child(4)') returns the div before. Why is this so? Is is somehow selecting the div in the <noscript> tag? When I remove the <noscript>, it selects properly.

Why is it behaving like that?


Solution

  • div:nth-child(4) does not give you the 4th div, it gives you the element that is both a div and a 4th child (and gives you nothing if the 4th child is something that is not a div; that is why you are not getting anything for div:nth-child(1)). The 4th div that you want is the 5th child with <noscript> present, and 4th child without it.

    From jQuery docs:

    The :nth-child(n) pseudo-class is easily confused with :eq(n), even though the two can result in dramatically different matched elements. With :nth-child(n), all children are counted, regardless of what they are, and the specified element is selected only if it matches the selector attached to the pseudo-class. With :eq(n) only the selector attached to the pseudo-class is counted, not limited to children of any other element, and the (n+1)th one (n is 0-based) is selected.

    So, if you want the 4th div, you will do body > div:eq(3).