Pseudo Class first three li's

I have a list which is generated dynamically. I need to target the first three li’s since they need a different top margin than the others, but between those three there are differences as well so I can’t target them in one rule. What would be the best way?


ul li.first, ul li.second, ul li.third {
}

or


ul>li, ul>li+li, ul>li+li+li {
}

Hello,

Giving specific class to your li (noonop’s first solution) is the one IE6 will understand.

If you use the second one, the Adjacent sibling combinator and the Child selectors are ok starting IE7 (if I do remember right, don’t have IE7 here to check) but be aware that the first selector (ul>li) will affect all your li in the list. The second one all of them except the first one and the last one all li exept the first one and second one. You’ll have to reset the css for the other by using:

ul>li+li+li+li {}

By using the pseudo-class :firstchild (starting IE7 ?) on the first one you will get out of the problematic above:

ul>li:firstchild {}
ul>li:first-child+li {}
ul>li:first-child+li+li {}

There is an easy way to select each li seperatly with css3 selector :nth-child(n)


ul>li:first-child  {}
ul>li:nth-child(2) {}
ul>li:nth-child(3) {} 

Sadly IE8 and under don’t understand it (IE9 does and other modern browsers too)

Nice explaining Candygirl. :slight_smile:

I would add the descendat selector-class-child selector combination:


ul li.first, ul li.first+li, ul li.first+li+li {
}

I don’t think “>” selector would be of very much help here since li will always be a direct child of the ul. So the descendant selector will do just fine, except if you have nested ul’s. Even then, “>” would apply to the nested ul’s and li’s the same way, so you’d probably need a class for the main ul, if the rules doesn’t need to apply for the nested ul’s.

The code above is provided with complete element names for readability. In a real code the above will not have ul but a class/id for the ul, or it would be based on the class/id of the ul’s parent, and li.first would be just .first. As always, a test code would probably be more suited in pointing out the best way.

Sorry, but that doesn’t work.
nth-child(2) hits the 2nd, 4th, 6th, 8th, 10th etc instance of the item
nth-child(3) hits the 3rd, 6th, 9th, 12th etc instance.

If you can’t put a class on the relevant items, your best bet is the li:first-child+li construction.

Stevie, I haven’t tested it, but for
nth-child(2) hits the 2nd, 4th, 6th, 8th, 10th etc instance of the item

it should be
nth-child(2n)?

If the parameter n is missing, then it should work as pointed by Candygirl?


ul>li:nth-child(1) {}
ul>li:nth-child(2) {}
ul>li:nth-child(3) {}

No IE8- support though.

Hi Stevie D,

Did you try it ?

According to the nth-child-pseudo’s documentation you have that exemple:

Examples:

foo:nth-child(0n+5) /* represents an element foo that is the 5th child
of its parent element /
foo:nth-child(5) /
same */

The behavior you’ve discribe is, for me, what the

:nth-child(2n+0),:nth-child(3n+0)

would do ?

(EDIT the +0 is optional as noonnope write it)

Hey Candygirl,

No, he described:

:nth-child(2n), :nth-child(3n)

EDIT: +1 is not optional, +1 would give you a different sequence all together.

2n = 21, 22, 23 = 2, 4, 6
2n+1 = 2
1+1, 22+1, 23+1 = 3, 5, 7 which is neither 2n neither 3n.

They’ll work in IE7.

:first-child will too, so long as you don’t have a comment in there (IE7 will think a comment is a child).

Stomme poes, thank you for the point

noonnope, thank you too

I must confess, because the documentation is in English, I’m having a hard time understanding all the subtilities ;p and I didn’t pay attention that, in my test, it was lines 1 4 7 instead of 3 6 9 with the 3n+1 :wink:

I think :nth-child(2n+0) will do the same then :nth-child(2n) ?

The sitepoint reference has a small section with a table explaining how the values work that makes things a little easier to understand.

Remember that the examples above would also hit nested lists - if that was an issue.

As an aside I usually use “nth-of-type” when I am concerned with a specific element although it’s not an issue in this case as only list elements can be children of a ul of course.

Yes, :nth-child(2n+0) will do the same as nt-child(2n).

Selectors Level 3

The :nth-child(an+b) pseudo-class notation represents an element that has an+b-1 siblings before it in the document tree, for any positive integer or zero value of n, and has a parent element.
[…]
The a and b values must be integers (positive, negative, or zero). The index of the first child of an element is 1.
[…]
If both a and b are equal to zero, the pseudo-class represents no element in the document tree.

The value a [and b] can be negative, but only the positive values of an+b, for n≥0, may represent an element in the document tree.

Example:

html|tr:nth-child(-n+6) /* represents the 6 first rows of XHTML tables */

So, another way to select the first three:


li:nth-child(-n+3) {}

No IE8-, FF3.0-, and apparently Op10.60- has problems with it: http://www.quirksmode.org/css/contents.html.

D’oh! :blush:
Sorry candygirl, you’re absolutely right and I’m an idiot who didn’t read carefully…

This is bit of a tricky one though! I targeted every third <li> in a row already using my serverside scripting.


#content .gallery .gal1,
#content .gallery .gal2,
#content .gallery .gal0 {
	width: 191px;
	height: 152px;
	margin: 15px 10px 0 0;
	float: left;
	background: url(../images/site/backgrounds/gallery_background.png) 0 0 no-repeat;	
}
#content .gallery .gal0 {
	margin: 15px 0 0 0;
}

Output:


<cfset modStyle = currentRow mod 3>
  <li class="gal#modStyle#"></li>

And no mather what I try, the first three <li’s> are not reacting to any of the suggestions so far.

Instead of the ColdFusion code, please post the resulting html mark up.

Since you have the possibility to provide classes server-side, the only question remaining is what browsers do you want to support, not if it’ll work or not. :slight_smile:

For a modern CSS3 solution, no IE8-, no FF3-, to be tested in Op, one line selector like this will do:


.gallery li:nth-child(-n+3) {}

Otherwise, if IE6- is no concern, you can choose between:

.gallery .gal0, .gallery .gal0+li, ul .gallery .gal0+li+li {
}

where the first li only gets a class: “gal0”, and


.gallery li:firstchild, .gallery li:first-child+li, .gallery li:first-child+li+li {
}

where the ul alone needs a class: “gallery”.

Finally, the full proof method: gal0, gal1, gal2 classes, if IE6- is a must. No need for ul’s class “gallery”, assuming you don’t have other li’s in the Content having gal# class names.

I would love to support as many browsers as possible. I don’t care at this point if IE 6 would be supported. Excuse me that I past a mixed CF html mark up in a html code:


<ul class="gallery">
	<cfloop query="getEventgallery">
  	<cfset modStyle = currentRow mod 3>
			<li class="gal#modStyle#"><a href="#link#" rel="prettyPhoto" title="#description#"><img src="event_gallery/#photo#" alt="#description#" /></a></li>
    <cfif modStyle eq 0></cfif>  
  </cfloop>
</ul>

No, I mean the resulting HTML, as in client-side HTML. :slight_smile:
The above is still CF.

<li class=“gal#modStyle#”>

I’m pretty sure (but did not look it up) that hashmarks (#) are not allowed in class tokens. So, without CF, I assume that stuff between the hashes gets filled with something?

That’s my point! Using the mod 3, I make sure that the third one in the row don’t have a right margin, since I don’t know how many images will be involved I need to do this. The stuff between the hash marks is the 1, 2, 0 (CF returns 0 as the third one)

@ noonnope: This is the returned html:


<ul class="gallery">
	
			<li class="gal1"><a href="http://www.youtube.com/watch?v=GYEDpUpBock" rel="prettyPhoto" title="Drambuie Event Thessaloniki"><img src="event_gallery/drambuie_thessaloniki.jpg" alt="Drambuie Event Thessaloniki" /></a></li>
    
			<li class="gal2"><a href="http://www.youtube.com/watch?v=2lGVRbGSvo4" rel="prettyPhoto" title="Drambui Event Athens"><img src="event_gallery/drambuie_athens.jpg" alt="Drambui Event Athens" /></a></li>
    
			<li class="gal0"><a href="http://www.youtube.com/watch?v=aWptAShzKSU" rel="prettyPhoto" title="Bacardi Event Athens"><img src="event_gallery/bacardi_athens.jpg" alt="Bacardi Event Athens" /></a></li>
    
			<li class="gal1"><a href="http://www.youtube.com/watch?v=1JlFBnQTY7s" rel="prettyPhoto" title="Bombay Sapphire Event Athens"><img src="event_gallery/bombay_sapphire_athens.jpg" alt="Bombay Sapphire Event Athens" /></a></li>
    
			<li class="gal2"><a href="http://www.youtube.com/watch?v=meN32koefY0" rel="prettyPhoto" title="Bombay Sapphire Event Thessaloniki"><img src="event_gallery/bombay_sapphire_thessaloniki.jpg" alt="Bombay Sapphire Event Thessaloniki" /></a></li>
    
			<li class="gal0"><a href="http://www.youtube.com/watch?v=vVBQjwq0yDk" rel="prettyPhoto" title="In a Sentimental Mood"><img src="event_gallery/in_a_sentimental_mood.jpg" alt="In a Sentimental Mood" /></a></li>
    

</ul>


I’m lost now. You said the first three, now you say every other 3rd li.

A picture would look better, but I’d say a li(#n mod 3 = 0#) class=“noRightMargin” is all you need:


#content .gallery li {
    width: 191px;
    height: 152px;
    margin: 15px 10px 0 0;
    float: left;
    background: url(../images/site/backgrounds/gallery_background.png) 0 0 no-repeat;   
}
#content .gallery .noRightMargin {
    margin-right: 0;
}

For every other 3rd li you apply a margin right 0, and you do that by adding the class noRightMargin for li’s that have 0 as the remainder of the division between their index and 3.