Image-Free Apple Style Pagination with CSS3

Written by Ben. Filed under Code. Tagged , , , , . Grab the Short Link. Bookmark the Permalink. Post a Comment. Leave a Trackback URL.

Explaining My Inspiration

Beautiful PaginationI remember the first time Apple introduced a very simple pagination UI element, back in an early version of the iTunes Store. I loved this element. It was clean, simple, easy to understand. Everything about it just seemed to work. Unfortunately, the latest version of the store no longer sports this elegant form of pagination. It’s been replaced with an anorexic scroll bar which means I can’t show you a screen capture. However, if you used iTunes a year or two ago, you’ll remember what I’m talking about. It’s the small row of dots with one “selected” to show you where in a set of pages you are. Apple used this with a simple right-to-left animation to add to the illusion that you were sliding through their content.

For some strange reason, this simple user experience made a mark on me. Honestly, I’m not even sure if Apple really introduced this form of pagination. This is just the first time I remember seeing it.

So, flash forward to a few weeks ago when one of the FORGE UI/UX Designers (Andy Rossi) hands me a PSD of a design for a web-app we’re working on. To my delight, Andy has recreated this style of pagination – with his own twist, of course. My job is to turn this beautiful little UI element into something that’s usable. And, if you know me, that means finding a robust solution, something that can be expanded easily and will degrade gracefully.

The rest of this article walks through my process in creating this interface element with the semantic and forward-thinking approach that makes FORGE unique in our market.

Project Paramaters

I had a few requirements in getting started, that I’ll share with you first:

  • semantic mark-up
  • cross-browser/operating system compatible
  • image free

The first two seem simple enough, but the last (image free) may seem a little odd. This stems from my recent interest in incorporating CSS3 into our production work at FORGE. We’ve been experimenting (like many others) with using some of the browser vendor specific CSS properties and allowing for a graceful degradation in “lesser” browsers. I was curious if this could be done simply with background-color and border-radius, so I set out to do it.

Writing the Mark-Up

I decided early on to use an ordered list as the primary mark-up element. We’re talking about a UI component that represents where you are in an ordered set of pages, so this makes semantic sense. Here’s what I came up with:

<ol class="pagination">
	<li class="on"><a title="Page 1" href="page1.html">Page 1</a></li>
	<li><a title="Page 2" href="page2.html">Page 2</a></li>
	<li><a title="Page 3" href="page3.html">Page 3</a></li>
	<li><a title="Page 4" href="page4.html">Page 4</a></li>
</ol>

Quite simply, you can see we have an ordered list with a class of “pagination”. Each list item inside our ordered list contains an anchor tag pointing to the page it represents. The class of “on” is added to the list item containing a link to the current page. This should look very familiar as most of us are handling our standard page navigation with mark-up very similar to this.

Ordered List with No CSS

Ordered List with No CSS

This mark-up renders pretty much the same in every browser our there. Here’s a screen capture I pulled from FireFox 3.5 on my Mac Book Pro. Kinda boring, but it gets better.

Adding Some Style

Now the fun begins. Let’s apply some simple styles to get this looking more like our elegant Apple pagination. First, we’ll remove the numbers on the left side of the list with a simple list-style:none;. Then we’ll float the entire list to the left and throw a 2 pixel border on it. Additionally, let’s remove all the padding from our ordered list as browsers typically will stick some padding on the left side.

Next we’ll make some adjustments to the list items and anchor tags. Both of these elements will need floated to the left to get them to flow horizontally instead of vertically and to get the ordered list’s border to show up in the right spot. Then we can set a fixed width and height for the anchor tags (I picked 6 pixels, but you can adapt these styles to suit your taste) and use the old text-indent: -9999px; trick to hide the anchor text. Finally we’ll need a little breathing room for our anchors, so let’s put some margin on the right side of each and give them a background color that matches the border of the ordered list.

The CSS should look something like this so far:

.pagination {
  list-style: none;
  float: left;
  border: 2px solid #4b4b4b;
}

.pagination li {
  float: left;
}

.pagination li a {
  float: left;
  width: 6px;
  height: 6px;
  margin-right: 3px;
  text-indent: -9999px;
  background-color: #4b4b4b;
}
Basic CSS applied to our ordered list (FireFox 3.5 on OS X on the left and IE7 on WinXP on the right)

Basic CSS applied to our ordered list (FireFox 3.5 on OS X on the left and IE7 on WinXP on the right)

This screen capture shows how things are looking in FireFox 3.5 on a Mac (left) and IE7 on WinXP (right). You can see we’re starting to get somewhere. Not quite complete, but certainly moving in the right direction. You’ll notice that the small squares are click-able links, these are actually the anchor tags. I’m sure you have also noticed that the “squares” aren’t quite square in IE. We can fix this by adding a line-height of 6 pixels to the anchors. You may also have noticed that the spacing isn’t quite right. We’ve set a 3px margin on the right of each anchor, which actually puts 6px of space between the last anchor tag and the ordered list’s border. If we remove the 3px padding from the right of the ordered list itself, we’ll have this problem solved.

Making Circles from Rounded Corners

CSS3 provides a beautiful little property called border-radius. This allows us to create rounded corners with CSS alone. Unfortunately, most browsers don’t support the official CSS3 property name yet. Luckily they do have vendor specific prefixes which allow us to get to some of this functionality now. Let’s set the -moz-border-radius, -webkit-border-radius and the border-radius properties of the anchors to 3 pixels. Since the anchor’s are 6 pixels high and 6 pixels wide, a 3 pixel border-radius will make a perfect circle. Let’s also set the same properties of the ordered list itself to 8 pixels. The calculation here is a little more complex. We have 6 pixels of height (from each anchor) plus 3 pixels of padding above and below each anchor (which puts us at 12 pixels) plus 2 pixels in the thickness of the top border and the bottom border. This gives us a total height of 16 pixels. Cut it in half and you get the 8 that we need.

Note: we will include all three of these properties in our CSS. If the browser doesn’t recognize a given property, it will just ignore it. Putting the actual border-radius property in is just a little future-proofing, for when the browsers actually support this without their vendor prefix.

Here’s the modified CSS:

.pagination {
  list-style: none;
  float: left;
  padding: 3px 0 3px 3px;
  border: 2px solid #4b4b4b;
  -moz-border-radius: 8px;
  -webkit-border-radius: 8px;
  border-radius: 8px;
}

.pagination li {
  float: left;
}

.pagination li a {
  float: left;
  width: 6px;
  height: 6px;
  line-height: 6px;
  margin-right: 3px;
  text-indent: -9999px;
  background-color: #4b4b4b;
  -moz-border-radius: 3px;
  -webkit-border-radius: 3px;
  border-radius: 3px;
}
Basic CSS with a few modifications (FireFox 3.5 on OS X on the left and IE 7 on XP on the right).

Basic CSS with a few modifications (FireFox 3.5 on OS X on the left and IE 7 on XP on the right).

You can see from the screen capture that the FireFox version (on the left) is looking great. Unfortunately, IE doesn’t support the border-radius property in any way. So, we’re out of luck getting the pagination to look exactly the same in IE. I actually have no problem with this. The squares, while not what we were going for originally, are still functional. They also provide a better user experience than a numbered list of links… The real question is, are you OK with some visitors seeing circles and some squares?

The ordered list with most of the CSS applied. Various browser results shown.

The ordered list with most of the CSS applied. Various browsers tested.

Now, the only thing that’s left is to add a little color modification to the “current” page. While we’re at it, we’ll specify a background color on the body to make this thing look great. Additionally, I noticed that on FireFox, if you click on one of the circles, you see an outlined box around a portion of the ordered list. This can be removed with a simple style applied to the anchors: outline: none;.

Correction: adding outline: none; removes key accessibility functionality from this system. Please don’t do this. I’m working on an alternative :active style which will solve this problem! Thanks for your patience.

Here’s the final CSS:

body {
  background-color: #2b2b2b;
}

.pagination {
  list-style: none;
  float: left;
  padding: 3px 0 3px 3px;
  border: 2px solid #4b4b4b;
  -moz-border-radius: 8px;
  -webkit-border-radius: 8px;
  border-radius: 8px;
}

.pagination li {
  float: left;
}

.pagination li a {
  float: left;
  width: 6px;
  height: 6px;
  line-height: 6px;
  margin-right: 3px;
  text-indent: -9999px;
  background-color: #4b4b4b;
  -moz-border-radius: 3px;
  -webkit-border-radius: 3px;
  border-radius: 3px;
}

.pagination li.on a {
     background-color: #1f84e3;
}
The final ordered list with all of our CSS applied. Various browsers tested.

The final ordered list with all of our CSS applied. Various browsers tested.

And this screen capture shows how it looks in various browsers with all of our styles applied. You can see that it’s not exactly consistent, but it’s darn close, and still functional everywhere. The fact that we’re not using any images here is what’s most fascinating to me. It’s proof that we really do need to start evaluating how we do things everyday. Given this task six months ago, I would have inevitably started in PhotoShop chopping up some circles. Today, things are different. It’s a great time to be web developer.

Another great thing about this code is how expandable it is. Need to fit a few more pages in? Just add list items and it works beautifully. No heading back to your image editor to re-export that border image. Color changes are a breeze also. It’s ALL taken care of in the CSS file – it really doesn’t get any easier than this.

What’s Next?

After completing this much, I applied some JavaScript to animate a fade out and fade in of the current anchor during the page transition. This is actually quite simple, but I’ll save that for another day.

I also had a thought that we could do all of this using the “em” measurement instead of pixels. I did a quick test and it was quite entertaining to watch the entire pagination list grow and shrink as I changed my browser’s default font size. I don’t know that this is something people would expect, or need, but it is kind of fun.

I would also like to state, that I have NOT done a complete browser/OS test run of this. Only the browsers you see listed above were tested, so I’m sure there are a few other issues that could be addressed. If you happen across an instance where this doesn’t work, feel free to post a comment and we’ll get it figured out.

The example files are available for your viewing (or downloading) pleasure at the following links. Feel free to use and enjoy (and show a little link-love).

Pixel-Based Image-Free Apple Style Pagination

Em-Based Image-Free Apple Style Pagination

Download Apple Style Pagination Examples

One Comment

  1. Posted November 20, 2009 at 6:39 am | Permalink

    Please note my correction in the post above regarding the outline property. When I have a free moment, I plan on working out some nice accessibility styles. Until then, I appreciate your patience!

One Trackback

  1. By Removing the onclick Outline from Links - techblog on November 16, 2009 at 7:53 am

    [...] Nov.16, 2009 in CSS Ben from Forge Ideas wrote up an interesting breakdown of how to create a simple pagination UI with CSS3 instead of images, and he mentions that it’s possible to remove the border that some browsers place around [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

...