-2

Supose I have a dom structure I can't control (i.e. is generated).

<div>
    ... more dom here ...
    <span>
        ... more dom here ....
        <span>
            ... more dom here ...
        </span>
        ... more dom here...
    </span
    ... more dom here ...
</div>

The fact is that I represented this structure as 3-leveled but it could have many levels: the first span is not direct child of the div, but a descendant, and the second span is not necesarily children of the first span, but a descendant.

Also, since there are many structures I can't control, there are perhaps more levels: more nested span tags.

My question is:

  1. How can I reach -with CSS- ONLY the last span level? This means: every div span not having any span descendants.
  2. How can I reach -with CSS- ONLY the first span level? This means: every div span not having any span in the dom path between the (expected) last span and the div.

I use jQuery for those selectors but since the code is dynamic and more components could appear, I cannot use jQuery code to filter what I expect and apply styles.

Luis Masuelli
  • 12,079
  • 10
  • 49
  • 87
  • is that third `` supposed to be a `` ? – arserbin3 May 23 '14 at 18:01
  • Can you show us what you have tried? Are the elements really just as naked as they are here in your post? – Jay Blanchard May 23 '14 at 18:06
  • @arsebin edited. yes, it was. – Luis Masuelli May 23 '14 at 18:37
  • @JayBlanchard I'm completely clueless. Current selectors which caused trouble because they styled every span were "div span" (or "div.aclass span"). Totally clueless how to fix so only the last span is styled) - it's troublesome to see that spans were not directly related vertically, but with a variable amount of intermediate ancestors. – Luis Masuelli May 23 '14 at 18:39

3 Answers3

1
  1. What you need to target any element according to its children (or absence of children) is basically a parent selector. It has been proposed and requested quite a lot, but it still does not exist in CSS. You can use jQuery, or you could also use whatever server-side langage to add a class (exemple: last-level) to the appropriate spans.

  2. To target spans that are directly inside div, and not inside another span, use the child selector div>span

herezy
  • 336
  • 1
  • 6
1

Neither is possible with just a CSS selector. The appropriate jQuery selectors would be, respectively,

  1. div span:not(:has(span)) and
  2. div span:not(span span)

But as you can see, neither of these are valid CSS selectors: the :has() selector is not available in CSS, and :not() does not allow combinators in CSS.

In particular:

  1. There is no way, even with an overriding rule, to reach the innermost span without some prior assumptions or knowledge of your markup. For example, you need to know in advance how many levels of span elements your structure will go, then target the exact number accordingly. If you can't know this in advance, you have no choice but to figure out a way to apply a class name to the innermost span so your CSS can target it.

  2. Applying styles to the topmost span on the other hand is doable if you use an overriding rule to undo the styles for any nested spans:

    div span {}
    div span span {}
    
Community
  • 1
  • 1
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
0

As far as reaching the first descendant of an element with only CSS, you can do this:

div > span {
    // your styles
}

As far as reaching an arbitrarily deep number of nested elements with CSS, I don't think you can do that dynamically. LESS and SASS (just CSS pre-processors in general) have some dynamic capabilities depending on what you want to do, so maybe you can look into those.

I'm sure there's a way to use jQuery selectors to reach whatever arbitrarily deeply nested element you want... For example, something like this:

$('div span').each(function() {
    if( /* $(this) is at a certain level */ ) {
         $(this).css( /* your style */ );   
    }
});

If you can post more relevant code, maybe that can help guide me a little bit more to edit my answer with a better solution.

Josh Beam
  • 19,292
  • 3
  • 45
  • 68
  • I can't write code I don't know how to write. `div > span` was not useful since I need to take into account that there could be an arbitrary chain (actually: branch, since DOM is a tree) of non-span items. i.e. examples could be `div > button > span` (yes, sounds weird but it is) or just `div > span`. – Luis Masuelli May 23 '14 at 18:41