Full screen background images are a nice feature for a number of WordPress themes. It’s also one of the few theme modifications that can be handled well through a plugin.
The implementations I’ve seen generally use the jQuery script backstretch.js– which handles responsive layouts and large images elegantly.
If you’re not a theme developer and just want to add a full screen background to your site, I’d suggest trying out one of these plugins:
- Simple Full Screen Background Image (Free)
- Easy Backstretch (Free)
- WP Backstretch (Paid)
If you are a developer and want learn how to add this feature to a theme, read on.
How it Works
There’s a couple items you’ll want to look out for with a feature like this:
- Load the scripts only when it can actually be used (e.g. image is set)
- Make sure the user has the ability to turn it on or off
- Remove the default inline styles used with background images
- Load the image at an appropriate time
I created a basic version of this in plugin form (on GitHub), which is the code I’ll walk through.
Add Support for Background Images to the Theme
We’ll use the built in WordPress support for background images. This line should be included in the function called from the after_theme_setup hook:
add_theme_support( 'custom-background' );
Read more about the custom background feature and additional arguments here.
Add Option to the Theme Customizer
Now let’s add an option that allows the user turn full screen backgrounds on and off. The dashboard UI isn’t very extensible, but we can add this easily to the theme customizer under the background heading:
/** * Adds an option to the theme customizer for full screen backgrounds. * Disabled by default. */ function basic_backstretch_customizer_register( $wp_customize ) { // Add full screen background option $wp_customize->add_setting( 'basic-backstretch', array( 'default' => 10, 'type' => 'option' ) ); // This will be hooked into the default background_image section $wp_customize->add_control( 'basic-backstretch', array( 'settings' => 'basic-backstretch', 'label' => __( 'Full Screen Background', 'textdomain' ), 'section' => 'background_image', 'type' => 'checkbox' ) ); } add_action( 'customize_register', 'basic_backstretch_customizer_register' );
Note, if you already use other options for your theme, change the ‘basic-backstretch’ setting to match the rest of your theme. E.g. ‘settings’ => ‘mytheme[full_background]’.
You’ll also want to use the actual text domain of your theme for translation.
Before Enqueuing the Scripts
Before the backstretch scripts are enqueued, we’ll want to make sure that they are actually needed.
This means that a background image would need to be set and that the user has chosen the option to display backgrounds full screen.
These two checks are:
- if ( get_background_image() )
- if ( get_option( ‘basic-backstretch’ ) )
If you’ve changed the option name, #2 might be different.
If those two conditions aren’t met, the scripts won’t be loaded.
Enqueue the Scripts
There’s a lot going on in this function. I’ve added inline comments that explain most of what is happening.
The theme_mod_background_image filter will be explained in the next section.
/** * Checks if a background image is present and if full screen background option is set. * If so, required scripts are loaded. */ function basic_backstretch() { if ( get_background_image() && get_option( 'basic-backstretch' ) ) { // Registers the backstretch script wp_register_script( 'basic-backstretch-js', get_template_directory_uri() . '/js/jquery.backstretch.js', array('jquery'), '20130930', true ); // Enqueues the script wp_enqueue_script( 'basic-backstretch-js' ); // Adds a javascript object with the background image URL // This is used to load the image after other images on page have finished wp_localize_script( 'basic-backstretch-js', 'basicbackstretch', array( 'background' => esc_url( get_background_image() ) ) ); // Remove the background image from being included in inline styles // Uses http://codex.wordpress.org/Plugin_API/Filter_Reference/theme_mod_$name add_filter( 'theme_mod_background_image', 'backstretch_background_image_mod' ); // Add script to load backstretch in the footer add_action( 'wp_footer', 'basic_backstretch_inline_script', 100 ); } } add_action( 'wp_enqueue_scripts', 'basic_backstretch' ); /** * Inline script will load the full screen background image after all other images * on the page have loaded. */ function basic_backstretch_inline_script() { ?> <script> jQuery( window ).load( function() { jQuery.backstretch(basicbackstretch.background, {speed: 300}); }); </script> <?php }
Prevent the Background Image Defaults from Displaying
When background support is enabled in a theme, inline styles are automatically added to the head of the page to display it properly. If you don’t remove these styles, you’ll likely see a flash of tiled images before backstretch has a chance to load.
In the above function I used a filter to remove the inline styles:
add_filter( ‘theme_mod_background_image’, ‘backstretch_background_image_mod’ );
With this function:
/** * Keeps inline styles for the background image from outputting in the header * * Works similar to the pre_option filter * http://codex.wordpress.org/Plugin_API/Filter_Reference/pre_option_(option_name) */ function backstretch_background_image_mod() { return false; }
This works by filtering the theme_mod before it renders, so no inline styles are rendered.
This might be less than ideal if another plugin needed to use the background image in some way- but I can’t really think of a good use case where this would happen.
Another way to change the output of the inline styles though, would be to pass a custom callback for wp-head-callback when registering support for custom backgrounds. That method is suggested in this backstretch tutorial by wpsites.
// Add custom background callback for background color function custom_background_callback() { if ( ! get_background_color() ) return; printf( '<style>body { background-color: #%s; }</style>' . "\n", get_background_color() ); }
Loading the Image
In the enqueue scripts section, this outputs the code in the footer of the page which triggers the loading of the image by backstretch:
<script> jQuery( window ).load( function() { jQuery.backstretch(basicbackstretch.background, {speed: 300}); }); </script>
There are two main hooks javascript is fired on: document.ready or the window.load. Since full screen images can be large in size, I choose to use the window.load hook. This means the background won’t fade in until all the other images on the page have rendered.
If your site has a ton of images and takes a long time to load, it might be strange to have the background load so late. But in my opinion, it’s more important for the primary site content to load first before nice design touches like the background.
Full Source Code
If you want to try this code in plugin, or read through it all in linear order, check out the demo plugin I put on GitHub. The minified code for backstretch.js is also there, but the official GitHub repo for that project is more likely to have the latest version.
Is the only reason to use a script over simply using
body { background-size: cover; }
, backwards compatibility?Yeah, that’s a really great question. “background-size: cover” is fairly well supported by browsers now, as this article on CSS-Tricks points out: http://css-tricks.com/perfect-full-page-background-image/.
With this backstretch implementation the large background image is not loaded until all the other images on the page have loaded, but that’s generally how CSS backgrounds work anyways.
I’ll have test it out and see if there’s any other differences. If not, I guess I’ll need to write an update…
I’ve found that Backstretch actually performs better than using background-size, in my case anyway. I initially had background-size built into my Publisher theme but had to remove it due to sluggish scrolling. In my testing, Backstretch was noticeably more performant when compared side by side with background-size.
Any plans to publish this in wordpress.org?
No, there are a number of great ones in there already. No need to clutter the directory up.
Tried all of these solutions and found WP Backstretch the most flexible. http://wpsites.net/web-design/3-ways-to-add-responsive-background-images-slideshows-in-genesis-using-backstretch/
I haven’t tried this yet, but I am wondering if there is an option for multiple background on different pages.