Grow your CSS skills. Land your dream job.

Better Ordered Lists (Using Simple PHP and CSS)

Published by Chris Coyier

Ordered lists are boring! Sure you can apply background images and do quite a bit of sprucing up to a regular ordered list, but you just don't get enough control over the number itself. Here is an example where you ditch the traditional ordered list and create your own!

If you set up a loop, or are already within an existing loop (think WordPress comments), the possibility for cool numbered lists presents itself. Just set up an integer variable in PHP that increments itself while the loop is running. Then echo the variable out where you need it and style it with CSS.

In this example, I used an h2 element with a huge font size, gray color, floated to the left, with a little right margin. This technique is nice 'n' bulletproof because it doesn't use any graphic elements to contain the number.

nicenumberedlists.jpg

Here is an example of a simple PHP loop:

<?php for ($i = 1; ; $i++) { 
		
   if ($i > 9) {
      break;
   }  ?>
		   
   <div class="comment-box">
      <h2 class="number"><?php echo $i ?></h2>
      <p>CONTENT GOES HERE.</p>
   </div>
		   
<?php } ?> 

Here is the applicable CSS:

h2.number {
	position: relative;
	top: 0px;
	left: 0px;
	font-size: 10em;
	color: #ccc;
	float: left;
	margin-right: 10px
}

#page-wrap {
	width: 760px;
	background: white;
	margin: 0 auto;
	padding: 10px 0px 50px 0px;
	background: white url(images/gradient2-bg.gif) bottom repeat-x;
}

#description-area {
	padding: 20px;
}

.comment-box {
	margin: 0px 0px 50px 50px;
	padding: 20px;
	width: 240px;
	border: 1px solid black;
	float: left;
}

LIVE EXAMPLE

DOWNLOAD EXAMPLE

Comments

  1. Mirmillo
    Permalink to comment#

    You can simplify your PHP by doing:

    <?php for ($i = 1;$i<10 ; $i++) { ?>
       <div class="comment-box">
          <h2 class="number"><?php echo $i ?></h2>
          <p>CONTENT GOES HERE.</p>
       </div>
    <?php } ?>
  2. Thanks Mirmillo! That is a bit cleaner.

  3. Permalink to comment#

    While I agree that your result looks good, I would have to disagree with your title. This is not at “Better Ordered List”, as it is NOT an ordered list at all. For something like this, you really should use an <ol>, although the styling options are very limited.

  4. BillyG
    Permalink to comment#

    I see a bunch of div’s, headers, and paragraphs. The only CSS ‘trick’ I see is a grid-derived layout.

  5. @kimblim: Why do you think for “something like this” you should use an <ol>? I don’t see any semantic benefit of doing it one way or the other. Also, I think the title is appropriate. In my opinion the example is better than an regular ordered list and the result is indeed an ordered list.

    @BillyG: While all of my examples will utilize CSS in some way or another, they may not be all be specifically focused on CSS. The “trick” part can be fairly loosely interpreted =).

  6. Permalink to comment#

    @Chris:
    You said it yourself: “and the result is indeed an ordered list”. If that is the case, then you really should use an <ol> (ordered list). Using anything but an <ol> for an ordered list makes no semantic sense whatsoever. Your example takes a heading (<h2>) and turns it into a numbered bullet.

  7. Permalink to comment#

    ^ “numbered bullet” should be “numbered list item”

  8. @kimblim: You are saying that if it’s not an <ol> it’s not an ordered list and I’m saying just because it’s not an <ol> doesn’t mean it’s not an ordered list. Just different ways of looking at it I guess. If it was possible to do this example by using an <ol>, I agree that would be better semantically, but unfortunately it’s not.

  9. I think people are missing the point hear. This is not actually a list or even an ordered list this is an alternative to a list.

    I like it, it is different but thats the whole point :D

  10. Permalink to comment#

    You could have a floated element which makes the content indented. Then you wouldn’t need any server-side scripting and it would be a semantic OL. You can even keep the HTML fully semantic and add the html with JS.

    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <title>Untitled Document</title>
    <script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.2.1.pack.js"></script>
    <script type="text/javascript">
    $(function() {
    	$("ol li")
    		.addClass("improved")
    		.each( function() {
    			$(this).html('<span class="content"><span class="block"></span>'   $(this).html()   '</span>')
    		})
    });
    </script>
    <style type="text/css">
    body { font-size:75%; font-family:Verdana, Arial, Helvetica, sans-serif; }
    p { margin:0 0 0.5em 0;}
    ol { padding:0; margin:70px 0 0 70px;}
    li.improved { font-size:400%; color:#ccc; padding:0;width:40%; float:left;margin: 0 0 50px 50px; }
    li.improved span.content { font-size:25%; color:#000; position:relative; top:-40px; left:-60px; vertical-align:bottom;}
    li.improved span.block{ float:left; width:60px; height:110px; }
    </style>
    </head>
    <body>
    <ol class="better">
    	<li>Content goes here.</li>
            <li>Content goes here.</li>
            <li>Content goes here.</li>
            <li>Content goes here.</li>
    </ol>
    </body>
    </html>
    
  11. Wow very interesting and in depth. Keep it up! :)

  12. Ian
    Permalink to comment#

    How can we change the content of each item?

  13. @Ian: Check out Dave’s awesome code suggestion above. Same results, and you can specify the content for each item instead of it being part of the loop.

    Originally, I was thinking this would be part of an already existing loop where the content is getting dynamically generated (like being pulled from a database). For example, the WordPress comment loop…

  14. Permalink to comment#

    Actually, if you really are interested in reducing your php code then you can do this (also semantically nicer):

    <?for ($i = 1;$i<10 ; $i  ):?>
       <div class="comment-box">
          <h2 class="number"><?=$i?></h2>
          <p>CONTENT GOES HERE.</p>
       </div>
    <?endfor;?>

    As of PHP 5.1 this is valid syntax.

  15. Very Nice. Gonna try intregrate it into my wordpress design.

  16. Paul Walker
    Permalink to comment#

    For more simple styles (basically, separate text styling) It’s easier to do the following:

    CSS:

    ul, ol {
    /*Bullet Styles*/ 
    }
    
    ul>*, ol>* {
    /*text Styles*/
    }
    

    HTML:

    ul>
    li>p>paragraph…/p>/li>
    li>p>paragraph…/p>/li>
    li>p>paragraph…/p>/li>
    /ul>
    
    ol>
    li>p>paragraph…/p>/li>
    li>p>paragraph…/p>/li>
    li>p>paragraph…/p>/li>
    /pl>
    

    Of course – this has the limitation of the numbers not being able to be (straightforwardly) positioned separately from the text (or for it to be floated), but unless you *need* to do that, it’s probably, IMO, a better solution.

  17. “If it was possible to do this example by using an , I agree that would be better semantically, but unfortunately it’s not.”

    Why is it not possible with an unordered list? Simply replace your divs with list items, remove the numbering from the list and include it with PHP as you’ve done, pretty much exactly as you’ve done with your comments. So in this case I believe Kimblim is completely right.

  18. Oh… At the moment i develop a website-concept and perhaps i need your tip ;)

    Ralph

  19. Permalink to comment#

    forgot to add: Place this under your last box: (note: didnt test it, but it should just work perfect)

    <script language="JavaScript" type="text/javascript">
    	function list_it(){
    	//Get all H2 elements
    	var h2s = document.getElementsByTagName('h2');
    	//Set up the counter for the numbers
    	var listCounter = 1;
    	//start to loop true all h2's
    	for (var i = 0; i<h2s.length; i  )
    	{
    		var h2 = h2s[i];
    		//only do the following if the H2 has the classname number
    		if(h2.className == 'number') {
    			//Change innerHTML 
    			h2.innerHTML = listCounter;
    			//Add 1 to the counter
    			listCounter  
    		}
    	}
    }
    //Fire the list function
    list_it();
    </script>
    

    It will loop true all H2 elements, checks if they contain the className number and replaces the content with ‘list number’

  20. nice article. here’s how I tame odrered lists ;).

  21. Great use of order lists. Modification from Mirmillo and others have made a master pieces of CSS script.

  22. Permalink to comment#

    how do you number the comment entires? could you supply code and instruction on how to edit my css?

  23. Permalink to comment#

    here’s a very simple method i created, without any php, javascript– just pure CSS– to get my number-indicators in an OL to float like drop-caps. it looks like this. as you can see, it works perfectly in chrome and firefox, but of course IE 8 chokes on it– the floats work, but the OL numbers don’t increment. i bet somebody here can work out a fix.

    keys to this method:
    –don’t put anything inside the LI’s. they are empty. all content goes after each closing LI.
    –float the surrounding div, not the LI.
    –the OL must specify decimal inside style.

    .dropli {
    float: left;
    width: .7em;
    font-size: 8em;
    line-height: 83%; }

    .dropcontent { margin-bottom:2em; }

    ol { list-style: decimal inside; }
    ………
    <ol>
    < div class=”dropli”><li ></li></div>< div class=”dropcontent”>orem ipsum dolor sit amet, consectetuer… </div>

  24. Wow! Excellent tutorial. I’ve been looking for something just like this. Lists can be such a bore.

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".