Search code examples
javascripthtmlcss-selectors

CSS nth-child selector works everywhere except on X


I just found something very weird. Its about this css selector

div:nth-child(3) a

On X I have a container div selected in my DevTools

enter image description here

Now, with the css selector div:nth-child(3) a I want to find the link holding the 4h text

I copied the HTML from X to produce a demo here. You can see there that it works as expected, I see the correct href value!

Although this sounds super easy, which it is. Simplified the HTML looks like this:

    <div>
        <div><a href="/elonmusk">@elonmusk<a/></div>
        <div>·</div>
        <div>
           <a href="/status/234324234234234">3h</div>
        </div>
    </div>

However, when I try to reproduce this on X.com it doesn't work

To reproduce, first select the container element enter image description here

Now if I perform that query I get enter image description here

It selects the first div. It can be fix when I query it as follows

$0.querySelector('div:nth-child(3)').querySelector('a')

Why does it work in my demo and not on X?


Solution

  • The HTML subtree you looked at is

    <div> $0
      <div>
        <a> $1
          <div>
            <span>...</span>
          </div>
        </a>
      </div>
      <div>
        <span>·</span>
      </div>
      <div> $2
        <a> $3
          <time>...</time>
        </a>
      </div>
    </div>
    

    Now $0.querySelectorAll("div:nth-child(3) a") selects all a elements that

    • are descendants of $0 and
    • have an ancestor div that is the third among its siblings. This ancestor can be outside of the subtree you are looking at!

    The result of this query contains both $3 (with $2 as the ancestor) and $1 (with an ancestor outside of this subtree).

    And $0.querySelector("div:nth-child(3) a") returns only the first of these, that is, $1.

    What you want is correctly expressed as $0.querySelector("div:nth-child(3)").querySelector("a").