Modifying Custom Background Feature for Any HTML Element You Want

Modifying Custom Background Feature for Any HTML Element You Want

In the recent new WordPress version, WordPress has added some new features such as Custom Background, Custom Header, etc, you can see this in action in the Twenty Eleven theme. The Custom Background will add a CSS snippet that effects the <body> element’s background, what if you only want this feature to effect another element you specify? Maybe the <header>, <content>, or <footer> elements or another HTML tag.


Find Out Something

In this tutorial, I use Twenty Eleven (in WordPress version 3.4) as a demonstration. Below is a function that handles the Custom Background feature for this theme, I found it in functions.php file:

add_theme_support(
	'custom-background',
	array(
		// Let WordPress know what our default background color is.
		// This is dependent on our current color scheme.
		'default-color' => $default_background_color,
	)
);

And it was declared in the theme.php file under the wp-includes directory:

	function add_theme_support( $feature ) {
		global $_wp_theme_features;

		if ( func_num_args() == 1 ) {
			$args = true;
		}
		else {
			$args = array_slice( func_get_args(), 1 );
		}

		switch ( $feature ) {
			// This function is so long, I only show stuff we need
			case 'custom-background' :
				if ( ! is_array( $args ) )
					$args = array( 0 => array() );

				$defaults = array(
					'default-image' => '',
					'default-color' => '',
					'wp-head-callback' => '_custom_background_cb',
					'admin-head-callback' => '',
					'admin-preview-callback' => '',
				);

				$jit = isset( $args[0]['__jit'] );
				unset( $args[0]['__jit'] );

				// Merge in data from previous add_theme_support() calls. The first value registered wins.
				if ( isset( $_wp_theme_features['custom-background'] ) ) {
					$args[0] = wp_parse_args( $_wp_theme_features['custom-background'][0], $args[0] );
				}

				if ( $jit ) {
					$args[0] = wp_parse_args( $args[0], $defaults );
				}

				if ( defined( 'BACKGROUND_COLOR' ) ) {
					$args[0]['default-color'] = BACKGROUND_COLOR;
				}
				elseif ( isset( $args[0]['default-color'] ) || $jit ) {
					define( 'BACKGROUND_COLOR', $args[0]['default-color'] );
				}

				if ( defined( 'BACKGROUND_IMAGE' ) ) {
					$args[0]['default-image'] = BACKGROUND_IMAGE;
				}
				elseif ( isset( $args[0]['default-image'] ) || $jit ) {
					define( 'BACKGROUND_IMAGE', $args[0]['default-image'] );
				}

				break;
		}
	}

We can see the add_theme_support is used without passing the value of wp-head-callback parameter (except for default-color) that means the default callback function will be called. In this case, that is _custom_background_cb. It was also defined in theme.php file:

function _custom_background_cb() {
	$background = get_background_image();
	$color = get_background_color();
	if ( ! $background && ! $color )
		return;

	$style = $color ? "background-color: #$color;" : '';

	if ( $background ) {
		$image = " background-image: url('$background');";

		$repeat = get_theme_mod( 'background_repeat', 'repeat' );
		if ( ! in_array( $repeat, array( 'no-repeat', 'repeat-x', 'repeat-y', 'repeat' ) ) )
			$repeat = 'repeat';
		$repeat = " background-repeat: $repeat;";

		$position = get_theme_mod( 'background_position_x', 'left' );
		if ( ! in_array( $position, array( 'center', 'right', 'left' ) ) )
			$position = 'left';
		$position = " background-position: top $position;";

		$attachment = get_theme_mod( 'background_attachment', 'scroll' );
		if ( ! in_array( $attachment, array( 'fixed', 'scroll' ) ) )
			$attachment = 'scroll';
		$attachment = " background-attachment: $attachment;";

		$style .= $image . $repeat . $position . $attachment;
	}
?>
<style type="text/css">
body.custom-background { <?php echo trim( $style ); ?> }
</style>
<?php
}

Notice anything? Yes, the CSS snippet we need in the end of function.


What We Need to Do

In your functions.php file, you add following code:

function change_custom_background_cb() {
	$background = get_background_image();
	$color = get_background_color();

	if ( ! $background && ! $color )
		return;

	$style = $color ? "background-color: #$color;" : '';

	if ( $background ) {
		$image = " background-image: url('$background');";

		$repeat = get_theme_mod( 'background_repeat', 'repeat' );

		if ( ! in_array( $repeat, array( 'no-repeat', 'repeat-x', 'repeat-y', 'repeat' ) ) )
			$repeat = 'repeat';

		$repeat = " background-repeat: $repeat;";

		$position = get_theme_mod( 'background_position_x', 'left' );

		if ( ! in_array( $position, array( 'center', 'right', 'left' ) ) )
			$position = 'left';

		$position = " background-position: top $position;";

		$attachment = get_theme_mod( 'background_attachment', 'scroll' );

		if ( ! in_array( $attachment, array( 'fixed', 'scroll' ) ) )
			$attachment = 'scroll';

		$attachment = " background-attachment: $attachment;";

		$style .= $image . $repeat . $position . $attachment;
	}
?>
<style type="text/css">
body.custom-background { <?php echo trim( $style ); ?> }
</style>
<?php
}
if ( is_wp_version( '3.4' ) ) {
	add_theme_support( 'custom-background', array( 'wp-head-callback', 'change_custom_background_cb' ) );
}
else {
	add_custom_background('change_custom_background_cb');
}

All you need is to replace body.custom-background with the CSS selector you need. The Custom Background feature will only change the background of the element that you define, not the whole site. These snippets also work with old WordPress versions (3.0 or earlier). All done!

We’re basically mimicking the built-in functionality, but tweaking it to suit our own needs.

That’s it! Hope you like that quick tip, I would appreciate any comments.

Update: This tutorial has been updated to fix the mistakes mentioned in the comments below. If you notice any other errors, please let us know!

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.customicondesign.com custom icon design

    very great tutotial. I like the article like this. very simple but useful.

  • http://kremalicious.com Matthias

    I’m sorry, but this post is very misleading and leads to very serious issues when implemented like that .

    First, support for Custom Background, Custom Header, etc wasn’t added in 3.4 but in 3.0. WP 3.4 only added a terrific UI for that.

    Second, what you’re describing in this post only applies to the pre 3.4 implementation for Custom Background. add_custom_background was deprecated in WordPress 3.4 (you didn’t even look in the Codex, right?) and what you have posted from the Twenty Eleven theme is from an old version of the theme. Please don’t tell developers to use a deprecated function. If you would have taken a look at the current version of the Twenty Eleven theme, you would have seen that all your posted snippets are not there anymore. This is what you should be using now:

    add_theme_support( ‘custom-background’);

    • http://wp.envato.com/ Japh Thomson
      Staff

      Hey Matthias, thank you so much for pointing that out. We’ve updated the post accordingly. Let us know if you still see any issues.

      Thanks again for your feedback :)

      • http://kremalicious.com Matthias

        Great, that was fast. I can’t test this at the moment but it looks about right. Only the non WP-default is_wp_version function needs to be defined somewhere, at the moment this would lead to a blank screen.

        And just as a completeness suggestion: if I see this right, users won’t see their changes in the new theme editor in this form, that’s what admin-head-callback & admin-preview-callback are for. Just modifying the css selectors from the _custom_background_cb function should be enough for these additional functions. But don’t just take my word for granted, I haven’t had the time to fully checkout this particular 3.4 stuff so thorough testing would be needed :-)

    • http://wp.tutsplus.com/author/leepham/ Lee Pham
      Author

      Hi, Mathias, thank you very much. It’s so embarrassing. :(

      • http://kremalicious.com Matthias

        Lee, no problem. The initial idea is really great, but checking the Codex for the functions you use from time to time is important. Everything changes pretty fast, those WP core devs are busy bees.

        I would suggest you use a local dev system with debugging turned on. That gives you the freedom to make errors to learn from them without being public. The old code would have flooded the debug.log under WP 3.4 with messages about deprecation and you would have been able to act on that. Have fun!

        • http://wp.tutsplus.com/author/leepham/ Lee Pham
          Author

          Hi Matthias, thanks for suggesting. I’ll try to use it next time. :)

  • http://www.wpfix.org wpfix

    Nice tut

  • http://www.wparabia.com Mostafa

    thank you for this tuts