--- comments: true date: 2010-11-17 18:27:32 layout: post slug: mark-up-a-semantic-accessible-progressively-enhanced-mobile-optimised-progress-bar-bonus-style-the-numbers-in-an-ordered-list title: 'Mark up a semantic, accessible, progressively enhanced, mobile optimised progress bar (bonus: style the numbers in an ordered list!)' wordpress_id: 1711 categories: - Web Development tag: - Accessibility - CSS - CSS3 - HTML - Markup - Mobile - Progressive Enhancement - Semantics --- How about that for an over-the-top title? But it's true, that's what we're going to be doing. It's been a while since my last post, unfortunately, so I thought I'd make up for it with this sizeable offering in which we will learn a lot of really great techniques in order to make something as simple as a progress bar. By which I mean a breadcrumb-esque meter of steps, such as you might find on a checkout process; we are making [this](/demos/progress-bar/): [](/demos/progress-bar/) And in doing so we will cover: * Design and build a semantic, accessible and sensible progress bar. * Utilise the much underused method of styling page-specific elements based on their IDs. * Style the numbers in an ordered list! * Progressively enhance it with some CSS3. * Optimise it for mobile. **N.B.** This article isn't so much about a progress bar, but more an illustration that best practices and more advanced techniques can be applied to even the most insignificant aspects of a build to create something awesome! ## Design and build Let us assume the brief is this: We require a numbered progress bar to indicate user location (past, current and future) during a checkout path on the OurService⢠website. It must: * Be fully accessible. * Provide a section title with supporting information. * Highlight the user's current location in the process. * Be navigable. * Work on mobile devices. The design, let's assume, is predefined. It looks as above, purely because it has to. The design is not the major focus of this article, the code and techniques are. > "Code what you consume, not what you see." ### Design The progress bar shall be a linear, left to right series of linked labels. Current location shall be indicated by a change in colour, progression onto the next step shall be indicated by an arrow. ### Build For the purposes of this tutorial we shall assume the current page is the payment page. One school of though I find invaluable when it comes to sensible and semantic builds is code what you consume, not what you see. This is a very broad generalisation but works for the most part. Code content independently of (and before you consider) coding any styles. Web development basics, but fundamental to web standards and progressive enhancement. So, what are we consuming? It's an ordered list of steps which indicate location in a process. Okay so first off we know we need an `
There are a few things in this code which I've not yet mentioned, one is the ID on the ``, another being the class on each `/*------------------------------------*\
MAIN
\*------------------------------------*/
html{
height:101%;
}
body{
font-family:Calibri, Arial, Verdana, sans-serif;
background:#fff;
color:#88979e;
width:940px;
padding:10px;
margin:0 auto;
}
/*------------------------------------*\
PROGRESS
\*------------------------------------*/
#progress{
list-style:none; /* Remove the bullets */
float:left; /* Make its width equal to the combined width of the items inside it */
margin-bottom:20px;
}
#progress li{
float:left; /* Stack them all up left */
font-size:0.75em; /* Make the entire item smaller */
font-style:italic; /* Make the entire item italic */
}
#progress a{
display:block;
text-decoration:none;
padding:10px 25px 10px 10px; /* Padding to accomodate background image */
background:#7b8d77;
color:#fff;
}
#progress span{
font-size:1.333em; /* Bring the size of the title only back up */
font-weight:bold;
display:block;
font-style:normal; /* Undo the italics */
}
#progress strong{
font-weight:normal; /* Remove the bolding for CSS enabled browsers */
}
#progress a:hover{
text-decoration:none;
}
#progress a:hover span{
text-decoration:underline; /* Underline the title on hover */
}
#details-page .details-step a,
#account-page .account-step a,
#products-page .products-step a,
#payment-page .payment-step a{
background:url(../img/css/splitter.gif) right center no-repeat #a49d4d; /* Arrow image on the current step */
}
#go-page .go-step a{
background:#a49d4d; /* Arrow image not needed on final step, colour only */
}
All of the above is very obvious, it is essentially just like creating a normal navigational menu, and gives us this:

## Styling numbers in ordered lists
Next up we style the numbers in the ordered list by using the very very useful and much unknown CSS counter module. Because you have such limited control over the appearance of your bullets in (ordered) lists they can be a pain to style. This pain is alleviated somewhat when using an unordered list as you can simply use a background image. It is an altogether different story when you're using an ordered list as the bullet needs to change with each list item.
What we do here is use CSS to do a very prog-like job; we get it to loop through each item in a parent container and then increment a user-defined value each time it encounters a specified child. Sounds Greek? [Read this](http://www.impressivewebs.com/css-counter-increment/).
Once we have this number available to us we use the CSS `:before` pseudo-element and the `content:;` property to insert the number before each item. How cool is that?!
/*------------------------------------*\
PROGRESS
\*------------------------------------*/
#progress{
list-style:none;
float:left;
margin-bottom:20px;
counter-reset:step; /* Set up name of increment on parent */
}
#progress li{
float:left;
font-size:0.75em;
font-style:italic;
}
#progress a{
display:block;
text-decoration:none;
padding:10px 25px 10px 30px; /* Padding changed to 30px to accomodate number */
background:#7b8d77;
color:#fff;
position:relative; /* Relative position to allow absolute positioning later on */
}
#progress span{
font-size:1.333em;
font-weight:bold;
display:block;
font-style:normal;
}
#progress strong{
font-weight:normal
}
#progress a:hover{
text-decoration:none;
}
#progress a:hover span{
text-decoration:underline;
}
#progress li a:before{
counter-increment:step; /* Increment the step on each occurance of this (pesudo) element */
content:counter(step); /* Write out value of the increment */
text-align:center;
font-weight:bold;
position:absolute; /* Position number */
top:50%;
left:5px;
margin-top:-8px;
}
#details-page .details-step a,
#account-page .account-step a,
#products-page .products-step a,
#payment-page .payment-step a{
background:url(../img/css/splitter.gif) right center no-repeat #a49d4d;
}
#go-page .go-step a{
background:#a49d4d;
}
This then gives us this:

* * *
## Progressively enhancing
Now for the CSS3 progressive bits:
/*------------------------------------*\
PROGRESS
\*------------------------------------*/
#progress{
background:#7b8d77; /* Give the ol a background to prevent white showing through behind the items' round corners (change value to #f00 to see what I mean) */
}
#progress{
-moz-border-radius:5px;/* Round all corners of the progress bar */
-webkit-border-radius:5px;
border-radius:5px;
}
#progress a{
text-shadow:1px 1px 1px rgba(0,0,0,0.25); /* A small text-shadow */
-moz-border-radius:5px 0 0 5px; /* Round the top- and bottom-left corners */
-webkit-border-radius:5px 0 0 5px;
border-radius:5px 0 0 5px;
}
#details-page .details-step a,
#account-page .account-step a,
#products-page .products-step a,
#payment-page .payment-step a{
background:url(../img/css/splitter.gif) right center no-repeat #a49d4d;
}
#progress .go-step a{
-moz-border-radius:5px; /* Round all corners of the final step */
-webkit-border-radius:5px;
border-radius:5px;
}
The full, combined CSS for the progress bar so far is:
/*------------------------------------*\
MAIN
\*------------------------------------*/
html{
height:101%;
}
body{
font-family:Calibri, Arial, Verdana, sans-serif;
background:#fff;
color:#88979e;
width:940px;
padding:10px;
margin:0 auto;
}
/*------------------------------------*\
PROGRESS
\*------------------------------------*/
#progress{
list-style:none;
background:#7b8d77;
float:left;
margin-bottom:20px;
counter-reset:step;
-moz-border-radius:5px;
-webkit-border-radius:5px;
border-radius:5px;
}
#progress li{
float:left;
font-size:0.75em;
font-style:italic;
}
#progress a{
display:block;
text-decoration:none;
padding:10px 25px 10px 30px;
background:#7b8d77;
color:#fff;
text-shadow:1px 1px 1px rgba(0,0,0,0.25);
position:relative;
-moz-border-radius:5px 0 0 5px;
-webkit-border-radius:5px 0 0 5px;
border-radius:5px 0 0 5px;
}
#progress span{
font-size:1.333em;
font-weight:bold;
display:block;
font-style:normal;
}
#progress strong{
font-weight:normal
}
#progress a:hover{
text-decoration:none;
}
#progress a:hover span{
text-decoration:underline;
}
#progress li a:before{
counter-increment:step;
content:counter(step);
text-align:center;
font-weight:bold;
position:absolute;
top:50%;
left:5px;
margin-top:-8px;
padding:2px 6px;
background:rgba(0,0,0,0.25);
-moz-border-radius:20px;
-webkit-border-radius:20px;
border-radius:20px;
}
#details-page .details-step a,
#account-page .account-step a,
#products-page .products-step a,
#payment-page .payment-step a{
background:url(../img/css/splitter.gif) right center no-repeat #a49d4d;
}
#go-page .go-step a{
background:#a49d4d;
}
#progress .go-step a{
-moz-border-radius:5px;
-webkit-border-radius:5px;
border-radius:5px;
}
Which, when coupled with the markup, gives this:
[](/demos/progress-bar/)
* * *
### Recap
So, let's cover what we've done so far. We've:
* Coded up a semantic progress bar (using an ordered list and correct generic elements).
* Made it accessible (addition of the strong around the content for non-CSS browsers).
* Styled it all up.
* Made use of [the body ID trick](http://www.venturelab.co.uk/devblog/2010/06/body-idsmaking-life-easier-for-yourself/) to mark the current page.
* Used CSS counters to style the numbers of an ordered list
* Progressively enhanced it all to make it a little easier on the eyes.
## Mobile optimisation
For more information on mobile/iPhone optimised sites please see [my associated article](/2010/01/iphone-css-tips-for-building-iphone-websites/).
Next up we need to optimise this thing for mobile. This couldn't be simpler. The key to optimising sites for mobile is linearise. Linearise everything.
In your markup, add this line to the `` section, thus:
Progress
This tells the user agent that the viewport should be the same as the device's own screen-size, that it should be initially set to a scale of 1 (i.e. no scale), its maximum scale is set to 1, and that users can't scale themselves.
Now, add the following to the very end of your CSS file:
/*------------------------------------*\
MOBILE
\*------------------------------------*/
@media (max-width: 480px){ /* In any browser narrower that 480px... */
body{
width:auto; /* Give the body a fluid width... */
padding:5px; /* And a slight padding */
}
#progress{
width:auto; /* Give the list a fluid width */
background:none; /* Remove the list's background... */
float:none; /* ...and float */
}
#progress li{
float:none; /* Remove list item float, causing them to stack */
margin-bottom:1px; /* Space them slightly */
}
#progress a{
margin:0 10px; /* Indent the left and right of each item by 10px */
-moz-border-radius:5px; /* Round all corners */
-webkit-border-radius:5px;
border-radius:5px;
}
#details-page .details-step a,
#account-page .account-step a,
#products-page .products-step a,
#payment-page .payment-step a,
#go-page .go-step a{
background:#a49d4d; /* Set the background of the current item */
margin:0 auto; /* Remove the 10px indent to show that the step is current */
}
}
Now, if you want to test this and don't have a smartphone, or haven't got this hosted in a live environment, simply resize your browser window right down until you see the change. I tend to use the Firefox Web Developer Toolbar addon to [resize the window to 480x800px](/wp-content/uploads/2010/11/mobile-optimised-progress.jpg).
On the iPhone this now looks like:

* * *
## [Demo](/demos/progress-bar/)
For the full working demo head to [/demos/progress-bar/](/demos/progress-bar/). For the complete CSS (with reset) please see [/demos/progress-bar/css/style.css](/demos/progress-bar/css/style.css). Also, try using Firebug to change the ``'s ID to `go-page`.
* * *
## Final words
As I stated previously, this article isn't so much about the progress bar itself. What I hope this article has shown is how something as small and trivial as a progress bar has a wealth of little nooks and crannies in which to immerse yourself. Semantics, accessibility, using `` IDs to style current states without a `class="current"`, how to use CSS counters to style the numbers in an ordered list, how to progressively enhance lean markup, and how to optimise things for mobile in a flash.
All of the above skills are easily and quickly transferable. It might be a progress bar today, but what could it be tomorrow? Skills like the ones covered here give you the potential to make something great, out of something very very simple.