CSS-Tricks PSD to HTML: You Design - We XHTML

Better Ordered Lists (Using Simple PHP and CSS)

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


Theoretically Related Articles:

Discussion Elsewhere


Responses


  1. 1

    Gravatar

    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 } ?>

    Comment by Mirmillo — October 28, 2007 @ 6:34 am

  2. 2

    Gravatar

    Thanks Mirmillo! That is a bit cleaner.


    Comment by Chris Coyier — October 28, 2007 @ 7:52 am

  3. 3

    Gravatar

    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.


    Comment by kimblim — October 28, 2007 @ 11:10 am

  4. 4

    Gravatar

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


    Comment by BillyG — October 28, 2007 @ 11:20 am

  5. 5

    Gravatar

    @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 =).


    Comment by Chris Coyier — October 28, 2007 @ 11:58 am

  6. 6

    Gravatar

    @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.


    Comment by kimblim — October 28, 2007 @ 12:13 pm

  7. 7

    Gravatar

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


    Comment by kimblim — October 28, 2007 @ 12:13 pm

  8. 8

    Gravatar

    @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.


    Comment by Chris Coyier — October 28, 2007 @ 12:30 pm

  9. 9

    Gravatar

    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


    Comment by Jermayn Parker — October 28, 2007 @ 6:48 pm

  10. 10

    Gravatar

    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>
    

    Comment by Dave — October 29, 2007 @ 7:06 am

  11. 11

    Gravatar

    Wow very interesting and in depth. Keep it up! :)


    Comment by hellyeahdude.com — October 31, 2007 @ 10:11 pm

  12. 12

    Gravatar

    How can we change the content of each item?


    Comment by Ian — January 25, 2008 @ 5:47 pm

  13. 13

    Gravatar

    @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…


    Comment by Chris Coyier — January 27, 2008 @ 7:25 pm

  14. 14

    Gravatar

    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.


    Comment by James — January 30, 2008 @ 10:25 am

  15. 15

    Gravatar

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


    Comment by Foxinni - Wordpress Designer — January 30, 2008 @ 11:47 am

  16. 16

    Gravatar

    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.


    Comment by Paul Walker — February 2, 2008 @ 1:35 am

  17. 17

    Gravatar

    “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.


    Comment by John Faulds — February 27, 2008 @ 9:48 pm

  18. 18

    Gravatar

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

    Ralph


    Comment by Ralph — March 7, 2008 @ 7:39 am

  19. 19

    Gravatar

    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’


    Comment by V1 — March 20, 2008 @ 1:29 am

  20. 20

    Gravatar

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


    Comment by Richard — April 7, 2008 @ 9:36 pm


Leave a comment

Sick of typing in all this info everytime you comment? Register or Login and save yourself time!

LINKS: You can use <a href="">LINK</a> tags here.
CODE SAMPLES: Please wrap code samples in BOTH <pre> and <code> tags.

Thank you for visiting CSS-Tricks! I'm glad you found an article useful enough to print out! Remember to visit css-tricks.com often for more fresh content.