6

I have a quite interesting problem here.
I want to target elements that match two conditions at the same time, but I can not find the way

<div class='redLink'>
    <!-- ... ... ... -->
        <a href='#'>Link</a>
    <!-- ... ... ... -->
</div>


<div>
    <!-- ... ... ... -->
        <a href='#' class='redLink'>Link</a>
    <!-- ... ... ... -->
</div>


My ideal CSS would be
[*:not(.redLink) a] AND [* a:not(.redLink)] {
    color:green; 
    /* i.e., color NOT red */
}

However, the operand , is just an OR (and, when it doesn't match one condition, it matches the other...!).
And the only AND I can find is the logical concatenation div#myDivId.someClass, though what I would like is something like [div#myDiv a].[div.someClass a]

My goal is to target ONLY those anchors <a/> that don't have the class .redLink and have no parents with the .redLink class eiher.

And, very important, the only thing I want to target is the final anchor, not the whole div or the whole element.redLink...

Thank you!

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Nico
  • 790
  • 1
  • 8
  • 20

2 Answers2

6

Unfortunately, you can't achieve this using a CSS selector with a single rule. Currently you can only target a elements without the class using a:not(.redLink).

It is not possible to target a elements that do not have any .redLink ancestors, because the :not() pseudo-class doesn't accept combinators (otherwise you would do a:not(.redLink a)). A selector like :not(.redLink) a wouldn't work either, because that targets a elements with at least one ancestor without the class, which is not the same as a elements that have no ancestors with the class.

For example if your structure looked like this:

<div class='redLink'>
    <p>
        <a href='#'>Link</a>
    </p>
</div>

That p doesn't have the class, so :not(.redLink) a would match.

If you happen to have the option of using jQuery, though, $('a:not(.redLink, .redLink a)') will work, because :not() is much more permissive in jQuery than in CSS.

If you need to do this using CSS only, the easiest solution is to make all a elements green, then override it:

a {
    color: green;
}

a.redLink, .redLink a {
    color: red;
}
Community
  • 1
  • 1
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • Wow, you really rocked here. My final goal was to use it with jQuery, so you solved my problem straight away. And, if I understand right, there is no way to achieve so using only CSS3, maybe if we wait for CSS4... – Nico Nov 19 '13 at 12:16
  • About your second (pure-CSS) solution, it works and I had thought of it, but doesn't satisfy my needs. The actual problem is to target inputs on a form that have `.noValidateField` themselves or their parent. But generally I want to validate, so, again, for your second solution, I would need to add the class `.yesValidate` to all all elements that I want to check, quite stupid I guess. Am I explaining myself correctly? (sorry for double-comment, but is clearer this way) – Nico Nov 19 '13 at 12:19
  • @Nico: My specialty lies in selectors :) I'm not so sure this will be possible in level 4 sadly - there's some documentation here: http://www.w3.org/TR/selectors4/#profiles which says even though `:not()` will allow you to use such a selector, it won't work in a CSS stylesheet because of performance reasons. – BoltClock Nov 19 '13 at 12:20
  • 1
    @Nico: If you're already using jQuery, you probably have nothing to worry about, particularly if you're using HTML5 and/or JS or a server-side language to validate. – BoltClock Nov 19 '13 at 12:23
  • I created a plugin for live form validation. You can see the last week's version at http://valideight.tk/ Documentation is not even started, yet, but it will be soon. And this way you can only submit a form when is `OK`. (And the server will validate it again, too, but it is a nicer user experience) – Nico Nov 19 '13 at 12:53
1

Maybe you can reverse the logic like this. Make every link green (if that is possible in your site) and make the specific links red again.

a {
    color: green; 
}

a.redlink,
.redlink a {
  color: red;
}

Of course it depends on the structure and complexity of your site and the existance of other styling that might collide with this, but I would prefer a CSS-only solution like this over JQuery if it is reasonably possible.

GolezTrol
  • 114,394
  • 18
  • 182
  • 210
  • Thank you very much, but it is not an optimized solution for me... Please see [what I just replied here](http://stackoverflow.com/questions/20071084#comment29898486_20071138) – Nico Nov 19 '13 at 12:22
  • I see, but as @BoltClock, I don't see another pure CSS solution, so I'll guess you will have to go for a Javascript/jQuery solution. – GolezTrol Nov 19 '13 at 17:23
  • Which is exactly what I needed on the field. But I wanted a more abstract solution for the sake of knowledge ;) Cheers! – Nico Nov 19 '13 at 20:00