Flexible Adjacent Entry Navigation for Single Posts in WordPress

Have you ever wanted to include adjacent entry navigation links (links to your previous or next posts) at the end of your current post? I confess, it’s not something I’ve usually done on my sites, but consider how nice it might be to have a link at the bottom of your post to one or two posts–not necessarily related to the current post, but at least near in time. I have seen this on quite a few sites which focus strongly on blogging regularly.

Did you know that the Genesis Framework (affiliate link) has a built in way of doing this? All you have to do is add support for it to your post type. For example, for posts, I could just add this to my theme:

add_post_type_support( 'post', 'genesis-adjacent-entry-nav' );

Genesis will take care of the rest. Alternatively, you can use a helper function provided by Genesis, which does just what I’ve shown above:

add_action( 'genesis_after_entry_content', 'genesis_prev_next_post_nav', 5 );

One implementation of it which I consider to be quite lovely is in Cook’d Pro (visit the demo and navigate to a singular post):

Cook'd Pro adjacent entry navigation

Another implementation of this kind of navigation that I like just uses arrows, although when I look at the source code, my guess is that they’ve written their own function instead of using the Genesis option (image intentionally blurred):

Adjacent Entry Navigation with Arrows

Potential Issues with Current Options

As I dug into the Genesis function and the simple arrow implementation both, I came up with some potential issues that concerned me:

Mobile Devices

if you go with the arrow based adjacent entry navigation, what happens on mobile devices/small screens where there isn’t room for them? The second example simply hides the links altogether, which works, but it would be nice to keep them if I can.


Based on what I know (not an expert), the accessibility of the adjacent entry navigation links seems a bit problematic. The Genesis function simply adds the links, but I’m concerned that there is no context to them, which I’m thinking could be confusing for some users. It feels similar to the “Read More” text on archives, which Genesis has resolved by appending “about {Title of Post}”, visually hidden, but available for screen reader users.

And the simple arrow option I found actually doesn’t include the title, just the link, which means that the links have no discernible text–definitely problematic.

Let’s Create a More Flexible Adjacent Entry Navigation

Note: this tutorial requires the Genesis Framework. Additionally, if you implement this, please practice safe coding and back up your website before you do anything else.

Well, I want to use this adjacent entry navigation, but I’d also like for it to be accessible. And, ideally, I’d like to have the flexibility to tweak how the navigation is displayed, because I do like those arrows. Let me show you my code and then I’ll describe the high points:

add_action( 'genesis_after_entry', 'leaven_adjacent_entry_nav' ); /** * Display links to previous and next entry. * * @return void Return early if not singular post. */ function leaven_adjacent_entry_nav() { if ( ! is_singular( 'post' ) ) { return; } genesis_markup( array( 'open' => '<div %s>', 'context' => 'adjacent-entry-pagination', ) ); echo '<div class="pagination-previous">'; echo '<span class="screen-reader-text">' . esc_attr__( 'Previous Post:', 'leaven' ) . ' </span>'; previous_post_link( '%link', '<span class="adjacent-link">%title</span>' ); echo '</div>'; echo '<div class="pagination-next">'; echo '<span class="screen-reader-text">' . esc_attr__( 'Next Post:', 'leaven' ) . ' </span>'; next_post_link( '%link', '<span class="adjacent-link">%title</span>' ); echo '</div>'; genesis_markup( array( 'close' => '</div>', 'context' => 'adjacent-entry-pagination', ) ); }
Code language: PHP (php)

I opted not to use the Genesis functions at all, because I wanted to add some new markup, and, as it turned out, I needed to modify how some of the underlying WordPress functions are used as well. So this leaven_adjacent_entry_nav function is a rewrite of the genesis_adjacent_entry_nav (you can find it in genesis/lib/structure/post.php).

My first task was to add context, similar to how Genesis handles the “Read More” links (when accessibility support is enabled). All I did here was add two spans: one at line 23 (“Previous Post: “) and the other at line 28 (“Next Post: “). Both spans have a class of screen-reader-text, so they are visually hidden.

The other part was a bit trickier, because I wanted to give myself the ability to use the simple arrow navigation on large screens, but not lose the adjacent entry navigation on small screens. The issue here is that the link needs to remain visible at all times, but I want to hide the title (visually) on large screens. It took me some figuring, but I finally realized that I could manage this in the WordPress functions for the previous/next post links, on lines 24 and 29:

previous_post_link( '%link', '<span class="adjacent-link">%title</span>' );

The first parameter of this function is the format for the URL. I just want this to be the URL and nothing else, no text arrows or anything. The second parameter is the one I’m currently really concerned with. %title is the default value for this placeholder–all I’m doing is wrapping the title in a new span element with a custom class, so I can style it (or not).

Styling the Adjacent Entry Navigation

At this point, you could add this to your theme and call yourself done–you’ll have functional adjacent entry navigation links. Styling for these will vary from one Genesis child theme to the next, probably based on whether the theme adds support for the feature or not. Since I wanted to make my navigation change significantly based on the screen size, I definitely needed to do some styling work. Here’s what I’m using:

.adjacent-entry-pagination .pagination-previous a:before { display: inline-block; font: normal normal normal 18px FontAwesome; text-rendering: auto; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-transform: translate(0, 0); -ms-transform: translate(0, 0); transform: translate(0, 0); vertical-align: middle; content: '\f104'; margin-right: 12px; } .adjacent-entry-pagination .pagination-next a:after { display: inline-block; font: normal normal normal 18px FontAwesome; text-rendering: auto; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-transform: translate(0, 0); -ms-transform: translate(0, 0); transform: translate(0, 0); vertical-align: middle; content: '\f105'; margin-left: 12px; } @media only screen and (min-width: 30em) { .adjacent-entry-pagination { margin-bottom: 0; } .adjacent-entry-pagination .pagination-previous, .adjacent-entry-pagination .pagination-next { position: fixed; top: 50%; } .adjacent-entry-pagination .pagination-previous a, .adjacent-entry-pagination .pagination-next a { color: #d3dad3; } .adjacent-entry-pagination .adjacent-link { position: absolute !important; clip: rect(1px, 1px, 1px, 1px); height: 1px; width: 1px; border: 0; overflow: hidden; } .adjacent-entry-pagination .pagination-previous { left: 24px; } .adjacent-entry-pagination .pagination-previous a:before { font-size: 48px; } .adjacent-entry-pagination .pagination-next { right: 24px; } .adjacent-entry-pagination .pagination-next a:after { font-size: 48px; } } @media only screen and (min-width: 60em) { .adjacent-entry-pagination .pagination-previous { left: 8%; } .adjacent-entry-pagination .pagination-next { right: 8%; } }
Code language: CSS (css)
  • Note: my theme is mobile first, so the media queries start with small screens and go up.
  • I use Font Awesome for my theme icons, so that’s what’s here for the :before and :after pseudo elements. You could use Dashicons, if you prefer, or implement Font Awesome as spans, which is how they usually recommend handling them, in which case you wouldn’t style the pseudo elements at all.
  • Once I am in the larger screen media queries, I hide the post title using the same styling I use for screen-reader-text.
  • The bulk of the CSS there just deals with changing the font size and positioning of the arrows, or pseudo elements, when I’m on a larger screen. I should note that in my use case, all posts will be displayed without a sidebar, so there will be lots of white space on each side of the post content.

I’d love to show you the results of this in action, but the project is still in development, so I can’t even really show you screenshots. I’ll update this post with a link when the site is live.

So, is this a more accessible adjacent entry navigation? I think so, in that I’ve added context to the links, although my understanding is that fixed position elements can be problematic, so the styling may be a step backwards. And I’ve accomplished my goal of making the navigation totally flexible, and display quite differently based on screen size.

Reader Interactions


  1. Matt says

    Hey Robin,

    Great article, I can’t wait to try it out. Is the site still in development or can we see a link to the live script in action?

    I’d love to add this to my site as a way to reduce my high bounce rate but I’d like to see some demos of it or hear how it’s worked for others.

    Thanks again for this piece!

    • Robin says

      Hey Matt! Yes, you can see the adjacent entry navigation on the final site here.

      I’ve actually just updated my own site to use an updated version of the adjacent entry navigation, using SVG icons instead of CSS pseudo elements. I don’t know how it affects bounce rates, as it’s so new, but figure it’s nice to have regardless.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.