0

I have a "self-similar" (or recursive) HTML structure where I need to build a CSS Selector that catches only the top matches in this structure. For instance, given the following HTML:

<div class="option-block">
    <div class="option">
        <p>main content</p>
    </div>
    <div class="detail">
        <div class="option-block">
            <div class="option">
                <p>child content</p>
            </div>
            <div class="detail">
                <p>child detail</p>
            </div>
        </div>
    </div>
</div>

I need a CSS Selector that gives me the first div within the top option-block, IOW, the div that contains the text main content.

I've tried with .option-block > div:first-child (and several variants like it), but that gives me also the div with the text 'child content'.

One thing to note is that this particular structure could be anywhere within the HTML document, so I don't have a prior reference to use as anchor (like they do here or here).

Another thing to note is that this structure could be self-replicating to more levels: the .detail component of an .option-block container could always have another .option-block container inside, so I cannot rely on counting or anything like that.

UPDATE: thanks for the answers so far. Something that I should have mentioned is that the selector is to be used programmatically to locate the items, not to apply styles. Also, the selector is to be applied from the context of an existing item, which may be already inside a this hierarchy.

quiram
  • 746
  • 1
  • 7
  • 18

3 Answers3

1

I'm going to assume you can't just change your HTML structure (otherwise just add an extra class to the 1st level, or wrap the whole thing and check for direct ancestry).


You could check the ancestors of .option-block. This works if you're fairly sure there won't be other .option-block > .detail structures outside of your block.

:not(.option-block) > :not(.detail) > .option-block > div:first-child {
  background: red;
}
<div class="option-block">
    <div class="option">
        <p>main content</p>
    </div>
    <div class="detail">
        <div class="option-block">
            <div class="option">
                <p>child content</p>
            </div>
            <div class="detail">
                <p>child detail</p>
            </div>
        </div>
    </div>
</div>
Sheraff
  • 5,730
  • 3
  • 28
  • 53
0

I believe there is no support for recursive functions for :first-child and :last-child selectors (check here)

A possible solution may be giving the "main content" div.option another class to have an unique selector. Otherwise you can set a class in the .option-block divs that are inside a .detail div and use the :not selector:

.option-block:not(.inner-option) .option{ ... }

0

From what I’ve heard, there doesn’t seem to be a way to do what I need with a CSS selector. However, after some additional research it seems that XPath can work, something like this:

(.//div[@class=“option-block”])[1]/div 
quiram
  • 746
  • 1
  • 7
  • 18