Floated lists with CSS3 and jQuery

We should all be using advanced CSS selectors by now—they make our lifes so much easier! In this quick tutorial, I’m going to explain how you can have a nicely floated list of items. We will use jQuery to make sure IE understands it too.

The markup

Let’s start with a very clean semantic markup, listing some photos:

<div id="page">

	<ul id="food">
		
		<li>
			<img src="pic-1.jpg" width="200" height="133" alt="Wagamama" />
		</li>
			
		<li>
			<img src="pic-2.jpg" width="200" height="133" alt="Strawberries" />
		</li>
			
		<li>
			<img src="pic-3.jpg" width="200" height="133" alt="The Horseshoe" />
		</li>
			
		<li>
			<img src="pic-4.jpg" width="200" height="133" alt="Brick Lane" />
		</li>
			
		<li>
			<img src="pic-5.jpg" width="200" height="133" alt="Portugal" />
		</li>
			
		<li>
			<img src="pic-6.jpg" width="200" height="133" alt="Burgers" />
		</li>
		
	</ul>
	
</div>

So here we basically have a container div, with the id of “page”. Then we have our list with the id of “food” and our list items, each one containing one image.

The CSS

After we’ve added some CSS resets (check the example page for this bit), let’s add some styling to our “page” div:

#page {
	width: 640px;
	padding: 20px 0;
	margin: auto;
	text-align: left;
	}

Here we’ve added a specific width to the container, some top padding and we’ve aligned it to the centre of the page.

Now let’s add some styling to the list:

#food {
	overflow: hidden;
	}

#food li {
	list-style: none;
	width: 200px;
	float: left;
	margin-right: 20px;
	margin-bottom: 30px;
	}

This should be all we need: a) we’ve added an overflow of “hidden” to the ul (because the elements inside it will be floated, this is the quickest way of clearing it); b) we’ve removed the default bullet points from the list items, added some width to them and floated them to the left; c) finally, some margins to add a bit of breathing space to the page.

If you check your page now, the layout is broken. The last item on each row has a right margin too, and there is no need for it.

We can fix it with some cool CSS:

#food li.end-row {
	margin-right: 0;
	}
#food li:nth-child(3n) {
	margin-right: 0;
	}
	
	
#food li.first-row {
	clear: left;
	}
#food li:nth-child(3n+1) {
	clear: left;
	}

Let’s look at it by steps:

  1. We’ve added this part #food li.end-row because some browsers (ahem!) don’t understand the more complex selector, so they will need a class to target those list items. We will add this class to our markup via jQuery in a bit.
  2. We wanted to target every third list item within our list. We accomplish that with this selector: #food li:nth-child(3n). This means that every three li our CSS will do something. (Read more about the :nth-child() pseudo-class on the W3C website.)
  3. #food li.first-row: this selector will just be useful for Internet Explorer, because it needs to have a specific class on the li item so it knows what we’re talking about.
  4. #food li:nth-child(3n+1): this will target every third li item, but starting from the first one. Here we want to clear these li items on the left, so each line starts fresh.

The JavaScript

The JavaScript part is only needed to accommodate Internet Explorer. Because it doesn’t understand the :nth-child selector (yet?), we need to add some very non-semantic classes to the li items we need to target, and we’ll be doing that via jQuery.

So, the next step is to download jQuery and link it to the page, placing this bit on the header of the page:

<script type="text/javascript" src="jquery-1.3.2.min.js"></script>

We will also create our own JavaScript file to instruct the HTML on how to behave with jQuery. Place this after the previous code:

<script type="text/javascript" src="clear-list.js"></script>

Now on our newly created file (clear-list.js), we’ll add this code:

$(document).ready(function () {
							
	$('#food li:nth-child(3n)').addClass('end-row');
	$('#food li:nth-child(3n+1)').addClass('first-row');
	
});

Let’s focus on what’s important here.

We are using jQuery to add a class (end-row and first-row) to specific selectors (#food li:nth-child(3n) and #food li:nth-child(3n+1)), and that’s all you need to know. You can edit those parts according to your own HTML, but it’s quite simple!

Conclusion

In a perfect world, we wouldn’t need to use jQuery to make this code work. But we don’t live in a perfect world, and we have Internet Explorer to thank for that.

With this quick and very simple tutorial (for example, the li items have the same height, so I’m kind of cheating here!) my goal was just to show you can use more advanced CSS selectors, but if your layout breaks or is unusable on some browsers, there are some easy solutions to put it back in place.

You can download the example files here:

View example [download id=”9″]

If you’d like me to do more quick demonstrations of CSS selectors, just name them in the comments :)