2

we have a partial html:

<ul>
    <li class="class1">AFFECTED</li>
    <li class="class1 class2">NOT</li>
    <li class="class1">NOT</li>
</ul>

<ul>
    <li class="class1 class2">NOT</li>
    <li class="class1">AFFECTED</li>
    <li class="class1">NOT</li>
</ul>

<ul>
    <li>NOT</li>  
    <li class="class1">AFFECTED</li>
    <li class="class1">NOT</li>
</ul>

I need a universal css-selector for the first li's of any list with only class1.

  • li's with extra classes (class2) MUST NOT be affected.
  • only first li with class1 should be selected (to change the appearance of A.
  • no JS/jQuery.
  • li's are float, so no hard coded nth-child.
  • code is generated automatically, so no way add/remove custom classes.

I've tried to use :not(class2), [class2] :first-child & :first-of-type but with no avail.

Thanks!

Solution: http://jsfiddle.net/6hxZa/3/

Max
  • 1,463
  • 5
  • 19
  • 34
  • I might be misunderstanding you but are you saying the li with class2 should not apply class1 to it? If you are that simply isn't possible because CSS doesn't work like that. I would suggest if that is the case looking at the code generating the list and set an exception to not add class1 – DJ Forth Apr 04 '13 at 15:04

3 Answers3

12

You should be able to capture only the elements with .class1 and no other using this selector:

li[class="class1"]

You won't be able to match only the first out of these elements because there isn't a selector to do that. :first-child only selects the very first child within the ul regardless of what classes it has, and :first-of-type selects the first li, also regardless of its classes (effectively making it the same as :first-child for li elements). You'll have to use the technique given here (where it also explains why these two pseudo-classes don't work) to apply the rule to all such elements then undo it for subsequent ones:

li[class="class1"] {
    /* Apply styles... */
}

li[class="class1"] ~ li[class="class1"] {
    /* ... and remove them after the first */
}

Note that the same selector is used so both classless elements and elements with .class2 are completely unaffected.

This jsFiddle demonstrates the desired effect with the provided HTML: http://jsfiddle.net/Cmypc/4/

Community
  • 1
  • 1
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • Good solution. I generally don't like having to 'undo' styles but this seems to be the best way to achieve the desired effect using only CSS. – metadept Apr 04 '13 at 15:33
  • I'm not quite happy because resets are double work, but as soon as we should modify only 2 css properties, that's seems applicable until css4 :) – Max Apr 04 '13 at 15:42
5

If you want to specifically exclude class2 from the selector, use:

li.class1:first-child:not(.class2) { }

If you want to exclude any additional classes other than class1 use:

li[class=class1]:first-child { }

I would recommend the first if you know which class(es) you're excluding as it will interfere less with other/future styles.

jsFiddle of #1: http://jsfiddle.net/Cmypc/ jsFiddle of #2: http://jsfiddle.net/Cmypc/1/

EDIT If you're looking for a :first-of-class selector, there isn't one (see this thread). A future solution may be the :nth-match selector but you'll have to wait for CSS4. Alternatively, you can use a more elaborate clearing selector to undo the styles applied (see BoltClock's answer) as a workaround.

Community
  • 1
  • 1
metadept
  • 7,831
  • 2
  • 18
  • 25
  • @Gareth A and E should be affected – Max Apr 04 '13 at 15:26
  • I know, I was just posting those as counter-examples to this answer's jsFiddles to show that it doesn't quite do what's required. – Gareth Apr 04 '13 at 15:27
  • @Gareth I'd misunderstood the initial question. Updated my answer (but BoltClock still has the only working solution that I see). – metadept Apr 04 '13 at 15:40
0

Try this

li:first-child
{
...
}

this is only for class 1

li.class1:first-child
{
color:#ff0000;
}

and here is a fiddle

and if you dont want the list with class2 to be affected maybe this can work for you

    li.class1.class2:first-child
    {
        ...
        code that will reset
    }
trajce
  • 1,480
  • 3
  • 23
  • 38
  • 1
    should I post the obvious?
    • A
    • A
    – Max Apr 04 '13 at 15:03
  • @gr9zev: It's not immediately obvious since the `...` in your question may imply that all your elements at least have `.class1`. Go ahead and update your original question to account for classless elements. – BoltClock Apr 04 '13 at 15:07