Kimler Sidebar Menu

Kimler Adventure Pages: Journal Entries

random top 40

Beautify a Resource List

Beautify a Resource List

May 21st, 2009  · stk

Sometimes we include a list of "additional information" links at the end of our articles. Generally, they've been styled on the fly, but we thought it was high time to spend a bit of attention on this detail. The resulting CSS-styled ordered list looks nice, includes a block hover effect, a "visited" status indicator and is XHTML/CSS valid. We thought people might like to use it on their website, so included a tutorial and ZIP file.

Adding Pizazz to an Ordered List

A lot of online articles include, at the end of the article, a list of "additional resources" - or links - for further reading and research. Several Randsco articles have such a list, but styling them is generally an afterthought, because most of the energy goes into the article itself.

Ideally, additional information links would be contained in an ordered list. It's semantically correct and allows visitors to reference a particular link by number. Unfortunately, we don't always follow our own advice and some of these links are held in simple paragraphs which may, or may not, be numbered.

We thought it was about time that we come up with a proper "additional information" list. By melding together some existing design ideas and adding our own CSS touches, we have constructed an ordered list that not only looks nice, but also includes a number of other features: a hip CSS roll-over effect; compatibility with fixed-width or liquid layouts; toggle-able ":visited" link status images; pure CSS (no JavaScript, AJAX or jQuery); and it's cross-browser friendly.

Have a look at the demo page and read on to get the ZIP file, learn about the design, look at the code and see the live example.

Our Newly Styled Ordered List

If you jump to the bottom of this article, you'll see our newly-styled "additional information" ordered list.

The new list includes a relevant level-four heading (h4), which fits in nicely with the rest of the page outline. Following the heading is a rendition of Soh Tanaka's sexy ordered list. When you hover over each item, you'll note the whole list element "lights up", which is accomplished using a CSS block hover technique. (Offsite links - which open in a new window - show with a greenish background and onsite links - which open in the same window - show up with a pinkish background - in keeping with our current link policy). If you click on a link and then return to this article, you'll see a check-mark graphic next to the item you clicked. This is the :visited status image that let's visitors know which (if any) of the links they followed.

We think the new design is nice. It also stretches and squeezes with the monitor width (between the normal minimums and maximums applied) ... so it works in a liquid layout. It's also cross-browser friendly. (I tested it from a PC using IE6, IE7, FireFox, Netscape, Opera, winSafari, Chrome and Flock).

The Design Process

For us, an "additional information" is more than just a list of links, which says nothing about the relative value of information. We like to qualify each link with a line or two that describes the link: why we've added it, how it might help a visitor or even what kind of link it is (article, online tool, PDF document, etc.)

With this in mind, we spotted a sexy-looking ordered list and we used that as our starting point. We also remembered the block hover effect and wanted to incorporate that as well.

At this point, we had a decision to make. How to achieve the :hover effect? Do we cater to IE6 and stuff everything into an anchor tag? Or do we make use of Peter Nederlof's Whatever:hover?

Because we've been popping stuff since early 2005, we continued with the same-old "stuff it in the <a>" route. Unfortunately, this decision created some extra CSS for cross-browser support (IE needed some really odd directives), limited semantically correct, block-level elements - notably <p> and <h5> - inside the list elements and also capped the number of links per list element to the stratospheric number of "one".

LOL ... after reading all the drawbacks, I'm tempted to go back and do a Whatever:hover version ... especially since I've been barking about ceasing to cater to IE6 - a junk pile of a browser if there ever was one.

Laziness wins. This version is done and I'm rolling with it - drawbacks and all!

It took some CSS tweaking to blend the style, hover effect, make it work in a liquid layout (always a challenge) and add the :visited graphic cues.


The XHTML Code

Here is the essential XHTML from the demo page:


  <div class="more-info VisitImg">  
    <h4>Additional Information</h4>  
        <a class="ext" href="" title=" click to read (opens in a new window) "><img class="status" src="checkmark.gif" alt="check" title="" />CSS-Styled Lists: <span class="para">This <em></em> website article covers more than 20 demonstrations, tutorials and best practices for styling lists, using CSS.</span></a>  
        <a class="ext" href="" title=" click &amp; go (new window) "><img class="status" src="checkmark.gif" alt="check" title="" />Listutorial <span class="para">This classic site takes you through basics of building background image lists, rollover lists, nested lists &amp; horizontal lists.</span></a>  
        <a href="" title=" Read the full article (opens link in the same window) "><img class="status" src="checkmark.gif" alt="check" title="" />Beautify a Resource List <span class="para">The full Randsco article that accompanies this demo page (not done yet ... lol ... not <em>even started</em> yet!).</span></a>  
      <li class="last">  
        <a class="ext" href="" href="#" title=" Learn the &#034;clip&#034; CSS directive (new window) "><img class="status" src="checkmark.gif" alt="check" title="" />The Misunderstood CSS "Clip" Property<span class="para">The CSS clip property is one of the least used.  Most people don't know <em>when and how</em> to use it. Learn more.</span><span class="para"><em>(Clip is used for the :visited status image in this demonstration page).</em></span></a>  


In looking at the code, it's fairly straight forward. A check-mark image is first element added to each of the list items. This is for the :visited status indicator. (These images could have been handled in the CSS by adding two more anchor tag background images, but for two small check-marks, it creates more overhead, so they're added in the XHTML instead). Because XHTML does not allow block-level elements inside inline-level elements, AC/DC <span> tags are used, in place of block-level <p> tags. (To me, this is semantically weird. Here, the <a> tags are defined in the CSS as block-level elements, so shouldn't they now be able to hold block-level elements? ... Hmmm.)

Of course, for IE6, everything in the list element is wrapped in an <a> tag, otherwise nothing would :hover properly. The rest is just normal markup, as you would expect from an ordered list. The whole lot is wrapped in a <div> having a classname (so multiples can exist on a page).

If you want to use the code, just cut'n-paste from above. Add it to a blank (preferably XHTML DOCTYPE) web page. Get it working before trying on your blog or full page, which might contain conflicting CSS directives.

Deployment on this dynamically-generated page requires a tad more specificity, which has necessitated an ID, rather than a classname. I don't recommend viewing the source of this page, if you want to see the mark-up for the ordered list. Instead, head to the stand-a-lone demo page.


The CSS Styling

Here's the essential CSS that controls the styling for the ordered list:


/* - - - - - - - - - - -  
* resource list styling  
* (an ordered list)  
* 2009  
* v090521-art  
/* block + heading */  
.more-info {  
  margin:10px auto;    
.more-info h4 {  
  font:bold 150% georgia,serif;  
  color:#666; background:inherit;  
/* ordered list */  
.more-info ol {  
  border:1px solid #ddd;  
  margin:20px 0; padding:0 0 0 35px;  
  background:#fff url(ul.gif) repeat-y;  
.more-info li {  
  margin:0; padding:0;  
  color:#555; background:inherit;  
  font:bold 1.5em verdana,sans-serif;  
/* block hover effect */  
.more-info a,  
.more-info a:visited {  
  padding:10px 0 10px 10px;  
  background:#f4f4f4 url(ul.jpg) no-repeat;  
  border:solid #ccc;  
  border-width:0 0 1px 0;  
.more-info li.last a,  
.more-info li.last a:visited {  
.more-info a:hover,  
.more-info a:visited:hover {  
  background:#fef url(ul.jpg) no-repeat 0px -800px;  
  border:solid #ccc;  
  border-width:0 0 1px 0;  
.more-info a.ext:hover,  
.more-info a.ext:visited:hover {  
  background:#efe url(ul.jpg) no-repeat 0px -400px;  
  border:solid #ccc;  
  border-width:0 0 1px 0;  
.more-info li.last a:hover,  
.more-info li.last a:visited:hover {  
/* :visited status */  
/* Note: To toggle OFF the :visited image status indicator -  
* just change the "VisitImg" classname to "noVisitImg" in  
* the XHTML code.  
* (Or remove the relevant XHTML/CSS code)  
.more-info a img {  
.more-info a:visited img {  
  clip:rect(0, 50px, 27px, 25px);  
.more-info a:visited:hover img {  
  clip:rect(0, 25px, 27px, 0);  
.more-info.noVisitImg a:visited img {  
/* span as paragraph */  
.more-info .para {  
  margin:10px 10px 10px 50px;  
  font:normal .8em verdana,sans-serif;  


The CSS is broken down into 5 commented sections.

The first is "block + heading", where the wrapping "more-info" <div> is styled and the heading (level 4 here) is styled. The block is set to be 80% of the width of the page and is centered. A bit of a top and bottom margin is applied. The heading color and font are selected.

The ordered list element directives follow. A thin border is added to the ordered list group and margins/padding are applied - to move the numbers inside the group, zero browser differences and leave 35 pixels for the number background shading image (2 pixels tall and 35 pixels wide | 287 bytes). Each list element margin and padding is explicitly defeated, text color and font styles are chosen (this text style will show for the numbers, as we'll override the styles for things inside the list elements.)

It's all pretty straightforward.

Next comes the block hover effect. Because we want the whole block to "light up", we change the display to "block". The padding we add to keep things looking nice, apply a background image - a 3-image construct holding a gray/pink/green fade (3 images stacked vertically, 1000 pixels wide by 400 pixels tall | 11,531 bytes) and position it for each of the three "cases" (unhovered, hovered internal link and hovered external link), covering :visited cases as well. The border is a bit of a fiddle. We don't want to add a double line at the bottom, so create a classname of "last" for the last list element and defeat the bottom border. The rest all have a bottom border applied, which give the appearance that each list element is a "cell". We defeat the normal underline that's applied, to keep things from looking awful.

Then comes the :visited status image styling. This feature is toggle-able and turned "on" by default. (To toggle this "off" for a particular list, just change the 2nd classname in the "more-info" DIV from "VisitImg" to "noVisitImg"). The visited link image contains two check-marks, a blue one and a red one (50 pixels wide by 27 pixels tall | 405 bytes). First, we position the image absolutely (so we can move it later and it won't affect the flow of the text), then we defeat the normal blue link border and finally turn visibility "off", as we only want it to show if the list element has been "visited". Then, we handle each of the two cases: unhovered and visited, or hovered and visited. For the unhovered-visited case, we turn visibility "on", then clip the image so that only the blue check-mark appears. (Clip is an often misunderstood CSS directive, which can only be applied to absolutely positioned elements and has a syntax that's both weird - in terms of how the values are used - and in terms of browser support. This article does a good job of summarizing the clip directive.) The image is positioned relative to its default location by margining, rather than by using top|bottom|left|right. (Each absolutely positioned image is positioned at its page position in the HTML, which is why each LI has the image first. Positioning with margins moves the image relative to that location and obviates the need to reset the origin by positioning its parent). Lastly, we add a directive to defeat the visited link status indicator, by turning visibility off by using the "noVisitImg" selector (with higher specificity).

Finally, the <span> tags, which act as "paragraphs", are styled. This includes making it a block level element, margining and picking font styles and color.

That's it ... or at least ... that's it for FireFox and all other modern browsers. If you were to look at Internet Explorer at this point, you might seriously consider pulling out all of your hair, as it looks nothing like what you might intend.


Fixing Internet Explorer

I'd show you a picture of how IE renders the above code, but it's too ugly for this blog! Suffice it to say that IE6 and IE7 both fail to render as one would like. Let's fix IE7 first, since it gets closer than IE6 and requires less head-banging.

The major problem with IE7 is that it only does the :hover bit over the text in each list element and not in the padding or margins. It's a "hasLayout" issue and most of the CSS directives that turn on the "hasLayout" property, are undesirable. Two that can be used here are: "width:100%" and "overflow:hidden".

Additionally, IE7 (all Internet Explorer version for that matter), don't correctly interpret the comma separator that's mandated for the clip directive. You have two choices here, either go with the non-comma version, which doesn't validate, but does work -or- feed the correct, comma-delimited version to modern browsers and a non-comma version to IE (which is what we do here). One of the nice things about IE conditional comments is that the W3C CSS Validator ignores their contents.

The fix for IE7 is simple and is applied in a conditional comment that targets that particular browser:


<!--[if IE 7]>  
  <style type="text/css" media="screen, projection">  
  /* ie7-specific */  
    .more-info ol { width:100%; } /* must specify width to get whole LI block hoverable */  
  /* erroneous IE clip separators */  
    .more-info a:visited img { clip:rect(0 50px 27px 25px); }  
    .more-info a:visited:hover img { clip:rect(0 25px 27px 0); }  


Of course, IE6 has other problems, all of them very odd. Firstly, it has the same "hasLayout" issue as IE7, but unlike IE7 - (a) overflow doesn't turn on "hasLayout" and (b) applying width to the <li> element doesn't achieve the goal. IE6 wants it applied to the <a> tag.

So, we add "width:100%" to the <a> tag and then the number slide to the bottom of the list block, from the top. This just looks goofy and we want to fix it. The easy fix is to float the <a> to the right, but doing this almost makes the problem worse. Though the numbers are now back at the top of the list block, the list blocks now extend too far to the left and overprint the numbers. In addition, there's an introduced "bottom padding" of 20px or so. Setting the width for the ordered list group at 100% takes care of the left-hand overrun, but the strange "bottom padding" persists. The only way I got rid of it was to explicitly set the bottom-padding for each <li> to be 1px (then "erase it" with a negative bottom margin of the same amount.

Of course, IE6 and lower will also require a non-comma-delimited clip directive, just like IE7, so it's added (for a second time, as opposed to making a third conditional comment that targets all versions of Internet Explorer).

Whew! After much monkeying, we now have something that looks darn near identical to the other browsers. The only difference I can tell, is that the numbers are positioned at the very top of each list element and not padded down. (Not a huge issue for me and besides ... it's IE6 ... it should be treated to something odd!)

Here's the final IE6 (and lower) CSS:


<!--[if lt IE 7]>  
  <style type="text/css" media="screen, projection">  
  /* ie6 and lower*/  
    .more-info ol { width:100%; } /* must specify width to get whole LI block to be hoverable */  
    .more-info li { padding: 0 0 1px 0; }  /* must give it padding or IE6 tosses in an ugly bottom buffer */  
    .more-info a {  width:100%; float:right; } /* width games */  
  /* IE erroneous clip separators */  
    .more-info a:visited img { clip:rect(0 50px 27px 25px); }  
    .more-info a:visited:hover img { clip:rect(0 25px 27px 0); }     


Conclusions and Summary

We've finally created a nicely styled, ordered list for our "additional resources" that we often add to the end of our web articles. We have provided the valid XHTML and CSS code for this ordered list, as well as a discussion about the design and a tutorial that would allow one to use it themselves.

The nicely styled ordered list includes several features: a CSS block-hover effect; the ability for deployment in a liquid or fixed-width layout; pure-CSS (no JavaScript dependencies); "visited link" status images and cross-browser capabilities.

If you want to play with the files, just download the ZIP file. Alternatively, everything you need can be obtained (stolen, kyped, nicked or pilfered) from the demo page.

As with all the stuff at Randsco, you're free to use this on your personal website. Those using it on a commercial website need to donate, which helps keeps it free for others. Learn more on our copyright page. Good luck and if you need support or have any questions regarding usage, deployment or technical issues, please contact me. (My rates are high and I'm worth it)! :p




Views: 53872 views
4 Comments · GuestBook
default pin-it button
Updated: 25-May-2009
Web View Count: 53872 viewsLast Web Update: 25-May-2009

Your Two Sense:

XHTML tags allowed. URLs & such will be converted to links.

Subscribe to Comments

Auto convert line breaks to <br />

1.flag Gary Comment
Very nice piece of work Scott, love the visited ticks ;). Looking forward to using it on future blog posts.

Another CSS rabbit out of the hat!

2.flag stk Comment
Gary - Glad you like. Had fun making it (except the wrestling with IE part ... blast that rich B.Gates guy).
3.flag John Comment
Scott, a comprehensive write up. Thanks for the effort .
4.flag stk Comment
Thanks ... and to think ... it was done in under 2,500 sentences! :p