Instantly share code, notes, and snippets.

Embed
What would you like to do?
Better, Faster, Responsive Images for Divi – Upload in Divi child theme.
<?php
// enable divi functions
add_action( 'wp_enqueue_scripts', 'my_enqueue_assets' );
function my_enqueue_assets() {
wp_enqueue_style( 'parent-style', get_template_directory_uri().'/style.css' );
}
//add 1440px image size
add_image_size('image_1440', 1440, 9999, false);
//move the 'wp_make_content_images_responsive' filter to run last
remove_filter( 'the_content', 'wp_make_content_images_responsive', 10);
add_filter( 'the_content', 'wp_make_content_images_responsive', 1600, 1);
add_filter( 'the_content', 'hb_add_id_to_images', 1599, 1);
//filter the content and add wp-image-$id class to the images, allowing responsive feature to work
function hb_add_id_to_images( $content ) {
global $wpdb;
if ( ! preg_match_all( '/<img [^>]+>/', $content, $matches ) ) {
return $content;
}
foreach( $matches[0] as $image ) {
if ( !preg_match( '/wp-image-([0-9]+)/i', $image ) ) {
$dom = new DOMDocument();
$dom->loadHTML($image);
$img_element = $dom->getElementsByTagName('img')->item(0);
$wp_upload_dir = wp_upload_dir();
$image_path = str_replace(trailingslashit(preg_replace("(^https?://)", "", $wp_upload_dir['baseurl'])), '', preg_replace("(^https?://)", "", $img_element->getAttribute('src') ));
$attachment = $wpdb->get_col($wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_wp_attached_file' AND BINARY meta_value='%s';", $image_path ));
if ($attachment) {
$img_element->setAttribute("class", "wp-image-".$attachment[0]);
$new_image = $img_element->ownerDocument->saveHTML($img_element);
$content = str_replace ( $image , $new_image , $content);
}
}
}
return $content;
}
//lower image max-width to 1080px everywhere (retina compatible)
function hb_content_image_sizes_attr( $sizes, $size ) {
$width = $size[0];
if ($width >= 1080) $sizes = '(max-width: 1080px) 100vw, 1080px';
return $sizes;
}
add_filter( 'wp_calculate_image_sizes', 'hb_content_image_sizes_attr', 10 , 2 );
//override Divi 'et_pb_maybe_add_advanced_styles' function to fix the problem of browser downloading overridden background image
function hb_pb_maybe_add_advanced_styles() {
$styles = array();
// do not output advanced css if Frontend Builder is active
if ( ! et_fb_is_enabled() ) {
$styles['et-builder-advanced-style'] = ET_Builder_Element::get_style();
if ( preg_match_all('/\.[_a-z0-9]+\.et_pb_fullwidth_header \{.*background-image.*\}/', $styles['et-builder-advanced-style'], $matches ) ) {
foreach( $matches[0] as $bg_css ) {
$styles['et-builder-advanced-style'] = preg_replace('/url\(.*\)/', 'none', $styles['et-builder-advanced-style']);
}
}
$styles['et-builder-page-custom-style'] = et_pb_get_page_custom_css();
}
foreach( $styles as $id => $style_data ) {
if ( ! $style_data ) {
continue;
}
printf(
'<style type="text/css" id="%2$s">
%1$s
</style>',
$style_data,
esc_attr( $id )
);
}
remove_action( 'wp_footer', 'et_pb_maybe_add_advanced_styles' );
}
add_action( 'wp_footer', 'hb_pb_maybe_add_advanced_styles', 9 );
add_action('wp_footer', 'hb_responsive_bg_image', 10);
//add responsiveness for background images
function hb_responsive_bg_image() {
global $wpdb;
$css = ET_Builder_Element::get_style();
//find the background-image css in the inline css
if ( preg_match_all('/\.[_a-z0-9]+\.et_pb_fullwidth_header \{.*background-image.*\}/', $css, $matches ) ) {
foreach( $matches[0] as $bg_css ) {
if (preg_match('/\b(?:(?:https?|ftp|file):\/\/|www\.|ftp\.)[-A-Z0-9+&@#\/%=~_|$?!:,.]*[A-Z0-9+&@#\/%=~_|$]/i', $bg_css, $url_matches)) {
$url = $url_matches[0];
$wp_upload_dir = wp_upload_dir();
$image_path = str_replace(trailingslashit(preg_replace("(^https?://)", "", $wp_upload_dir['baseurl'])), '', preg_replace("(^https?://)", "", $url ));
$attachment = $wpdb->get_col($wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_wp_attached_file' AND BINARY meta_value='%s';", $image_path ));
$bg_css = preg_replace('/background-color([^;]*);/', '', $bg_css, 1);
if ($attachment) {
$image_meta = wp_get_attachment_metadata($attachment[0]);
$extra_css = '';
//add fullsize background image style, fixing the problem of browser downloading overridden background image
$extra_css .= '
@media only screen and ( min-width: 1441px ) {
' . $bg_css . '
}';
//add responsive background image for (non-retina) screen with max-width 1440px (use 1440px image), 1080px (use 1080px image), 768px (use 768px image)
if ($image_meta['sizes']['image_1440']) {
$extra_css .= '
@media only screen and ( max-width: 1440px ) {
' . str_replace(basename($url), $image_meta['sizes']['image_1440']['file'], $bg_css) . '
}';
}
if ($image_meta['sizes']['et-pb-portfolio-image-single']) {
$extra_css .= '
@media only screen and ( max-width: 1080px ) {
' . str_replace(basename($url), $image_meta['sizes']['et-pb-portfolio-image-single']['file'], $bg_css) . '
}';
}
if ($image_meta['sizes']['medium_large']) {
$extra_css .= '
@media only screen and ( max-width: 768px ) {
' . str_replace(basename($url), $image_meta['sizes']['medium_large']['file'], $bg_css) . '
}';
}
//add responsive background image for retina screen with max-width 1440px (use fullsize image), 768px (use 1440px image), 540px (use 1080px image), 384px (use 768px image)
$extra_css .= '
@media
only screen and ( max-width: 1440px ) and (-webkit-min-device-pixel-ratio: 2),
only screen and ( max-width: 1440px ) and ( min--moz-device-pixel-ratio: 2),
only screen and ( max-width: 1440px ) and ( -o-min-device-pixel-ratio: 2/1),
only screen and ( max-width: 1440px ) and ( min-device-pixel-ratio: 2),
only screen and ( max-width: 1440px ) and ( min-resolution: 192dpi),
only screen and ( max-width: 1440px ) and ( min-resolution: 2dppx) {
' . $bg_css . '
}';
if ($image_meta['sizes']['image_1440']) {
$extra_css .= '
@media
only screen and ( max-width: 768px ) and (-webkit-min-device-pixel-ratio: 2),
only screen and ( max-width: 768px ) and ( min--moz-device-pixel-ratio: 2),
only screen and ( max-width: 768px ) and ( -o-min-device-pixel-ratio: 2/1),
only screen and ( max-width: 768px ) and ( min-device-pixel-ratio: 2),
only screen and ( max-width: 768px ) and ( min-resolution: 192dpi),
only screen and ( max-width: 768px ) and ( min-resolution: 2dppx) {
' . str_replace(basename($url), $image_meta['sizes']['image_1440']['file'], $bg_css) . '
}';
}
if ($image_meta['sizes']['et-pb-portfolio-image-single']) {
$extra_css .= '
@media
only screen and ( max-width: 540px ) and (-webkit-min-device-pixel-ratio: 2),
only screen and ( max-width: 540px ) and ( min--moz-device-pixel-ratio: 2),
only screen and ( max-width: 540px ) and ( -o-min-device-pixel-ratio: 2/1),
only screen and ( max-width: 540px ) and ( min-device-pixel-ratio: 2),
only screen and ( max-width: 540px ) and ( min-resolution: 192dpi),
only screen and ( max-width: 540px ) and ( min-resolution: 2dppx) {
' . str_replace(basename($url), $image_meta['sizes']['et-pb-portfolio-image-single']['file'], $bg_css) . '
}';
}
if ($image_meta['sizes']['medium_large']) {
$extra_css .= '
@media
only screen and ( max-width: 384px ) and (-webkit-min-device-pixel-ratio: 2),
only screen and ( max-width: 384px ) and ( min--moz-device-pixel-ratio: 2),
only screen and ( max-width: 384px ) and ( -o-min-device-pixel-ratio: 2/1),
only screen and ( max-width: 384px ) and ( min-device-pixel-ratio: 2),
only screen and ( max-width: 384px ) and ( min-resolution: 192dpi),
only screen and ( max-width: 384px ) and ( min-resolution: 2dppx) {
' . str_replace(basename($url), $image_meta['sizes']['medium_large']['file'], $bg_css) . '
}';
}
?>
<style type="text/css" id="responsive-bg-image-style">
<?php echo $extra_css;?>
</style>
<?php
}
}
}
}
}
// **********End Faster, Better Divi images******
@MartyD23

This comment has been minimized.

Copy link

MartyD23 commented Nov 17, 2017

Hi, I'm using the Extra theme. This code works to add srcset to my post images, but doesn't alter the featured image, sidebar widget images, or the related posts images. Is there a way to get these working also?

I'm currently using this plugin which allows me to do all this, but thought your's may have been a better solution as it's tailored specifically for divi https://en-gb.wordpress.org/plugins/responsify-wp/

@Antera

This comment has been minimized.

Copy link

Antera commented Dec 13, 2017

This is awesome ! Could you make a WP plugin for this ?

@fldtrace

This comment has been minimized.

Copy link
Owner Author

fldtrace commented Mar 3, 2018

Hey guys,
The code is optimized for Divi theme. Yes, it can be extended to work virtually on any theme. At this point, I do not want to invest the time to create a plugin because it could become obsolete if Divi decides to add support for srcset.

@joachimtranberg

This comment has been minimized.

Copy link

joachimtranberg commented Mar 3, 2018

I was trying to use this, but it doesnt work with utf-8? Special letters like øæå (danish) doesnt work in the alt title and alt text.

@huubl

This comment has been minimized.

Copy link

huubl commented Aug 24, 2018

It's not working for the background images, any idea why?

@shantiram108

This comment has been minimized.

Copy link

shantiram108 commented Oct 19, 2018

Thank you so much for this. Seems insane that elegant themes have not fixed this already.

It's not working for the background images, any idea why?

The regex on line 104 is incorrect, maybe because of a recent update to Divi.
Try replacing line 104 with this:
if ( preg_match_all('/(\.et_pb_fullwidth_header\.[_a-z0-9]+|\.et_pb_slider \.[_a-z0-9]+) \{.*background-image.*\}/', $css, $matches ) ) {
This also makes it work for slider backgrounds.

However there still seems to be issues with css specificity, sometimes the responsive styles are overridden.

@ThomasZUOO

This comment has been minimized.

Copy link

ThomasZUOO commented Dec 14, 2018

Thank you so much for this. Seems insane that elegant themes have not fixed this already.

It's not working for the background images, any idea why?

The regex on line 104 is incorrect, maybe because of a recent update to Divi.
Try replacing line 104 with this:
if ( preg_match_all('/(\.et_pb_fullwidth_header\.[_a-z0-9]+|\.et_pb_slider \.[_a-z0-9]+) \{.*background-image.*\}/', $css, $matches ) ) {
This also makes it work for slider backgrounds.

However there still seems to be issues with css specificity, sometimes the responsive styles are overridden.

Sadly still does not work for background images, and of course those are the main culprit. :/

@hleen

This comment has been minimized.

Copy link

hleen commented Jan 4, 2019

I really appreciate yor work!
However, it does not work on my fullwidth header image
It has the following class:

<div class="et_pb_module et_pb_fullwidth_image et_pb_fullwidth_image_0">
<img src="[url]mylogo.jpg" alt="">
</div>

I already tried:

`if ( preg_match_all('/(\.et_pb_fullwidth_header\.[_a-z0-9]+|\.et_pb_slider \.[_a-z0-9]+|\.et_pb_fullwidth_image \.[_a-z0-9]+) \{.*background-image.*\}/', $css, $matches ) ) { `

without success. It also does not get an ID.

@crobertwatson

This comment has been minimized.

Copy link

crobertwatson commented Jan 17, 2019

Didn't work for me at all. No srcset anything shows up in my view source even after regenerating the thumbnails. I added it as noted to the functions.php file, but it doesn't seem to be doing anything. Maybe because I'm using a Divi child theme.

@behiveco

This comment has been minimized.

Copy link

behiveco commented Jan 26, 2019

Such a shame Elegant Themes hasn't added SRCSET support yet. It's been 2 years since I asked in Support! Thanks for your work. Are you still updating this?

@MartyD23

This comment has been minimized.

Copy link

MartyD23 commented Jan 27, 2019

Like most Divi users i'm also shocked ET hasn't added support for this.

Yet, if you look on the ET blog, all their images have srcset for responsive images!!!

Can we all do our bit and email support asking them for it? I've done this.

Hopefully the more requests they get the sooner it will be implemented!

Note: for long standing issues like this you may have to write a letter to Nick Roach and send it to his physical mailing address. I've had to do this on occasion to fix long standing bugs that were simply not fixed by pleading with support over many months to do so.

@MartyD23

This comment has been minimized.

Copy link

MartyD23 commented Jan 27, 2019

Just wanted to post an update.

I'm using the Extra theme and for a long time used the Responsify WP plugin: https://en-gb.wordpress.org/plugins/responsify-wp/

I recently saw it wasn't working, but then realized i needed to change to the picture attribute in the plugin settings. It was working fine before with the img attribute, so not sure why the change?

I also discovered i was having issues with getting lazy loading working when using the plugin. I found out that not all lazy load plugins support the picture attribute, but i found one that does : https://wordpress.org/plugins/lazy-loading-responsive-images/

So basically using these two plugins together on the Extra or Divi theme will allow you to have highly customizable responsive images for different devices. Hope this helps other Divi users.

@ThomasZUOO

This comment has been minimized.

Copy link

ThomasZUOO commented Jan 31, 2019

Just wanted to post an update.

I'm using the Extra theme and for a long time used the Responsify WP plugin: https://en-gb.wordpress.org/plugins/responsify-wp/

I recently saw it wasn't working, but then realized i needed to change to the picture attribute in the plugin settings. It was working fine before with the img attribute, so not sure why the change?

I also discovered i was having issues with getting lazy loading working when using the plugin. I found out that not all lazy load plugins support the picture attribute, but i found one that does : https://wordpress.org/plugins/lazy-loading-responsive-images/

So basically using these two plugins together on the Extra or Divi theme will allow you to have highly customizable responsive images for different devices. Hope this helps other Divi users.

Hmm, when using responsify-wp the images are being cutoff on mobile, also Divi full with sliders are getting messed up responsify with it. It looked so promising! :O

@SeanYoko

This comment has been minimized.

Copy link

SeanYoko commented Feb 7, 2019

Is this up to date?

I attempted to add this to my child theme functions.php, it, unfortunately, did not solve my issue as many other folks above have also stated.

I'm experiencing just the same trouble as cited below.

Anyone else got any ideas?

I really appreciate yor work!
However, it does not work on my fullwidth header image
It has the following class:

<div class="et_pb_module et_pb_fullwidth_image et_pb_fullwidth_image_0">
<img src="[url]mylogo.jpg" alt="">
</div>

I already tried:

`if ( preg_match_all('/(\.et_pb_fullwidth_header\.[_a-z0-9]+|\.et_pb_slider \.[_a-z0-9]+|\.et_pb_fullwidth_image \.[_a-z0-9]+) \{.*background-image.*\}/', $css, $matches ) ) { `

without success. It also does not get an ID.

@SeanYoko

This comment has been minimized.

Copy link

SeanYoko commented Feb 7, 2019

Specifically, The code is generated. I see the media queries at the bottom of the file but all of them are overridden by the standard divi CSS.

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