views:

238

answers:

5

I have some divs:

<div class="A">"Target"</div>
<div class="A B">"NotMyTarget"</div>
<div class="A C">"NotMyTarget"</div>
<div class="A D">"NotMyTarget"</div>
<div class="A E">"NotMyTarget"</div>

Is there a CSS selector that will get me the div containing Target but not the divs containing NotMyTarget?

Solution must work on IE7, IE8, Safari, Chrome, and Firefox

Edit: So far Nick is the closest. It's clumsy and I don't like the solution, but at least it works: .A { style that all divs will take } div.B { style that will override style .A }

+9  A: 

I think the best you can do (until CSS 3) is override the styles in this case with what you don't want from class A B in A, like this:

.A.B { /* Styles */ }
.A { /* Reverse any styling you don't want */ }
Nick Craver
Why reverse styling of class A if you can just not include the styling for class A?
Veger
@Verger - Because `class="A B"` matches `.A.B` and `.A` both...but I'm a bit tired, it's possible I have this completely backwards.
Nick Craver
@Nick - True, but `class="B"` only matches `.B` and there is no need for any reversing :) (btw I did not know about the `.A.B` syntax, so thanks for that!)
Veger
@Verger - The OP wants `A` specifically though, so `.B` or anything else would get everything but the element they wanted...definitely backwards to think about that's for sure :)
Nick Craver
The .A.B syntax doesn't work in IE<8. In those browsers IE will only see the last class in the chain - it will apply .A.B to *all* elements with class B
Gareth
@Gareth - Yep that's true, but the same result for this question...I'm all ears for a better method, but not sure can get closer on this. If there is a better method I'd welcome it, then I'd learn something from this as well, which is always a plus.
Nick Craver
+4  A: 

You can use the attribute selector to match the div that has only one class:

div[class=A] {
  background: 1px solid #0f0;
}

If you want to select another div that has multiple classes, use quotes:

div[class="A C"]{
  background: 1px solid #00f;
}

Some browsers do not support the attribute selector syntax. As usual, "some browsers" is a euphemism for IE 6 and older.

See also: http://www.quirksmode.org/css/selector_attribute.html

-- Full example --

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;

<html>
<head>
    <title>Untitled</title>
    <style type="text/css">
        .A { font-size:22px; }
        .B { font-weight: bold; border:solid 1px blue;}
        .C { color: green; }

        div[class='A'] {
            border: solid 1px red;
        }
        div[class='A B'] {
            border: solid 3px green;
        }
    </style>

</head>

<body>

<div class="A">"Target"</div> 
<div class="A B">"NotMyTarget"</div> 
<div class="A C">"NotMyTarget"</div> 
<div class="A D">"NotMyTarget"</div> 
<div class="A E">"NotMyTarget"</div> 

</body>
</html>
Ron DeVera
seems very promising, unfortunately I couldn't get this to work. Perhaps I'm doing something wrong here. Commenters: this definitely does or does not work (FF, IE7, IE8, Safari)?
MedicineMan
Works fine in FF, Ie8, safari, etc with a strict doctype.
Chris Lively
A: 

The whole idea of using multiple classes is to make separate classes to suit your needs. You should be able to re-write your CSS to avoid this problem.

pixeltocode
A: 

If you have to select elements with certain classes, but not others, then you're using the cascading part of CSS wrong.

The parent-child relationship is there to help you, not hurt you.

A should be your base class and B, C, D, and E should only add things to or change parts of A.

thinkswan
+2  A: 

.A:not(.B) {}

But guess who doesn't support that... Indeed, IE<=8.

Ms2ger