0

I think this is impossible :-(

Using CSS, I need to select the last label in the list of paragraphs, which is inside of a span.

<div>
    <p>
        <span>
            <label>no good, because not the last</label>
        </span>
    </p>
    <p>
        <span>
            <label>good</label> <!-- This one should be selected -->
        </span>
    </p>
    <p>
        <label>no good, because is not inside of a span</label>
    </p>
</div>

Virtually the selector would be something like this:

div (p > span):last-child label {
    background: red;
}

But I don't think CSS understands parenthesis (yet).

The reason for this is that ExtJS (Sencha) puts radio buttons in nested containers. The visibility of buttons is declared in the inner containers (that would be the span tags in the example above). I want to round corners of the last VISIBLE label, thus I need to find the last outer container that has an inner container declaring it's visibility.

Perhaps there is a different workaround for this? As a last resort, I'd accept a JS solution, as long as it's based on native ExtJS components/elements traversing syntax, rather than jQuery.

Please ask for more detail if needed.

Geo
  • 11,580
  • 4
  • 31
  • 54
  • In short,, which nth element you want to select? – Mr. Alien May 22 '13 at 18:03
  • It can't be nth. It has to be the last visible - in this particular case the last containing another element. – Geo May 22 '13 at 18:16
  • You want to select this -> `

    good

    `
    – Mr. Alien May 22 '13 at 18:19
  • I'm sorry, yes. I thought it was clear. – Geo May 22 '13 at 18:20
  • Your modified question is very different. No need for `:has` anymore. But the main problem still is: There is no `:last` selector in CSS. – Linus Caldwell May 22 '13 at 18:36
  • @LinusCaldwell It is not that much different. Yes you do need a ":has" because you have to check whether it has a `span` or not. And you are wrong ":last-child" is a valid CSS selector. The problem here is the parenthesis I think. – Geo May 22 '13 at 18:41
  • 1. No, you don't need a `:has` selector because `p > span > label` cannot select a `` that is not inside a ``. 2. I didn't say `:last-child` is invalid, i said there is no `:last` selector which is something completely different. – Linus Caldwell May 22 '13 at 18:47

1 Answers1

1

It will (maybe, depends on if the selector will be in the final spec) partly be possible with CSS 4:

!p > span {
    background: red;
}

But this will select all <p/> that have a <span/> inside, not only the last one. CSS currently does not know a :last selector, and as far as I can see even with CSS 4 this won't be implemented1.

So the summary is: Currently there is no way to do this in pure CSS.


Currently your only option is to use JavaScript. A sample in jQuery would be:

$('p:has(span)').last().css({ 'background': 'red' });

Here is a demo.

Or, as you mentioned in your comment, with extjs:

Ext.select('p:has(span):last').setStyle('background', 'red');

Here is a demo.


Answer to your updated question

Your new example does not need a parent selector anymore. The partly working CSS would be

div > p > span > label {
    background: red;
}

But still: There is no :last selector in CSS1. Updating the above JavaScript samples:

jQuery:

$('div > p > span > label').last().css({ 'background': 'red' });

extJS:

Ext.select('div > p > span > label:last').setStyle('background', 'red');

1 About the :last selector:

To make it more clear: :last-child selects the last child inside an element in the dom, whatever it is. It is no sub query. So, even if your parenthesis version would be implemented, :last-child would select nothing because the really last element is not part of the query. You would need a :last selector like in some JavaScript libraries which selects the last item of the resultset, so it's a sub query. This is a completely different selector and will not be part of CSS soon.

Linus Caldwell
  • 10,316
  • 12
  • 43
  • 56
  • Thank you. Yes, I figured I could do it using jQuery. But I'm ExtJS right now. Never heard of CSS4 - this is exciting! – Geo May 22 '13 at 18:19
  • 1
    @Geo You need to use this solution, as of now there's no work around for this :) – Mr. Alien May 22 '13 at 18:24
  • 1
    That site is horribly out of date. The subject selector does not use that syntax anymore, and in fact, it may not even be usable in CSS once Selectors 4 is implemented. See my comments under http://stackoverflow.com/questions/1014861/is-there-a-css-parent-selector/1014958#1014958 – BoltClock May 22 '13 at 19:38
  • @BoltClock, thank you! Updated my answer. Maybe you know if the `:nth-last-match()` selector will work this way. – Linus Caldwell May 22 '13 at 20:18
  • 1
    No, `:nth-last-match()` operates based on siblings as well, and its use of combinators is also not allowed in CSS. In short, this will still not be doable in CSS, unfortunately... – BoltClock May 22 '13 at 20:58
  • @BoltClock, hmm... too bad. Thank you for the info! – Linus Caldwell May 22 '13 at 21:24
  • Ended up using JS. Thank you! – Geo May 26 '13 at 00:18