2

Having the following structure:

<ul>
    <li>
        <div><span class="node">Content1</span></div>
    </li>
    <li>
        <div><span class="node">Content2</span></div>
    </li>
    <!-- but also: -->
    <li>
        <div><span class="node">Content3</span>
            <ul>
                <li>
                    <div><span class="node">Content on 2nd level</span></div>
                </li>
            </ul>
        </div>
    </li>
</ul>

Now I want to select all span elements with the CSS class node which are on the first level of the hierarchy. How to do that without also matching the last span on level 2?

Edit: The div tags are just for demo purposes. They can change to span or even be nested within another div. I don't want to get a brittle CSS selector out of this (web testing), so I do not want to use direct child selectors. Furthermore, I cannot make changes to the HTML code myself.

D.R.
  • 20,268
  • 21
  • 102
  • 205
  • What about overriding the applied rule for the 2nd level `.node`? http://jsfiddle.net/hashem/3Wney/ – Hashem Qolami Jul 29 '14 at 07:35
  • @HashemQolami: Good idea for CSS styling, however, for selecting elements in web testing this is not suitable :-) – D.R. Jul 29 '14 at 07:44
  • Do you know in advance how many levels of content there will be? Or can there be an arbitrary number of levels > 2? – BoltClock Jul 29 '14 at 07:58
  • I guess my point is, as I mention in my answer, you will need to know a few things in advance about the HTML in order to construct a selector that will conform to that HTML. If there were a "closest descendant" selector, this would be made much easier, but unfortunately CSS selectors haven't advanced to that point yet. – BoltClock Jul 29 '14 at 08:01
  • I think this may help, checkout the answer to this question: [css-to-select-top-level-of-a-ul][1] [1]: http://stackoverflow.com/questions/15705064/css-to-select-top-level-of-a-ul – HowieH Jul 29 '14 at 08:53

3 Answers3

2

You will need to start from the parent of the top-level ul and work your way down using child selectors. For example, assuming the parent element is identified by #parent:

#parent > ul > li > div > span.node

If the hierarchy of elements between the li and the span.node is not fixed, then things get a little more complicated. In order to avoid matching the inner span.node elements, you will need to make some assumptions about the markup, since a simple descendant selector like the following will always return every span.node since every nested list occurs as a descendant of your top-level li elements:

#parent > ul > li span.node
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • Really important to note the identifier of the parent element or there is no anchor point at the root for your selector. – David Barker Jul 29 '14 at 07:25
  • 1
    @D.R.: I don't think it's as straightforward then. Let me think about it and I'll edit my answer. – BoltClock Jul 29 '14 at 07:36
2

You can use > selector:

#parent > ul > li  .node

Or, if you haven't parent id:

ul > li :not(ul) .node
Bhojendra Rauniyar
  • 83,432
  • 35
  • 168
  • 231
0

Fix/Ammend your html code, simple is better.

Working fiddle

<div><span class="node test">Content2</span></div>

add 2 class names to your span

.node.test {
    color: red;
}

points to the right span

hahaha
  • 1,001
  • 1
  • 16
  • 32
  • As I am web testing an existing application this is not a suitable solution for me. I cannot change the HTML myself. – D.R. Jul 29 '14 at 07:27
  • @DavidBarker if the word "fix" was too much for you I apologise. But using 2 class names to point to something instead of something like `#parent > ul > li > div > span.node` in my book is much better. – hahaha Jul 29 '14 at 07:30
  • @D.R. I did not know you had no access to the html, maybe put this in your question :) – hahaha Jul 29 '14 at 07:31
  • 1
    Not really, polluting html with unnecessary class' in my book is bad. – David Barker Jul 29 '14 at 07:34