Support

Account

Home Forums Front-end Issues WordPress 4.4 responsive images

Solving

WordPress 4.4 responsive images

  • Now that we have responsive images baked into the WP core as of 4.4 (released 8 Dec 2015), is there a way we can take advantage of this in our custom fields? Images added to the default WP content editor are automatically outputted with the responsive markup already generated. However, images added through AFC fields are not.

    Is there a catch all way (function?) that we can take advantage of that does not involve manually parsing each custom field through a filter or adding additional markup to our echoing of fields? I’d love to easily be able take advantage of this on sites I already have out there without having to perform major updates to the template files of each site.

    EDIT:

    I’ve had a look into the release notes for the responsive image update included within 4.4 and there’s some functions and hooks included: https://make.wordpress.org/core/2015/11/10/responsive-images-in-wordpress-4-4.

  • I have been using a function that bridged ACF and the RICG Responsive Images plugin. I went ahead and adapted that to WP 4.4.

    function _acf_ricg_image($image, $alt='', $class = '', $size='full') {
    
    	if (!empty($image)) {
    		if (!$alt) {
    			$alt = $image['alt'];
    		}
    				
    		$url = $image['url'];
    		
    		if ($size) {
    			if (isset($image['sizes'][$size])) {
    				$url = $image['sizes'][$size];
    			} 			
    		}
    		
    		if (function_exists('wp_get_attachment_image_srcset')) { 
    			$img = '<img src="'. $url . '" srcset="' . wp_get_attachment_image_srcset( $image['id'], $size ) . '" alt="' . $alt . '"';
    		} else {
    			$img = '<img src="'. $url . '" alt="' . $alt . '"';
    		}
    		
    		if ($class) { 
    			$img .= ' class="' . $class . '"';
    		}
    		$img .= ' />';
    		
    		return $img;
    	}	
    }

    Then in my template I use:

    <?php if (get_field('slide_image')) { echo _acf_ricg_image( get_field('slide_image')); } ?>

    There has to be a better way to do it, but I haven’t had time to look into it yet. Will update this thread if I come up with something better.

  • This isn’t a catch all way — still requires editing your template and potentially your fields. But the real solution is much simpler than the function I was previously using. Use ID as the return type on your images:

    <?php echo wp_get_attachment_image(get_sub_field('image'), 'full'); ?>

    (h/t Joe McGill for pointing me in the right direction.)

  • Hi timstl.

    Thanks for posting this up! I’m going to have a play with this. I guess asking for a catch-all solution is unlikely as at the end of the day, the older markup on a template level will probably restrict being able simply patch everything site-wide.

    I’ll give the snippet in your last post a go and I’ll report back 🙂

  • Again, I’m sure this could be improved upon but here’s what I’ve ended up with.

    <?php 
      $image = get_sub_field('image_field_name');
      $imageID = $image['ID'];
      echo wp_get_attachment_image( $imageID, 'full', false, array( 'class' => 'lazyload', 'data-sizes' => 'auto' ) );
    ?>

    This works for images that are set to return the image array (this is how all my fields are currently set up). I’ve included the lazysizes jquery plugin (https://github.com/aFarkas/lazysizes) on my site which will lazyload images and update the image’s sizes attribute to match its container rather that what WordPress seems to be doing by default which seems to be an arbitrary value.

  • OK, only one issue I can see is with images inserted through the WYSIWYG editor. These don’t seem to get parsed in the same way as images inserted into the regular WP post editor.

  • I think it would be possible to parse the HTML from the editor on load and replace the image tag with one that includes srcset, but that seems like a poor solution. In addition to being a pain to code, you probably don’t want a preg_replace running every page load on every WYSIWYG field.

    Hopefully ACF issues an update that will start including srcset in img tags when they are added to the WYSIWYG editor on the admin side.

    Regarding your snippet above, I would return the image ID instead of array whenever possible. Again, per Joe McGill’s recommendation, it will be faster. Not the end of the world, but if possible might as well speed it up.

  • I found a solution so that ACF creates the correct code from a WYSIWYG field. You only have to add

    add_filter( 'acf_the_content', 'wp_make_content_images_responsive' );

    to your functions.php. I hope Elliot will add this direct into the code, so that ACF filters the WYSIWYG content like WP does.

    For the image field this code works for me:

    $image = get_field('my_image');
    $img_src = wp_get_attachment_image_url( $image['id'], 'full' );											$img_srcset = wp_get_attachment_image_srcset( $image['id'], 'full' ); ?>
    											<img src="<?php echo esc_url( $img_src ); ?>"
    	width = "<?php echo $image['sizes']['Stripe-width']; ?>"
    	height = "<?php echo $image['sizes']['Stripe-height']; ?>"
    	srcset="<?php echo esc_attr( $img_srcset ); ?>"
    	sizes="(max-width: 100vw) 480px" alt="<?php echo $image['alt']; ?>"
    >
  • Thanks for the updates guys.

    Will have a play and report back.

    EDIT:

    Thomas, your filter for acf_the_content worked perfectly!

  • I talked to Elliot and he will include the additional filter for acf_the_content into the next version of ACF.

  • Hi,

    This looks like it is exactly what I’m trying to do but I can’t seem to get it to work. I’m not a very experienced code writer. Sorry for that 🙂

    I have added timstl’s function-code to my function.php and then in my template added:

    <div class="wrapper">
    	<div class="wrapper2">
    	<img class="bilder2" src="<?php echo wp_get_attachment_image(get_sub_field('hero_image'), 'full'); ?>					    						</div>
    </div>

    Also I have changed the field to return image ID. But it doesn’t seem to work for me.
    Anyone who could point me in the right direction?

  • wp_get_attachment_image(get_sub_field('hero_image'), 'full');

    This will output the entire img tag w/ the srcset, so you do not need to include the img in your template.

    <div class="wrapper">
    	<div class="wrapper2">
    	<?php echo wp_get_attachment_image(get_sub_field('hero_image'), 'full'); ?>					    						</div>
    </div>

    If you need to add a class to the img, you can pass an array into the function (see: https://codex.wordpress.org/Function_Reference/wp_get_attachment_image).

    <?php echo wp_get_attachment_image(get_sub_field('hero_image'), 'full', 0, array('class' => 'bilder2')); ?>

  • Thank you so much! That took me somewhere!

    However the resizing of the images doesn’t seem to work properly. The images seem to be stuck at a low resolution. Have I missed something?

    http://www.tor-bjorn.com/works/human-nature

  • Quick note on your site tor2dbear, your CSS is resizing the image to max-height: 100vh; which is distorting your image. I’d put the image inside a container which has the property height: 100vh; and then set your image as the background-image and set the background-size to cover and background-position to center. This will then not distort your image but note that this wont work in older browsers (IE 9+ will be fine: http://caniuse.com/#search=background-size).

    Like this: http://codepen.io/nathobson/pen/bEeWEZ

  • Thank you for the feedback NatHobson. Something (cant’t remember what) was broken on that page. I haven’t implemented your code but the distortion is no longer there.

    However, I’m still struggling to get a smaller size image to load. I have been playing around with the sizes-property but I’m starting to doubt that’s actually the issue here. I can see that the different image sizes is “loaded” under img scrset but the browser doesn’t seem to be able to access them.
    What am I missing?

    http://www.tor-bjorn.com/works/human-nature

  • I just took a look at your site and it appears that my browser is loading the correct image based on image screen size.

    A not about the way browsers have implemented srcset. The browser will only make one request for one image that matches the current screen width. If you resize your browser after this it will not request another image. If you resize your browser and then force a page refresh it will get the image that matches the new screen width.

  • Okay! I feel like a fool 🙂 That explains why me playing around with sizes in the Developer Tool didn’t change a thing.

    Right now this is the values that I have for sizes
    sizes="(max-width: 1920px) 100vw, 1920px"

    I’m still trying to get my head around how the “break points?” actually work but I guess this is the reason why it’s either the 800×533 or the full size (1920) image that is being loaded?
    Where in my code would I be able to customize this? The image size is always 75% so if I understand it correctly that should be my value for sizes?

    Much appreciate all of the help!

  • If you take a look at one of my earlier replies, you should see my comments on how I’ve handled the sizes property:

    I’ve included the lazysizes jquery plugin (https://github.com/aFarkas/lazysizes) on my site which will lazyload images and update the image’s sizes attribute to match its container rather that what WordPress seems to be doing by default which seems to be an arbitrary value.

  • @tor2dbear no reason to feel like a fool. When I first started dealing with responsive images Chrome had implemented it natively and it worked this way but Firefox had not yet and I needed to add picturefull.js to the site for it to work. There were some hours of frustration trying to work out why it was working in Firefox and not Chrome… until I happened upon an article about Chrome that explained it.

  • Thank you for replying NatHobson!

    I’m not really sure I understand exactly how the lazysizes-plugin works/will help me but I trust you do 😉 Will it handle the sizes attribute for me?
    Right now I’m using this wordpress plugin for lazy load that I found works for custom fields which I then guess I won’t need anymore?
    https://sv.wordpress.org/plugins/lazy-load-enhanced/

    Right now the code I use to load the image field looks as follows:
    <?php echo wp_get_attachment_image(get_field('hero_image_3'), 'full', 0, array('class' => 'bilder2')); ?>

    I can’t figure out how to implement the code you provided in order for it to work on my website. The ID parameter is not in the code I use right now. Am I right thinking this is the issue?

  • I have used wp_get_attachment_image_src to display my images – I’m doing it this way as I need to use the image’s caption (post_excerpt) as my ‘alt’ content. Frustratingly (for me with limited experience!) timstl code works only when using wp_get_attachment_image. With this in mind how would I change timstl’s snippet so it works form me also? Here’s what I’m working with…

    <?php if(get_field('post_images')): ?>
    		<?php while(the_repeater_field('post_images')): ?>
    			<?php 	$image = wp_get_attachment_image_src(get_sub_field('post_image'), 'large');
    					$largeImage = wp_get_attachment_image_src(get_sub_field('post_image'), 'full');
    					$attachment_id = get_post_thumbnail_id($post_id); ?>
                <li <?php  the_sub_field('module_class');?>>
                <a href="<?php echo $largeImage[0]; ?>" title="<?php $attachment = get_post($attachment_id); echo($attachment->post_excerpt); ?>">
    	    	<img src="<?php echo $image[0]; ?>" alt="<?php $attachment = get_post($attachment_id); echo($attachment->post_excerpt); ?>" /></a></li>
    	    <?php endwhile; ?>
    	</ul>
    		<?php endif; ?>
  • Just wondering if people have yet considered how to setup ACF to use responsive images to their full intention/potential.

    By that I mean – different crops of images (or different images entirely) for different viewports (as opposed to just WP image sizes / auto crops).

    I’m thinking something like multiple ACF Image Fields (Mobile Image, Tablet Image, Desktop Image) – that have their own WP image size, and output a responsive image tag with the different sources.

    Anyone have other ideas?

    EDIT: see http://support.advancedcustomfields.com/forums/topic/acf-responsive-image-field/

  • This reply has been marked as private.
  • Yes, I have, but for me that means disabling the built in responsive images of 4.4. It will only return alternates of the same image that are different sizes but a different ratio and the builders of the plugin and function that have been incorporated into WP do not include any way to filter or alter the images uses in the srcset.

    I have brought it up both before the release of 4.4 when it was being discussed and as an issue on trac after the release and this was met by either my comments being deleted or just ignored.

    Anyway, the way to do this is that when editing an image you can select alternate images (acf image fields attached to attachments) that will be used at different screen widths. These could be the same image cropped at a different ratio or a completely different image. Then build your own srcset using these values. You’ll need to disable wp filter added to “the_content” add your own and build a new function that works pretty much the same way as the WP function but also takes the custom field choices into account.

  • Well I think if WP haven’t enabled the ability to use responsive images properly (their solution seems more like a RWD CSS media query solution) then disabling the built in functionality would be the only way to go.

    And adding the ACF image fields to the attachments seem an obvious and good place for them.

Viewing 25 posts - 1 through 25 (of 31 total)

You must be logged in to reply to this topic.