Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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, josh@joshuadnelson.com
*/
$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>' : '';
@rsynnot

This comment has been minimized.

Copy link

@rsynnot rsynnot commented Jun 12, 2017

This is awesome.
But where do the media query breakpoints come from?
Mine are different to yours in your output there...

.hero-photo {
		background-image: url(...)
}
@media only screen and (min-width: 5846px) {.hero-photo {
		background-image: url(...)
}}
@media only screen and (min-width: 300px) {.hero-photo {
		background-image: url(...)
}}
@media only screen and (min-width: 768px) {.hero-photo {
		background-image: url(...)
}}
@media only screen and (min-width: 750px) {.hero-photo {
		background-image: url(...)
}}

I added in an IF statement to omit giant 'full' size images from the initial CSS rule:

if( !empty( $prev_size ) ) {
	//so a size now exists
	if ($prev_size <= 1280 ){
		$css .= '@media only screen and (min-width: ' . $prev_size . ') {';
		$css .= $background_css;
		$css .= "}\n";
	}
} else {
	$css .= $background_css;
}

And now that first huge image does not appear 😄

@ronca85

This comment has been minimized.

Copy link

@ronca85 ronca85 commented Jul 21, 2017

i have a project with an owl carousel 2 slider on the front-page with background images showing up inside. how do i use this code to makethe images responsive?

@mariannag7282

This comment has been minimized.

Copy link

@mariannag7282 mariannag7282 commented Sep 18, 2019

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

@MaikelGG

This comment has been minimized.

Copy link

@MaikelGG 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

This comment has been minimized.

Copy link

@ggeiger 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; ?>

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