Skip to content

Instantly share code, notes, and snippets.

@joshuadavidnelson
Last active January 22, 2024 12:42
Show Gist options
  • Save joshuadavidnelson/eb4650aa1ee8da9c7d731960e9402e21 to your computer and use it in GitHub Desktop.
Save joshuadavidnelson/eb4650aa1ee8da9c7d731960e9402e21 to your computer and use it in GitHub Desktop.
Using WordPress responsive images for css background-image property, in-line styling
<style>
.header {
background-image: url(http://local.dev/wp-content/uploads/2016/04/image-300x151.png)
}
@media only screen and (min-width: 300px) {.header {
background-image: url(http://local.dev/wp-content/uploads/2016/04/image-768x386.png)
}}
@media only screen and (min-width: 768px) {.header {
background-image: url(http://local.dev/wp-content/uploads/2016/04/image-1024x515.png)
}}
@media only screen and (min-width: 1024px) {.header {
background-image: url(http://local.dev/wp-content/uploads/2016/04/image.png)
}}
</style>
<?php
/**
* Generate some inline styles for use with the background-image and responsive images in WordPress.
*
* Uses wp_get_attachment_image_srcset to gather the image urls and device sizes.
* A mobile-friendly application of the background-image property.
* In this example, it's setup for a full-width image
*
* @author Joshua David Nelson, [email protected]
*/
$image_id = get_post_thumbnail_id(); // set or grab your image id
$img_srcset = wp_get_attachment_image_srcset( $image_id, 'full' );
$sizes = explode( ", ", $img_srcset );
$css = '';
$prev_size = '';
foreach( $sizes as $size ) {
// Split up the size string, into an array with [0]=>img_url, [1]=>size
$split = explode( " ", $size );
if( !isset( $split[0], $split[1] ) )
continue;
$background_css = '.header {
background-image: url(' . esc_url( $split[0] ) . ')
}';
// Grab the previous image size as the min-width and/or add the background css to the main css string
if( !empty( $prev_size ) ) {
$css .= '@media only screen and (min-width: ' . $prev_size . ') {';
$css .= $background_css;
$css .= "}\n";
} else {
$css .= $background_css;
}
// Set the current image size as the "previous image" size, for use with media queries
$prev_size = str_replace( "w", "px", $split[1] );
}
// The final css, wrapped in a <style> tag
$css = !empty( $css ) ? '<style>' . $css . '</style>' : '';
@mariannag7282
Copy link

Thank you for this. Where would I place your code to generate the responsive background-image?

@MaikelGG
Copy link

MaikelGG commented Jul 2, 2020

Thanks for this snippet.
Perhaps something changed in the Wordpress function but I needed to add sort($sizes); to get the order right, otherwise it is all mixed up. Maybe somebody will run into the same issue....

@ggeiger
Copy link

ggeiger commented Sep 22, 2020

Thanks for the original code! It inspired me to complete a different version. I ended up creating a function (added to functions.php):

function getSrcSet($id) {

  $img_srcset   = wp_get_attachment_image_srcset($id, 'full');
  $srcset_array = explode(", ", $img_srcset);
  $images  = array();
  $x = 0;

  foreach ($srcset_array as $set) :

    $split = explode(" ",$set );

    if (!isset($split[0], $split[1])) continue;

    $images[$x]['src'] = $split[0];
    $images[$x]['width'] = str_replace('w', '', $split[1]);

    $x++;

  endforeach;
  
  // sort the array, ordered by width
  usort($images, function($a, $b) {
    return $a['width'] <=> $b['width'];
  });

  return $images;
}

Then in my template file I'm calling the function and looping through the results:

$css = '';
$image_id = get_post_thumbnail_id();
$srcset = getSrcSet($image_id);

foreach ($srcset as $set) :

  // skip big ones
  if ($set['width'] > 1600) continue;

  $css .= '@media only screen and (min-width: ' . $set['width'] . 'px) {
    .slide { background-image: url(' . $set['src'] . '); } }';

endforeach; ?>
  	
<div class="slide"></div>
 
<?php $css = !empty($css) ? '<style>' . $css . '</style>' : ''; echo $css; ?>

@ensignrolaren
Copy link

@ggeiger Thanks for your rewritten code– it does the job nicely. The addition of the custom usort() function solves the problem I was having with the original where the wp_get_attachment_image_srcset() function called the sizes out of order.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment