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>

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>

Our CSS should look like this:

#nav a, #nav a:visited {
#nav a:hover, #nav a:active {
background:url(images/tab-right.jpg) no-repeat 100% 1px;
#nav a span {
#nav a:hover span {
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.

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&exclude=181&title_li=&depth=1')); ?>

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&exclude=181&title_li=&depth=1')); ?>

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

Kyle Eslick is WordPress enthusiast who took his passion for WordPress to the next level in 2007 by launching as a place to share hacks, tutorials, etc. Follow Kyle on Twitter @KyleEslick!

  1. xero says:

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

  2. You’re welcome 🙂

  3. Hayes Potter says:

    Very nice code I’m impressed Jean-Baptiste.

  4. jbj says:

    Thanks a lot, Hayes!

  5. Ben says:

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

  6. Ben says:

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

  7. jbj says:

    @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. Ben says:

    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

  9. 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. Ben says:

    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. Ben says:

    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. Patrick Sweeney says:

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

  13. Thanks a lot Patrick, I’m glad you liked the tutorial 🙂

  14. Tl7 says:

    Great trick there , thanks alot!

  15. Steve & Irv says:

    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. jbj says:

    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. CSS says:

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

  18. valerio vaz says:

    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 ? thanks in advance.

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

  20. Josh says:

    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:

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

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

  21. Olaf says:

    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. ghprod says:

    So fun with it 🙂

    So nice .. Thnx

  23. spencerp says:

    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()”

    Next should be for categories..

  24. jbj says:

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

  25. Marty says:

    just what the doctor ordered…

    thumbs up 🙂

  26. Phil says:

    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. zach says:

    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. zach says:

    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. @zach: It’s due to the curly quotes. Just manually replace it and you’re done!
    Read more about it here.

  30. sunil says:

    I need vertical css menu

  31. Karl says:

    Thanks! Just what I needed.

  32. Chris says:


    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. Matt Sweet says:

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

  34. Ben says:

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


    (need wordpress 2.7+)

    it’s in the docs here:

  35. Chad says:

    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

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

    Thanks again guys!

  36. leslie says:

    Just one question. I have this code in a wordpress theme. Now, if I want to exclude certain pages to show up, how do I do that?


  37. Debbie Campbell says:

    Oh my God – I too cried when I found this. Thank you so much.

  38. Debbie Campbell says:

    What an incredibly useful article!

    I wound up using it like this in header.php and it worked perfectly with wp_page_menu:

    <?php echo preg_replace('@]*)>]*)>(.*?)@i’, ‘$3‘, wp_page_menu(‘echo=0&orderby=name&exlude=181&title_li=&depth=1’)); ?>

  39. Muadib says:

    I also wanted to get the current tab portion to work so that the currently open tab is highlighted. I did this by adding an additional replace for the list item (li) containing whatever was in the current $post->post_title.

    This worked but broke when I used redirectors for parent pages (this is where you click on the parent and get redirected to one of its children pages, it’s helpful when you just want to categorize topics but not really talk about the categories themselves). To get around that, I check first to see if the current post has a parent(this works because I only have two layers, if you have more, I guess you’d need to add more checks but I can see where that could get messy).

    If you’re not using redirection, just look at the snippet after the “else” statement.

    if($post->post_parent) {
    $parent = get_post($post->post_parent);
    // Form menu items
    $menu_li = preg_replace(‘@]*)>]*)>(.*?)@i’, ‘$3‘, wp_list_pages(‘echo=0&orderby=name&exlude=181&title_li=&depth=1′));
    // Find and replace selected tab list item%0pan>’.$parent->post_title.'(.*)D
    echo preg_replace(‘@<li(.*)<s@i’, ‘<li id="current"$1’.$parent->post_title.’$3‘, $menu_li);

    // Form menu items
    $menu_li = preg_replace(‘@]*)>]*)>(.*?)@i’, ‘$3‘, wp_list_pages(‘echo=0&orderby=name&exlude=181&title_li=&depth=1’));

    // Find and replace selected tab item
    echo preg_replace(‘@<li(.*)’.$post->post_title.'(.*)@i’, ‘<li id="current"$1’.$post->post_title.’$3‘, $menu_li);

  40. Matt Rittman says:

    I have a question about this. What if I want to make it so whatever page you’re on, the button in the navigation bar has a different color to let you know you’re on that specific page? Is this possible with this hack?

  41. hasfa says:

    Thanks for the nice and useful code

  42. Muadib says:

    I was playing around today with the loopy replacement fix above and happened upon this page:

    “All list items (li) generated by wp_list_pages() are marked with the class page_item. When wp_list_pages() is called while displaying a Page, the list item for that Page is given the additional class current_page_item. ”

    so basically instead of replacing any output coming from wp_list_pages, you can just create a CSS class to handle class_page_item and your buttons will be just as good! Even better, you won’t waste any precious processing on replacements!

  43. pomah blog says:

    thanks for this very useful code, i will try to use it to my blog

  44. Tati says:

    Hello Everyone,
    I love this tutorial! However, I have not idea how to add this to my blog. I want this specific hack. People are saying its different for wp 2.8 and above. Also that codex link is something I don’t understand. Can someone guide me so I can add it to my wp site. I wanted two navigation bars so this is perfect! Can someone just post the code or something on how to do implement it? Please let me know.

    Thank You

  45. WhiteSphynX says:

    Can someone please post a link to this hack or codex implemented so we can see it in action?
    Thx much!
    Also no one commented on sunil’s post about a possible way to do this vertically. Any thoughts?
    Thx Again!

  46. veteriner says:

    thanks for info good sharing
    To get around that, I check first to see if the current post has a parent(this works because I only have two layers, if you have more, I guess you’d need to add more checks but I can see where that could get messy

  47. card admin says:

    i am card blog admin.

    i tried using this exactly same. I want to highlight active category item similar to Current_page_item. How to do it along with this span code added category list?


  48. Ted says:

    WOW !!! SUPERB work man!!! great!

  49. Monica Pitts says:

    Thank you for this article. I have used it a few times and it works very well! For the first time I was using the exclude feature for the menu and it was not working. Upon staring at the word exclude for a while I realized that it was misspelled. No biggie. Just needed to add a “c”. Just wanted to let you know and thanks again!

  50. Abhijit V. Chaore says:

    Awesome! I was wondering how to modify the WordPress code in order to get sliding doors effect. But the code you provided worked for me. Thanks.

  51. Waylon says:

    I have been trying to use the sliding doors technique with dropdown menus. Any tips or insight on using this technique for Parent links and being able to style the child links with their own look? In other words keeping the two visually different?

  52. Shanna says:

    Very, very nice…you rock! Thank you.

  53. Geert van der Heide says:

    Nice! Thankzzzz!

  54. evan says:

    perfect tutorial! tutorial as I need … thank you:) that’s work for me!

  55. Pavlo says:

    Wow, nice work… I was really looking for a wordpress code like this one. You helped me a lot and all the comments helped me as well. Did first the error with the “ as well. Thanks for the great support you offer as well. Great work!

  56. Mack says:

    Excellent piece of code, shall use it!

  57. ken says:

    I tried so many stupid plugins to get my menu bar right for the idris theme .
    Just pasted the code “To list your categories:” in header.php under

    It works like a charm . Hope this helps for idris users.

  58. dave says:

    If you are just using a page menu….
    $pages = get_pages();
    $currpage = get_the_ID();
    foreach ( $pages as $pagg ) {
    $link = get_page_link( $pagg->ID );
    $pname = $pagg->post_title;

    if ($pagg->ID==$currpage){
    $cssclass = “selected”;
    $spanClass = “on”;
    } else {
    $spanClass =””;
    <a href="” class=”” title=””><span class="”>

  59. mark r says:

    usefull article…
    thank you, Jean.

  60. nesla says:

    thank u jean..Good article.

  61. Diana Ratliff says:

    Appreciate the specific instructions and the example.

Trackbacks/Pingbacks »

  1. CSS Techniques: Using Sliding Doors with Wordpress Navigation | CSS-FAQ says:
  2. 10 tutos pour créer de sublimes boutons en CSS says:
  3. Top 10 CSS buttons tutorial list says:
  4. xeRo.Tumble says:
  5. CSS Techniques: Using Sliding Doors with Wordpress Navigation | blackleafmedia says:
  6. WP Limits » Blog Archive » Navigation Tips: Suckerfish, Sliding Doors, and Breadcrumbs says:
  7. links for 2008-09-17 | orioa says:
  8. WP?????-2.3: WordPress??????? | ???? says:
  9. WordPress Developer’s Toolbox | rafdesign says:
  10. Joshua London » Blog Archive » Sliding Doors (kinda) for WordPress says:
  11. How to: Use the CSS Sliding doors technique within WordPress says:
  12. 10 Killer WordPress Hacks « ArticleSave says:
  13. 10 Killer WordPress Hacks | How2Pc says:
  14. 10 Killer WordPress Hacks | Web Hosting and Domains says:
  15. Mellowish » Blog Archive » 10 Cool WordPress Hacks says:
  16. KurtQian’s blog - 10 Killer WordPress Hacks says:
  17. Top 50 Wordpress Tutorials - NETTUTS says:
  18. Top 50 Wordpress Tutorials says:
  19. 10????WordPress?? : ???????… says:
  20. 100+ Massive CSS Toolbox | tripwire magazine says:
  21. Top 50 WordPress Tutorials | The PhenixbluE says:
  22. 10 Killer WordPress Hacks | Bookmarks says:
  23. Top 50 Wordpress Tutorials | Design-Tut+ says:
  24. Breezy’s Wordpress » Blog Archive » Daily Digest for May 16th says:
  25. 22 CSS Button Styling Tutorials and Techniques : Speckyboy Design Magazine says:
  26. Top 50 Wordpress Tutorials says:
  27. More Tab Menu Hacks says:
  28. 30+ Useful WordPress Tutorials says:
  29. Techflaps | 15 Tutorials on Creating CSS Navigaton Menus with Sliding Doors Effect says:
  30. Top 5 Tutoriais Menú de Navegación para WordPress | Ajuda Wordpress em Português says:
  31. Top 50 Wordpress Tutorials « The Interweb of TJ says:
  32. Using CSS Sliding Doors in WordPress Navigaton says:
  33. 22 tutoriels pour boutons CSS | WebCssDesign says:
  34. 30+ Useful WordPress Tutorials | The Apple Tech Blog says:
  35. Top 50 Wordpress Tutorials from TutPlus | WordPress News Magazine says:
  36. top 50 tutorials of wordpress(must use) | Umraz Ahmed | the official site says:
  37. Top 50 Wordpress Tutorials | NetExUrl | Web Development Tutorials & Design Resources says:
  38. 40+ CSS Based Navigation Tutorials Web Design Blog says:
  39. |??????| 50???WordPress?? : Welcome to says:
  40. WordPress – Snipers » Blog Archive » 40+ CSS Based Navigation Tutorials says:
  41. 15??????CSS???????? - IETester says:
  42. 185+ Very Useful and Categorized CSS Tools, Tutorials, Cheat Sheets « qeqnes | Designing. jQuery, Ajax, PHP, MySQL and Templates says:
  43. Designing A Perfect Navigation Menu Bar : Blog Design Series Part 3 | Creative Blogging Ideas says:
  44. 10 Adet Mükemmel CSS Menü Dersi | Sorbize says:
  45. 10 Adet Mükemmel CSS Menü Dersi « Web Önerilerimiz says:
  46. Geek is a Lift-Style. »Archive » 10 Killer WordPress Hacks says:
  47. 30 Excellent CSS Based Navigation and Buttons Tutorial | Dzinebook blog | Inspirational design resource for Web design - development - freelancer tips says:
  48. Top 50 WordPress Tutorials « Santosh Kori's Blog says:
  49. Top Collection Of WordPress Tutorials On The Web | Nerdy Geeks Blogging Guide says:
  50. Top Collection Of WordPress Tutorials On The Web | Nerdy Geeks says:
  51. 20 Excellent CSS Menu And Button Tutorials | VaneGraphics says:
  52. 22 CSS Button Styling Tutorials and Techniques says:
  53. 40 Useful layout by CSS Tutorials including Techniques And Resources « 68Design – ( Creative Design Transmitter says:
  54. 30 Excellent Tutoriel de Navigation CSS et boutons | says:
  55. 60+ Awesome WordPress Tutorials | says:
  56. Writing WordPress Guides For The Advanced Beginner - Smashing WordPress says:
  57. Writing WordPress Guides For The Advanced Beginner | Body Mind and Mood says:
  58. Writing WordPress Guides For The Advanced Beginner | TunerLabs Blog says:
  59. Bangladesh Web Lab | Bangladeshi Web Designer and Developer Blogs – Top 50 WordPress Tutorial says:
  60. Writing WordPress Guides For The Advanced Beginner | dot Key Plugins says:
  61. 30 Excellent CSS Based Navigation and Buttons Tutorial says:
  62. 100+ Resources for WordPress Theme Developers - | Web Help 101 says:
  63. Writing WordPress Guides For The Advanced Beginner |Layout to HTML says:

Tweetbacks »