Responsive background images

Responsivity is a big issue nowadays with all the phone users browsing your website rather than taking their laptop here and there.

We all know how to use responsive images already, that is not that big issue if you don’t check this post on CSS tricks out. But what if you need responsive background images, well even that is not that big issue, for more check this out on Smashingmagazine. But!
What if you need dynamically defined background images? We can’t define all the possible background images for all possible divs we might have now and then in the bare CSS file beforehand.

Why do we need dynamically defined images?

There are simply cases where you want an image used on the containers background because you plan to have a content over it, or blend the image with the background image on :hover, :active, :focus what ever states or script/user action.
Or, you can take advantage of the CSS background-size: cover/contain/.. feature which might help you with the variety image sizes your client is uploading that simply do not fit with your div container sizes you like to keep in your design, the image proportions are not accurate and so you help your self with the background image which doesn’t take the divs dimensions into account as much as inserted image and so on and so forth. In such cases it is grate to use background image.. but … there is always but.. how to set it all up.

Well, here is my approach to that.

Testing scenario:
Say we simply want to query number of posts. We want to use the featured image for each post as it’s background (with responsive dimensions).

Wordpress with defined image sizes (there are 4 in WP by default already) plus we have to be able to set featured images and have them set.

In order to set background image for a specific div we need basically something like this:

[php]<div style="background-image: url(‘img/image.jpg’);">….some content..</div>[/php]

Here is an elementary WordPress loop enriched by the CSS style defining divs background image.

[php]if ( have_posts() ) :
while ( have_posts() ) : the_post();
echo ‘<div style="background-image: url(‘img/image.jpg’);">’; the_content(); // call for post_content
echo ‘</div>’;

This will gives as number of post/pages with the same image.jpg as the background.

What we are going to actually do is to take a featured image ID of the post send it along the CSS queries to the function which gives us back the needing CSS. Even more, we will store all the image IDs on side and send it to our function but not sooner than the query loop loops trhough all it has to loop through. Thanks to this the result will be much cleaner than if we write the complete CSS query for each div in each loop circle.

The function takes two arguments. Image IDs in simple array and the image sizes with queries in second array.
the call looks might look like this:

$id_array(23, 3, 2455, 267, 90);
$queries = array(
array(‘large_screens’,’min-width: 1450px’), // the predefined WP image size, CSS query
array(‘medium’,’max-width: 480px’),
array(‘large’,”) // the empty query is basically saying "this is overall css definition"

responsive_background_pictures($id_array, $queries)

It might seems bit puzzeling at first glance but you have to set it once and you are done for all. The most puzzeling is the $queries array where you define multiple arrays within array. Each array defines in first place the name of picuture size that has to be used for the given resolution.

Here is the actual function:

[php]// $id_array: array(1, 2, 3,…)
// $queries = array(
// array(‘large_screens’,’min-width: 1450px’), // the predefined WP image size, CSS query
// array(‘medium’,’max-width: 480px’),
// array(‘large’,”)
// );
function responsive_background_pictures($id_array, $queries){
$with_euery = ”;
$without_euery = ”;
// for each style resolution
foreach($queries as $query){
$each_style = ”;

// for each picture
foreach ($id_array as $id) {
$each_style .= ‘#img_’.$id.'{background-image:url(‘.wp_get_attachment_image_src(get_post_thumbnail_id($id) , $query[0])[0].’);} ‘;
// if the query has no media query resolution set, print it out as it is
$with_euery .= ‘@media only screen and (‘.$query[1].’) {‘;
$with_euery .= $each_style;
$with_euery .= "}\n";
$without_euery .= $each_style;

return $without_euery."\n".$with_euery."\n";

(the function will goes in to your function.php file in the template directory)

The loop in your template will look like this:

[php]// define image sizes for queries
$queries = array(
array(‘large_screens’,’min-width: 1450px’), // the predefined WP image size, CSS query
array(‘medium’,’max-width: 480px’),
// define empty array for image IDs
$id_array = array();

if ( have_posts() ) :
while ( have_posts() ) : the_post();
// create specific ID named by the picture ID
echo ‘<div id="img_’.$post->ID.’">’; // see the trick with div ID named by picture ID // add the actual pict id to the array
$img_id = get_post_thumbnail_id( $post->ID );
$id_array[] = $img_id;
the_content(); // call for post_content
echo ‘</div>’;

// run the function
echo ‘<style>’.responsive_background_pictures($id_array, $queries).'</style>’;[/php]

If you look closer, you’ll see a trick with div IDs based on picture IDs which we are sending to a function and the function generates appropriate style output.
The function will echo something like this:

The function generates the overall background image sources, after that adds the wanted image sources for each resolution Query. You can add as many Queries as you like, and do it for as many pictures as your server PHP max execution time handles ;)

the resulting HTML might look like this:

<div class="post-423 attachment type-attachment status-inherit hentry item " id="img_423" ></div>
<div class="post-424 attachment type-attachment status-inherit hentry item " id="img_424" ></div>
<div class="post-425 attachment type-attachment status-inherit hentry item " id="img_425" ></div>
@media only screen and (min-width: 1450px) {#img_423{background-image:url(×1068.jpg);}#img_424{background-image:url(×1450.jpg);}#img_425{background-image:url(×1450.jpg);}}
@media only screen and (max-width: 480px) {#img_423{background-image:url(×236.jpg);}#img_424{background-image:url(×400.jpg);}#img_425{background-image:url(×400.jpg);}}


And the website usage might be something like the website below. Nothing visibly fancy, but the images you serve to viewers are optimised for the actual device, be it mobile, or 24″ designers monitor ;) Small gets small, large gets larger.