Guide to Styling the WP-PageNavi WordPress Plugin

If you’re not familiar with the WP-PageNavi WordPress plugin, it allows you to replace normal previous/next navigation with a more advanced, numbered paging navigation.

wp page navi

In this tutorial, we’re going to go over how to:

  • Install WP-PageNavi and properly integrate it in your theme.
  • Two methods to disable and/or override default plugin styles.
  • An overview of the HTML markup output by WP-PageNavi
  • Finally, how to alter the look of your page navigation through CSS

Install the Plugin

You have two options when it comes to installing the WP-PageNavi plugin.

  • Download it from WordPress.org, upload it to your /wp-content/plugins/ directory, and activate (aka, the old fashioned way).
  • Depending on your host, you can also automatically install plugins by searching them in “Add New” page under Plugins in your WordPress admin panel. Just search for “pagenavi” and you should find it.

Okay, that should’ve been pretty easy. Now it’s time to get your hands a little dirty in code for the integration part.

Theme Integration

In our theme integration, we never want any errors to be displayed if the WP-PageNavi isn’t active. Instead, we’ll make sure it falls back on the old previous/next-style navigation. To do this, we’ll use a function_exists conditional check.

Let’s say this is your normal previous/next WordPress navigation code:

<div class="navigation">
	<div class="alignleft"><?php next_posts_link('&laquo; Older Entries') ?></div>
	<div class="alignright"><?php previous_posts_link('Newer Entries &raquo;') ?></div>

We will change it to the following:

<?php if (function_exists('wp-pagenavi')) { wp_pagenavi(); } else { ?><div class="navigation">
	<div class="alignleft"><?php next_posts_link('&laquo; Older Entries') ?></div>
	<div class="alignright"><?php previous_posts_link('Newer Entries &raquo;') ?></div>
</div><?php } ?>

This basically checks to see if WP-PageNavi is active and if it is, it displays the new page navigation code. If not, it gracefully falls back to the normal previous/next navigation.

Please Note: Depending on how your CSS is coded, you may want to put the wp_pagenavi(); part inside the “navigation” (or equivalent) div. Keep in mind WP-PageNavi spits out a new class called “wp-pagenavi” though which we can use to style separately.

Override Plugin Styles

By default, WP-PageNavi automatically inserts a CSS file called pagenavi-css.css from its plugin directory into the header of your site. We don’t want these default styles to interfere with our own cool custom-made styles, so we’ll completely get rid of them, and there are two simple ways to do just that.

  • Add a CSS file to your theme directory – This is probably the easiest way to override the default WP-PageNavi styles. If you have a file called pagenavi-css.css in your theme directory, WP-PageNavi will use this instead of the default one in the plugin directory.
  • Add a snippet to your functions.php file – The following code snippet we picked up from WP Recipes will completely disable the above behavior and not include any stylesheet from the plugin (either the default one or an override in your theme directory).
add_action( 'wp_print_styles', 'my_deregister_styles', 100 );

function my_deregister_styles() {
	wp_deregister_style( 'wp-pagenavi' );

Just plop that code in your theme’s functions.php file and add the CSS styles to your regular theme’s stylesheet (usually style.css).

Note: Make sure the code is surrounded by brackets like <?php ... ?> if your functions file is currently empty.

WP-PageNavi HTML Markup and CSS Selectors

Here’s what the WP-PageNavi markup looks like. In the following example, there are four pages, currently on page two.

<div class="wp-pagenavi">
	<a href="http://example.com/" >Previous</a><a href="http://example.com/" class="page" title="1">1</a>
	<span class="current">2</span>
	<a href="http://example.com/?paged=3" class="page" title="3">3</a>
	<a href="http://example.com/?paged=3" >Next</a></div>
	<span class="extend">...</span>
	<a href="http://example.com/?paged=4" class="last" title="Last &raquo;">Last &raquo;</a>

We can use the following CSS selectors to target the above HTML markup:

  • .wp-pagenavi – Applies to the entire div, useful for CSS clears, padding/margin, font sizes and styles (bold, italic, etc.)
  • .wp-pagenavi a – Targets all links inside the page navigation, including page numbers and previous/next.
  • .wp-pagenavi a.page – Targets page numbers specifically
  • .wp-pagenavi a.first – Targets the “first” link specifically (not listed above)
  • .wp-pagenavi a.last – Targets the “last” link specifically
  • .wp-pagenavi span – Targets the current page number along with the extend part (the thing with three dots)
  • .wp-pagenavi span.current – Specifically targets the current page number
  • .wp-pagenavi span.extend – Specifically targets the extend (three dots thing)
  • .wp-pagenavi span.pages – Specifically targets page number display (i.e. Page 1 of 4)

Note: The previous and next links by default, have no CSS class on them. If you want them to completely differentiated from the page numbers and first/last links, those will need to reset any styles added to the .wp-pagenavi a selector. If that made no sense, take a look at the following (really simplified) example.

For example: Let’s say you wanted the previous and next links to be bold, but every other link to have a normal weight. You would need to do the following:

.wp-pagenavi a { font-weight: bold; } /* Previous and Next links only */
.wp-pagenavi a.page,
.wp-pagenavi a.first,
.wp-pagenavi a.last { font-weight: normal; } /* Other links */

I combined page number links, the first link, and the last link into one rule for example purposes. Of course, you can separate them and add more specific styles to each one.

This would be much easier if there was a class added to previous/next links by default, but there’s not. It’s not a huge deal as you can just reset them anyway.

You can use .wp-pagenavi a.previouspostslink and .wp-pagenavi a.nextpostslink to select previous and next links, respectively.

So pretty much everything above up until the unordered list of selectors isn’t relevant anymore, but we’ll keep it just because it could be a useful lesson in overriding CSS in some other situations. The below CSS example will still apply as we didn’t use those selectors anyway.

A CSS Example

Here’s an example of a PageNavi styling we built:

Blogwave Updated PageNavi

Here’s the code we used to get this look, multi-single-line CSS is optional:

.wp-pagenavi a, .wp-pagenavi span {
	padding: 5px; margin-right: 10px;
	font-size: 15px; color: #03719c; text-decoration: none;
	border: 3px solid #ccc; -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px;
.wp-pagenavi a:hover, .wp-pagenavi span.current {
	background: #03719c;
	color: #fff;
	border: 3px solid #AFAFAF;
.wp-pagenavi span.current { font-weight: bold; }

And here’s what it all means:

First Rule
The .wp-pagenavi a, .wp-pagenavi span selects all anchor and span elements (pretty much everything) inside the .wp-pagenavi div.

  • The first line of the rule sets a padding of 5px so it won’t be crammed up against the light gray border (defined below). It also sets a consistent margin of 10px to the right of each element so there is equal spacing between each.
  • The second line sets a font size of 15px, makes the text color blue, and makes sure links have no underline.
  • The third line sets a solid 3px gray border on everything. The border-radius code makes the corners rounded.

Second Rule
The .wp-pagenavi a:hover, .wp-pagenavi span.current selects the link hover effect as well as the current page number, respectively.

  • The first line sets a dark blue background color.
  • The second line makes the text white.
  • The third line gives a slightly darker border.

Third Rule
This selects the current page number (again) without affecting the link hover effect as well (like the second rule). This just makes the current page number a bold font weight.

The reason we didn’t include it with the link hover effect is that it has an uneven effect going from normal to bold font weight.

Note: Depending on how your CSS is coded, you may have to use more specific selectors. For example, if there are styles for #content a and your WP-PageNavi is inside the content div, you may have to rewrite your PageNavi CSS as #content .wp-pagenavi a and override any other less-specific styles.


We know this was a relatively simple example, you could have a lot more advanced CSS rules to differentiate the various links and other elements even more. Hopefully, you picked up a few CSS tips along the way too.

Optional WP-PageNavi integration is a pretty cool feature theme developers could integrate into their themes. With the integration method we outlined above, users could easily choose whether or not to use it, and it could be a nice option for a lot of blogs.

You may want to see our guides and tutorials:

These posts will help you find more solutions you may be looking for.

Comments   Leave a Reply

  1. i have neve theme and i copy the css of plugin to my stylesheet and code into function still it is not working…..

    1. Are you copying the CSS into a stylesheet or a function?

  2. Does anyone know how to change the page #? I have been trying at this for weeks and my website is due to my boss ASAP!

    For example, right now it’s:
    1,2,3,4,5,.. etc..

    I want it to look like this:
    Appetizers, Salads, Pasta, Pizza, etc…

    If this isn’t possible does anyone else have any good ideas?

  3. Here is another way to styling WP-PageNavi with CSS and a javascript ‘fade’ effect :

  4. The css is not working on mine: http://lrastart.org/

    It keeps reverting back to the original css.

    1. Make sure to check over the “Override Plugin Styles” portion of the tutorial.

  5. There are some nice styles here 😉 Great page navi guide.

  6. I think function_exists(‘wp-pagenavi’) is not working, it should be ‘wp_pagenavi’.

    Thx for the tutorial!

  7. Just to let you know that you used .first and .last instead of :first and :last (the first two won’t work).

    Excellent tutorial tho 🙂

    1. I think you’re referring to pseudoclasses like :first-child and :last-child but you wouldn’t need to use those anyway since “first” and “last” classes are automatically output in the plugin.

      There is more information on CSS pseudo selectors and browser compatibility on this page: http://kimblim.dk/css-tests/selectors/

  8. It still irks me that this plugin doesn’t use an ordered list for the markup. I went for WP Page Numbers in the end. Good tutorial though, thanks.

    1. Hey Karl, thanks for letting me know about that plugin, never used it before. Looks almost the same but with list markup and more CSS classes.

      Also has a few built-in “themes” which is pretty cool.

  9. Great tutorial!

    Just one thing: the previous and next links do have CSS classes on them: ‘previouspostslink’ and ‘nextpostslink’.

    1. Hey scribu, I thought I was going insane for a sec as I hadn’t seen that before, but it appears you’re right.

      I googled “nextpostslink” and came across this post: http://yoast.com/pagination-classes/ which Lester Chan (original author of the WP-PageNavi plugin, in case anyone didn’t know) commented saying he added the previous/next classes to the core plugin code.

      Turns out I was using an outdated version of the plugin that didn’t have classes on the previous/next links yet, hence I was using that workaround. I’ll update the post accordingly.

  10. Hello,

    At the moment it pagenavi shows 10 posts per page – how do I change it to 5?


    1. Don’t think that has to do with pagenavi, you need to adjust that in your reading settings.

    2. Oh of course! thanks

  11. Jean-Baptiste Jung May 8, 2010 at 3:39 am

    Thanks for the useful guide! I’ll definitely use it when developing my themes.

    1. Thanks Jean-Baptiste, it is a cool feature to implement in themes, especially in released ones.

      A lot of users prefer to have this sort of navigation and it’s useful if the integration and CSS styles are already in place within the theme, all they have to do is install the plugin.

  12. Awesome! I’m bookmarking this tutorial because I’m sure its gonna come in handy one of these days. Good job Leland! 😀

    1. Thanks a lot Jaypee, appreciate it!

Add a Comment

We're glad you have chosen to leave a comment. Please keep in mind that all comments are moderated according to our privacy policy, and all links are nofollow. Do NOT use keywords in the name field. Let's have a personal and meaningful conversation.

WordPress Launch Checklist

The Ultimate WordPress Launch Checklist

We've compiled all the essential checklist items for your next WordPress website launch into one handy ebook.
Yes, Send Me the Free eBook!