Skip to content

Instantly share code, notes, and snippets.

@fldtrace
Last active July 3, 2021 18:26
Show Gist options
  • Star 27 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save fldtrace/b75fe97c9a60270dd672566b796be936 to your computer and use it in GitHub Desktop.
Save fldtrace/b75fe97c9a60270dd672566b796be936 to your computer and use it in GitHub Desktop.
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******
Copy link

ghost 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
Copy link

Antera commented Dec 13, 2017

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

@fldtrace
Copy link
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
Copy link

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.

@huub-l
Copy link

huub-l commented Aug 24, 2018

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

@formicagreen
Copy link

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
Copy link

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
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
Copy link

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
Copy link

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?

Copy link

ghost 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.

Copy link

ghost 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
Copy link

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
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
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.

@fldtrace
Copy link
Author

fldtrace commented Jul 2, 2019

Hello, the word is that Divi will update their core to work.

Meanwhile, if you need assistance with this plugin please post this project for my partners. https://codeable.io/?ref=oXT3x

@ThomasZUOO
Copy link

This is from their latest blog!!

"Responsive Images are coming soon to Divi as well. This will improve the optimization of images used in Divi even further by serving up the scaled images that are the right size for different responsive displays (like tablet and phone"

@oheinrich
Copy link

With the new version 2.27 of the Divi / Extra Theme SRCSET is support, hooray!!! :-)
https://www.elegantthemes.com/api/changelog/extra.txt

version 2.27 ( updated 08-15-2019 )

  • Added SRCSET support for responsive images.

@appbisweb
Copy link

With the new version 2.27 of the Divi / Extra Theme SRCSET is support, hooray!!! :-)
https://www.elegantthemes.com/api/changelog/extra.txt

version 2.27 ( updated 08-15-2019 )

  • Added SRCSET support for responsive images.

Yes, but still no background image optimization. So the second part should be still useful for page speed improvements.

@ThomasNL1995
Copy link

While i can't get this to work anymore i found a promising plugin called Optimole:
https://wordpress.org/plugins/optimole-wp/

It's free for websites that stay under 5000 unique views per month. It serves all images INCLUDING background images via their CDN and makes them responsive and as a bonus converts them to webp.

This drastically improved my pagespeed score, getting rid of anything regarding images :)

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