This sliding doors CSS hack allows you to create sophisticated tabs for your navigation bar. Sadly, Wordpress core functions wp_list_pages() and wp_list_categories() don’t allow you to add the required span tag to use this technique.

We are going to see how to proceed in order to use sliding doors in our Wordpress theme.

Sliding doors, why?

There’s many articles available on the web about the sliding doors technique, so I’m not going to talk a lot about it. For people who don’t already know this famous hack, here’s a quick example.

Let’s build a typical navigation list:

<ul id="nav">
<li><a href="#">link n°1</a></li>
<li><a href="#">link n°2</a></li>
<li><a href="#">link n°3</a></li>
</ul>

If we apply, via CSS, background images to our links in order to make this menu prettier, we’ll quickly see a big problem: We must add a fixed width to the links, otherwise the image will be truncated if the link is too short, or the link will overflow the image if its width is too long.

That’s why sliding doors are very useful: We just have to add a span element inside the link, and then, in our CSS, assign a different background image to both the span element and the link.

<ul id="nav">
<li><a href="#"><span>link n°1</span></a></li>
<li><a href="#"><span>link n°2</span></a></li>
<li><a href="#"><span>link n°3</span></a></li>
</ul>

Our CSS should look like this:

#nav a, #nav a:visited {
display:block;
}
#nav a:hover, #nav a:active {
background:url(images/tab-right.jpg) no-repeat 100% 1px;
float:left;
}
#nav a span {
float:left;
display:block;
}
#nav a:hover span {
float:left;
display:block;
background: url(images/tab-left.jpg) no-repeat 0 1px;
}

Please note, as this is only an example, the CSS above isn’t complete and only shows how to apply the sliding doors hack.

You can see a live demo of a navigation menu which uses this technique on my blog here.

Wordpress sliding doors

Using the sliding doors hack within Wordpress

I saw many blog posts where some users told you to modify Wordpress core in order to apply this technique. Personally, I never really liked this idea: First, the Wordpress core wasn’t made for being modified. And secondly, if you do, when you’ll upgrade your WP version, you’ll have to re-modify the core. Not user friendly at all!

Instead of this, let’s use a regular expression, by using the php preg_replace() function. We are going to get our pages (or categories) without displaying it, and passing it as a parameter to preg_replace(). The two remaining parameters will be, of course, our regular expression: The pattern we’re looking for, and this pattern’s replacement.

To create this menu, paste the following code instead of the wp_list_pages() (or wp_list_categories()) function in the header.php of your Wordpress theme.

To list your pages:

<ul id="nav">
<li><a href="<?php echo get_option('home'); ?>/"><span>Home</span></a></li>
<?php echo preg_replace('@\<li([^>]*)>\<a([^>]*)>(.*?)\<\/a>@i’, ‘<li$1><a$2><span>$3</span></a>’, wp_list_pages(’echo=0&orderby=name&exlude=181&title_li=&depth=1′)); ?>
</ul>

To list your categories:

<ul id="nav">
<li><a href="<?php echo get_option('home'); ?>/"><span>Home</span></a></li>
<?php echo preg_replace('@\<li([^>]*)>\<a([^>]*)>(.*?)\<\/a>@i’, ‘<li$1><a$2><span>$3</span></a>’, wp_list_categories(’echo=0&orderby=name&exlude=181&title_li=&depth=1′)); ?>
</ul>

Right now, your new menu is ready. You just have to make it sexy with CSS. Have fun! :)

Want automatic updates? Subscribe to our RSS feed or
Get Email Updates sent directly to your inbox!
Digg This | Stumble it | Add to Del.icio.us | | Print This

There Are 72 Responses So Far. »

  1. 1 xero
    Wednesday, July 2nd, 2008 at 2:21 am

    thats it.. thanx.. been figure it out forever..

  2. 2 Jean-Baptiste Jung
    Wednesday, July 2nd, 2008 at 4:19 pm

    You’re welcome :)

  3. 3 Hayes Potter
    Monday, July 7th, 2008 at 12:22 am

    Very nice code I’m impressed Jean-Baptiste.

  4. 4 jbj
    Monday, July 7th, 2008 at 5:04 am

    Thanks a lot, Hayes!

  5. 5 Ben
    Thursday, July 10th, 2008 at 1:54 am

    Sorry, I just get these errors with wordpress 2.5.1:
    “Parse error: parse error, unexpected ‘)’, expecting ‘,’ or ‘;’”

  6. 6 Ben
    Thursday, July 10th, 2008 at 2:03 am

    I got it - just a silly thing: Your (or this blog) wrote “?” instead of “‘”. So now, everything is fine. thanks for your code.

  7. 7 jbj
    Thursday, July 10th, 2008 at 9:15 am

    @Ben: Glad you fixed your problem. Can you tell me where the “?” is? I need to correct that mistake asap so no-one will have this problem again.

  8. 8 Ben
    Thursday, July 10th, 2008 at 1:16 pm

    Sorry, it seems that the blog reformated the character. Some of the ‘ characters are italic for me - I replaced them with the original ‘ and it works for me.

    best regards
    ben

  9. 9 Jean-Baptiste Jung
    Thursday, July 10th, 2008 at 3:44 pm

    Oh, ok. It’s a well known problem.
    As Kyle said in another post, when you copy code from a blog, ALWAYS paste it on a plain text editor (Vi, emacs, Microsoft Notepad, TextEdit…) and then copy the code from the editor.

  10. 10 Ben
    Friday, July 11th, 2008 at 1:49 am

    I work with TYPO3, so I usually do that :) But also in Editor they are different characters (maybe it works this time): ’ (italic) and ‘ (like it should be).

  11. 11 Ben
    Friday, July 11th, 2008 at 1:51 am

    Haha, when I cop now my entry before into the editor, the regular character is wrong also. Maybe also a problem with the font or something like that. But thanks for your help and the good code.

  12. 12 Patrick Sweeney
    Thursday, July 17th, 2008 at 2:53 pm

    Fantastic tutorial! I’ll make sure to blog about this later on.

  13. 13 Jean-Baptiste Jung
    Sunday, July 20th, 2008 at 9:48 am

    Thanks a lot Patrick, I’m glad you liked the tutorial :)

  14. 14 Tl7
    Sunday, July 27th, 2008 at 9:40 am

    Great trick there , thanks alot!

  15. 15 Steve & Irv
    Sunday, July 27th, 2008 at 1:24 pm

    Quick q from a newbie…we’re using Joomla for a site we’re building and want to use the sliding door technique for our front page…

    Does your CSS hack work if we’re not using wordpress?

    Thanks in advance.

    Steve & Irv

  16. 16 jbj
    Monday, July 28th, 2008 at 11:00 am

    For sure, there’s a way to do the same thing in Joomla but I never tried. You should keep the regular expressions, and try if it works once adpted to Joomla.
    I’ll be curious to know, so don’t hesitate to come back here and tell us about your experience!

  17. 17 CSS
    Tuesday, August 12th, 2008 at 12:27 am

    Hi………..
    Oh! nice article. Please visit and enjoyed this article.
    Thank you
    CSS

  18. 18 valerio vaz
    Thursday, September 4th, 2008 at 10:24 am

    Hy, i’m having a problem copying and pasting the code,
    Well i’m not dumb, but the code gives me a parse error when trying to execute the page…

    Can someone email me the code ? valerio.jezus@gmail.com thanks in advance.

  19. 19 Jean-Baptiste Jung
    Tuesday, September 9th, 2008 at 2:54 pm

    @Valerio: I think the problem is the quotes. You should replace them manually, and everything will works :)

  20. 20 Josh
    Wednesday, September 10th, 2008 at 9:33 am

    Thanks for the code! I needed it for both top level and sub nav and modified it a bit. Here’s the code for listing the sub-level page navigation:

    post_parent)
    $children = wp_list_pages(”title_li=&child_of=”.$post->post_parent.”&echo=0″);
    else
    $children = wp_list_pages(”title_li=&child_of=”.$post->ID.”&echo=0″);
    if ($children) { ?>

    <?php echo preg_replace(’@\]*)>\]*)>(.*?)\@i’, ‘$3‘, $children); ?>

  21. 21 Olaf
    Sunday, September 28th, 2008 at 11:29 pm

    I just wanted to thank you for a great tutorial, it really helped me in writing a tutorial on how to implement menus genereted by my site in WordPress, though I must say that I think the WordPress team should have a look at their wp_list_pages function and start allowing people to add custom class names to the ul tag, li tag and a tag and the option to add a span tag inside. Good and good looking navigation is pretty important and if it wasn’t for guys like you, writing these tutorials, most people would have a hell of a time figuring out how to do this.

    Anyway once again, thank you for a great tutorial, you saved me a lot of time and I made sure to make a point of all the credit, for this technique, going this way.

  22. 22 ghprod
    Wednesday, October 22nd, 2008 at 3:15 pm

    So fun with it :)

    So nice .. Thnx

  23. 23 spencerp
    Monday, November 3rd, 2008 at 12:59 pm

    You shouldn’t need this “hack” with the new 2.7 version of WordPress, “we” got them to implement the same parameters as the wp_link_pages link_before / link_after.

    “link_before and link_after for wp_list_pages()”
    http://trac.wordpress.org/changeset/9484
    http://trac.wordpress.org/ticket/8041

    Next should be for categories..
    http://codex.wordpress.org/index.php?title=Template_Tags%2Fwp_link_pages&diff=62692&oldid=46067

  24. 24 jbj
    Monday, November 3rd, 2008 at 5:40 pm

    @spencerp: Good to know! But this hack was very useful to me until WP 2.7.

  25. 25 Marty
    Sunday, November 23rd, 2008 at 3:27 pm

    just what the doctor ordered…

    thumbs up :)

  26. 26 Phil
    Thursday, December 4th, 2008 at 12:41 pm

    This steers me in the direction I was seeking - thank you. However, I’d like to swap the background image for the currently selected page using CSS. If it’s possible, where in the code might I insert a class=”current” id?

  27. 27 zach
    Thursday, December 11th, 2008 at 3:43 pm

    I about cried when I saw this post, since I have been trying to figure this out for days. Very excited.

    Then I put the code in after copying it from another text editor to remove syntax error, and I get the following:
    Warning: Unexpected character in input: ”’ (ASCII=39) state=1 in /home/zacharyr/public_html/sandbox/wp-content/themes/clean-copy-right-sidebar-1/header.php on line 34

    Warning: Unexpected character in input: ‘\’ (ASCII=92) state=1 in /home/zacharyr/public_html/sandbox/wp-content/themes/clean-copy-right-sidebar-1/header.php on line 34

    Parse error: syntax error, unexpected ‘<’ in /home/zacharyr/public_html/sandbox/wp-content/themes/clean-copy-right-sidebar-1/header.php on line 34

    I know you are busy but any help would be greatly appreciated.

  28. 28 zach
    Thursday, December 11th, 2008 at 3:46 pm

    I previously posted about this wasn’t working, but that is because of the syntax with the ‘ and ” so future people please watch out.

    If there is a God, I hope he (or she) sends you directly into heaven and hands over your 40 virgins for this WP hack.

  29. 29 Jean-Baptiste Jung
    Thursday, December 11th, 2008 at 4:33 pm

    @zach: It’s due to the curly quotes. Just manually replace it and you’re done!
    Read more about it here.

  30. 30 sunil
    Sunday, January 25th, 2009 at 2:49 pm

    I need vertical css menu

  31. 31 Karl
    Friday, February 20th, 2009 at 12:22 pm

    Thanks! Just what I needed.

  32. 32 Chris
    Friday, March 27th, 2009 at 10:24 pm

    Question:

    If we are using the A List Apart CSS Sliding doors technique, they use an id=”current” in the li tag to create the active tab. How can I make it so that you code will append the id=”current” to the li tag of the active category?

    Thanks for the help, this is a great tutorial!

  33. 33 Matt Sweet
    Wednesday, May 13th, 2009 at 6:38 pm

    Thankyou! I nearly cried when I saw this. I have been looking for a way to add spans for ages!

  34. 34 Ben
    Sunday, May 31st, 2009 at 5:56 pm

    Since Wordpress 2.7 you don’t need to do this anymore, use wp_list_pages parametes link_before and link_after:

    wp_list_pages(
    array(
    ‘link_before’=>”,
    ‘link_after’=>”
    )
    );

    (need wordpress 2.7+)

    it’s in the docs here:

    http://codex.wordpress.org/Template_Tags/wp_list_pages

  35. 35 Chad
    Friday, June 26th, 2009 at 5:44 pm

    OMG! If ever there was a true WordPress God, it is you! Thank you soooo much for this. Now I knew there was something silly going on, but I just couldn’t figure it out. I have been trying to wrap my brain around this problem for the last 4 hours. Suddenly I find this post and realized the solution was at my finger tips the entire time. I am running version 2.8 so this hack is not necessary anymore, but it led me to the place on the WordPress site which told me how to do it with version 2.8 http://codex.wordpress.org/Template_Tags/wp_list_pages

    <?php wp_list_pages(’orderby=name&exlude=2&title_li=&depth=1&link_before=&link_after=’); ?>

    Thanks again guys!

Trackbacks/Pingbacks


Leave A Comment