The wheels are always turning over here. Tune in to see what's up.


Bulletproof Gallery Style Lists

View the Live Demo  •  Download The Source Code

Listing pages are becoming increasingly ubiquitous features of Web design as content management systems enable even the smallest sites to easily upload and archive a ton of data. While the classic vertically-oriented list may be just fine for text-heavy datasets like blog posts or press releases, many designers are turning to grid-based gallery style layouts to add visual interest to portfolios, product listings and the like. In addition to being more aesthetically pleasing, a gallery style list makes better use of screen real estate because multiple items can fit onto one row.

From a purely aesthetic standpoint, gallery style lists really are the way to go, especially if each item contains an accompanying photo or graphic of some kind. From a coding standpoint, however, creating a gallery style list poses a quite a challenge that if not tackled properly can result in a broken page that does more harm than good to the design.

In this article, we'll be creating a rock solid gallery framework using just a little CSS, some server-side logic and a dash of jQuery for standards-challenged browsers. Here's what we need it to do for us:

  • We're going to assume a fixed-width layout. That is, a fixed number of items per row and a fixed width for the gallery itself. While fluid layouts are gaining popularity and may be appropriate for a site that has a massive amount of data and doesn't need to look perfect (think Newegg), what we're going for here will look more consistent and work just fine for the vast majority of sites out there, which are using a fixed-width layout.
  • Each item should accommodate a variable amount of text without breaking the design.
  • The gallery can handle any number of items.
  • The markup must be completely semantic HTML and CSS with no cruft.
  • Everything must work cross-browser (IE6 included).
  • We want this to work flawlessly with a CMS, so any special classes must be added automatically via a (server-side) script.

The HTML Foundation

This is a pretty tall order, but it's nothing that can't be handled with some cleverly written CSS and a little help from jQuery. Let's not jump the gun, though. The first thing we need to do is write our markup.

This is pretty straightforward, as it is a listing page, after all. As you can see above, we've created a purely semantic unordered list with no unneeded markup. What's contained within the <li> tag and how many <li> tags there are is limited only by your imagination. In this example, we'll be creating a gallery of music albums. Each item has a title, short description and a thumbnail of the album cover.

The CSS Structure

To get the items to display in the gallery style, with multiple items on a row, we'll need to give each item a fixed width and then use float: left; so that multiple items stack in a row from left to right. For this example, I'll pretend that my content area is 720 pixels wide. With this width I can get four items at 150 pixels wide each onto a row, with a 40 pixel gutter in between items. Obviously these numbers will change from one design to the next. What's important to remember is that the gutter should only appear in between items and never on the outside edge. The left edge of the first item should align precisely to the left edge of the content area, and the right edge of the last item should align precisely to the right edge of the content area. It's this kind of pixel perfection that will push a design to the next level of polish and professionalism.

So far, everything has been quite straightforward, but the inclusion of the gutter creates a problem. Since the gutter only needs to appear between items (three gutters), adding a 40 pixel left margin to each of the four items results in four gutters, indenting our gallery 40 pixels inward from the edge of the content area and pushing the fourth item down onto the next line. Not good. The solution to this is removing the margin-left: 40px; declaration from the first item in each row. In order to select the first item in each row using CSS, we'll need give it a special class, as we have no other way of differentiating these items from the rest of the items. To keep things semantic, we'll simply assign it class="first". We'll need to do this to every fourth item, starting with the first one (so items 1, 5, 9, 13, etc.). If you're hand-coding a page, this is simple enough to do at first, but would certainly get annoying if in the future you had to remove one item from the list and then change all the special classes. If you were using a content management system, adding the class by hand would likely prove impossible. Instead, we'll want to use some server-side logic to automatically assign our class.

The ExpressionEngine Goodness

Adding a class to every nth item in ExpressionEngine is extremely easy.

Our ExpressionEngine gallery template would look something like what you see above. Inside our repeater template, which is the <li> tag, notice the switch parameter. This is a super flexible piece of functionality that allows you to rotate between bits of code in a fixed pattern. Each bit of code is separated by the pipe character. Since we just need to add class="first" to the first item and not do anything to the other three items, we just add three pipe characters after class="first" and don't put anything between them, so we have {switch='class="first"|||'}. ExpressionEngine will run through the four conditions and then loop back to the first one as long as there are items to be displayed, so every fourth item starting with the first will receive class="first" and the others will remain unchanged—exactly what we need! This is just one application for this amazing piece of functionality.

If you use WordPress or TextPattern instead of ExpressionEngine, you'll likely need to write a bit of PHP to get this same type of function working, but it shouldn't be anything too complex. (I prefer not to write PHP for stuff like this, so I use ExpressionEngine, but I digress!)

One Last Concern

The last thing we need to do is make sure that varying amounts of text in each item don't break the grid. This occurs when there is one taller item and a shorter one after it, causing the next row to want to start underneath the shorter item rather than back at the left side of the gallery (see example below).

To achieve this, we're going to give that first item on each row another CSS property that you might be familiar with—clear: both;. This works like a reset switch and tells the browser to move the selected item and all the items that follow it clear of any floated elements. This ensures that a new row will only start below the tallest item in the row before it. This technique works flawlessly in standards-compliant browsers like Firefox, Chrome and Safari, but unfortunately not in our arch nemesis, Internet Explorer.

Internet Explorer is going to need a little help from good old jQuery to behave like a decent piece of software. We're going to use Rob Glazebrook's EqualHeights jQuery Plugin to force all the items to take on the height of the tallest one, thus fixing the floating problem in IE. Since this issue is specific to IE, we'll use conditional comments in the head of the document to load and execute the JavaScript, meaning that standards-compliant browsers will ignore it and display the list properly using only CSS. On a real site, you'd probably want to link to jQuery outside the conditional comments because it will likely be used for other stuff, but for this example we'll keep it inside so good browsers don't have to load it.


We now have a truly dynamic gallery style grid layout that will not break, regardless of the amount of text in a given item and which browser it's viewed in. While the logic behind creating this framework might be somewhat complex, the resulting code is very straightforward and pretty much unbreakable. It can be recycled from project to project with the only modification being the width of the gallery, items and gutters.

View the Live Demo  •  Download The Source Code

Back To News Listing

Back To Top