Instead of navigating down a page by scrolling and then clicking a link to get to the next page, waiting for a page refresh, infinite scrolling pulls the next set of posts automatically into view when the reader approaches the bottom of the page, more like an application.
Unlike many of the modules already in Jetpack, Infinite Scroll only works with themes that support it. Since each theme is constructed a bit differently, the Infinite Scroll module needs information about the theme to function properly. Read on for detailed instructions on adding support to your theme and using CSS to customize the look.
Adding Support
Enabling Infinite Scroll is very similar to adding support for post thumbnails or editor styles because we make use of add_theme_support()
. By providing a few key pieces of information when calling add_theme_support()
, Infinite Scroll will seamlessly integrate with your theme.
If you have a well crafted theme, like WordPress default themes, adding Infinite Scroll is a breeze. Here is how it's done for Twenty Twelve:
add_theme_support( 'infinite-scroll', array(<br /><%%KEEPWHITESPACE%%> 'container' =&gt; 'content',<br /><%%KEEPWHITESPACE%%> 'footer' =&gt; 'page',<br />) );
With that you get a fully functioning infinite scroll experience.
container
The container
parameter is the core of adding infinite scroll to your theme, it specifies the ID of the HTML element to which Infinite Scroll should add additional posts to. The default value is content
, but can be any valid CSS ID that appears in the supported theme and is appropriate for appending posts to. Usually, this'll be the parent container of the posts in your theme.
footer
One of the issues with infinite scroll is that you can't access the footer of a page since whenever you approach the end, new posts are loaded. Our infinite scroll comes with a fixed footer that slides in once you scroll down the page. The footer
parameter helps blend this footer with your theme design. By passing another ID, the infinite scroll footer will match its width so that it fits perfectly in your design. See it live here: http://twentytwelvedemo.wordpress.com/blog/. If you pass a false
value instead, no new footer would be added.
There're also other parameters you can tweak—here is an example showing all the default values for each configuration option:
add_theme_support( 'infinite-scroll', array( 'type' => 'scroll', 'footer_widgets' => false, 'container' => 'content', 'wrapper' => true, 'render' => false, 'posts_per_page' => false, ) );
Breaking down each option:
type
type
accepts two different values: scroll
or click
. This controls the default Infinite Scroll behaviour. scroll
will cause posts to be loaded automatically when the visitor approaches the bottom of the current list of posts, while click
shows a Load more posts button, letting the user control when more posts are loaded.
scroll
is the default, but if a theme has footer widgets, this could be overridden to click
so the widgets are accessible.
footer_widgets
The footer_widgets
argument accepts a variety of values and indicates whether or not a theme has footer widgets. If footer widgets are present, the scroll type will be set to click
so the widgets are accessible.
At its simplest, either a boolean true
or false
can be set if the footer should always or never be shown, respectively.
Additionally, either a string representing a sidebar ID ('sidebar-1'
, for example), or an array of sidebar IDs will be accepted by the footer_widgets
argument. The Infinite Scroll code will check if the sidebar(s) contain widgets and set the footer_widgets
argument accordingly.
Whenever possible, we highly recommend providing sidebar IDs if a theme places widget areas below the post list. Doing so provides the best experience for theme's users by dynamically determining whether the scroll type should be scroll
or click
. That said, if a theme specifies click
as the type from the outset, then the footer_widgets
argument can safely be omitted.
If all of those options weren't enough, the infinite_scroll_has_footer_widgets
filter is available for advanced logic. The filter must return a boolean value, and could be used to detect the presence of nav menus, or a visitor using a mobile device.
wrapper
The wrapper
argument behaves similarly to footer_widgets
, in that it accepts a few different values. This argument determines whether or not each set of additional posts is contained within a <div>
element when appended to the container specified in the preceeding argument.
If a boolean value (true
or false
) is specified, either a <div>
with the class infinite-wrap
is placed around the additional posts, or it isn't.
To wrap the posts in a <div>
with a custom class, set the wrapper
argument to a string representing the custom class.
It is generally good practice to wrap the appended posts in a <div>
, unless doing so will result in invalid markup. For example, if a theme uses a list element (<ol>
, <ul>
) to display posts, the wrapper should be disabled so that <div>
elements don't appear where they don't belong..
render
Infinite Scroll uses a standard WordPress loop to render the additional posts it appends, and utilizes template parts in the content-{post format}.php
form. If a theme includes at least content.php
, then the render
argument can be omitted. Below is the default rendering function Infinite Scroll uses:
while( have_posts() ) { the_post(); get_template_part( 'content', get_post_format() ); }
If greater customization is needed, or a theme doesn't use the content
template parts, a function name should be specified for the render
argument and that function will be used to generate the markup for Infinite Scroll. The function must include the while()
portion of WordPress' loop and can utilize any function available to the theme when it renders posts.
posts_per_page
By default, the type
argument controls how many posts are loaded each time Infinite Scroll acts. For the scroll
type, seven (7) posts are loaded each time Infinite Scroll is activated. For the click
type, a site's "Blog pages show at most" value found under Settings → Reading is used.
If, however, a theme's layout expects a certain number of posts, the posts_per_page
argument will override the defaults discussed in the preceding paragraph. This control is beneficial, for example, in a theme with a three-column layout where greater or fewer than three posts would result in an uneven layout.
Examples
With as wide a variety of themes and themers as exists, we aimed to provide enough control over how Infinite Scroll behaves as is necessary to support many themes. That said, our experience on WordPress.com showed that generally, each theme needs very few configuration options. To demonstrate, we've provided the Infinite Scroll configuration of WordPress default themes.
Twenty Twelve
/** * Add theme support for infinite scroll. * * @uses add_theme_support * @return void */ function twenty_twelve_infinite_scroll_init() { add_theme_support( 'infinite-scroll', array( 'container' => 'content', ) ); } add_action( 'after_setup_theme', 'twenty_twelve_infinite_scroll_init' );
For those unfamiliar with the Twenty Twelve theme, it uses content-{post format}.php
template parts and has no widget area below posts, so we've omitted the footer_widgets
and render
arguments. In reality, since the container
value matches the default, that argument could be omitted as well; we've left it for clarity.
Twenty Eleven
/** * Add theme support for infinity scroll. */ function twenty_eleven_infinite_scroll_init() { add_theme_support( 'infinite-scroll', array( 'container' => 'content', 'footer_widgets' => array( 'sidebar-3', 'sidebar-4', 'sidebar-5', ), 'footer' => 'page', ) ); } add_action( 'init', 'twenty_eleven_infinite_scroll_init' );
Twenty Eleven comes with footer widget areas, which wouldn't be reachable when you scroll down as new posts would be added whenever you reached the bottom. To solve this, we pass an array with the IDs of those widget areas to footer_widgets
. Now, if one of those sidebars has a widget, our Infinite Scroll plugin will detect it, and switch to the click
type automatically (where you click to load more posts on demand), so your footer content is still perfectly accessible. If your theme has footer widgets, consider this approach as you greatly improve the experience of your users.
Twenty Ten
/** * Add theme support for infinity scroll */ function twenty_ten_infinite_scroll_init() { add_theme_support( 'infinite-scroll', array( 'container' => 'content', 'render' => 'twenty_ten_infinite_scroll_render', 'footer' => 'wrapper', ) ); } add_action( 'init', 'twenty_ten_infinite_scroll_init' ); /** * Set the code to be rendered on for calling posts, * hooked to template parts when possible. * * Note: must define a loop. * function twenty_ten_infinite_scroll_render() { get_template_part( 'loop' ); }
Twenty Ten uses a slightly different template structure to render posts, so we need to provide a custom render function to infinite scroll.
Do It With Style
The last missing piece is how to make IS blend perfectly with your site design. Infinite Scroll relies on the theme supporting body_class
, and it provides theme developers with the utmost flexibility to improve the experience by using some specific body classes: whenever infinite scroll is active there will be an infinite-scroll
class available on body
; if the infinite scroll type is "scroll", there will also be a neverending
class too. Once the last post in a blog has been loaded, there will be an infinity-end
class added. With these, you can hide your regular footer and navigation links, and show them again when IS is finished. Example:
/* Hides navigation links and site footer when infinite scroll is active */ .infinite-scroll #navigation, .infinite-scroll.neverending #footer { display: none; } /* Shows the footer again in case all posts have been loaded */ .infinity-end.neverending #footer { display: block; }
There are also two elements that you'll want to style so that they fit in with your theme:
<span class="infinite-loader">[...]</span>
and
<div id="infinite-handle">[...]</div>
span.infinite-loader
is the loading indicator that is displayed while new posts are being retrieved. It is inserted as a child of container, and it is possible that after it is no longer needed, it will be hidden rather than removed from the DOM. Ensure that your CSS handles both cases.
div#infinite-handle
is the Load more posts button shown for type=click
. You can ignore this if your theme will always use type=scroll
and will never have any footer widgets.
JavaScript Events
Inevitably, there are situations in a theme that require some JavaScript interaction after posts are added. One such example is in a theme that uses jQuery Masonry and needs to trigger that library to position the additional posts. Recognizing this need, we trigger an event after posts are appended. To make use of this event, simply catch the post-load
event when it fires on document.body
:
( function( $ ) { $( document.body ).on( 'post-load', function () { // New posts have been added to the page. } ); } )( jQuery );
Other notes
Recognizing that this feature requires theme support to be useful, we've bundled support for the latest three default themes, Twenty Ten, Twenty Eleven, and Twenty Twelve, with Jetpack. If you happen to be using one of those themes, you can enable the Infinite Scroll module and enjoy this new feature immediately. If you are using one of the Automattic themes from WordPress.org, they should be updated already with infinite scroll support (the module card will provide a prompt to users who can upgrade themes if the active theme has an update available).