Jump to content

Responsive Images


Oliver
 Share

Recommended Posts

Because I’ve never been really happy with the current strategies (I know) to deliver images the right solutions in responsive layouts, I lately started to work on my own approach. Other solutions like for example Wilcox’ Adaptive Images just rely on the screen resolution/window size or require additional (and manually added) data attributes or even js/noscript hacks in the markup.

For me it was important to have a solution, that is installed once and then just works. So I took some ideas from other stratgies and put something together that seems to work so far (but I still have to test it in older browsers). Feel free to give it a try. I’d love to get some feedback on this. For detailed info have a look at the README.

https://github.com/oliverwehn/Responsive-Images

  • Like 4
Link to comment
Share on other sites

Because I’ve never been really happy with the current strategies (I know) to deliver images the right solutions in responsive layouts...

Hi, Hopefully if I understand you correctly, you are looking for a way to have truly responsive images that resize to any screen size?

I use this:

img {
    height: auto;
    max-width: 100%;
    width: auto;
}
 

In your html for the <img> omit the width and height attributes and you should end up with something like in these examples below. Just resize your browser.

Example 1 Responsive images (in progress, so temporary link)

Example 2 Responsive slideshow

I hope I have not misunderstood your intentions?

  • Like 1
Link to comment
Share on other sites

Oliver,

Thanks for posting this. I have also been tinkering with different strategies for responsive design. I was about to start a similar discussion about it, then I saw this.

With ProcessWire, we have an opportunity to dream up new/different kinds of logic to handle responsive elements -- not just images but everything in an application. I am playing with ideas of rendering pages in certain ways, in certain combinations, rendering some parts/pages but not others -- using the elegant traversal methods available to us in ProcessWire.

It's pretty exciting. ProcessWire is already deeply impressive. If we can showcase ways to use ProcessWire to handle responsive design, that would really get some attention!

I'll take a closer look at your plugin. Generally, I would be very interested in discussing ways we can do this.

Thanks again,

Matthew

  • Like 1
Link to comment
Share on other sites

@NooseLadder, Your css approach is nice (also the one I use), but it serves the same image to every screen. What I think Oliver wants to achieve is serving different images depending on the screen, so people don't download images bigger than what's really needed.

Link to comment
Share on other sites

Of course, this also depends what framework you are using.

For instance, if you use the Crop image field and then associate that with Bootstrap, you can specify using different thumbnails for different media queries. In addition, you can add classes in Bootstrap to either show or not show elements for various devices. (Other frameworks have similar approaches)

Mixing and matching this way allows not only different sizes, but because of using the crop image, you can also change the area of the image viewed. So on the desktop the thumbnail image might be a landscape, but on a phone where that would bad, you would have a close up of one distinctive element in the image. 

It has been one of the joys of the Thumbnails plugin that I can easily spend time thinking about not just what size an image should be, but also the context - whether that is in relation to the surrounding text, or the size of the browser.

  • Like 1
Link to comment
Share on other sites

You all seem to mix up responsive layout with adaptive images. This is about adaptive images, which is something different.

Well, it is about adapting the images to the viewport, which is strongly related to responsive layouts. 

I have always felt that it is not just about file size (though with more 4g licences granted today in the UK, that will slowly become less of an issue), but about how the image works a design sense as well. 

If the up side of responsive layouts is their adaptability to the viewport, the downside is that does not necessarily mean that the "adjusted" layout is the best use of the smaller viewport.

Adapting the image both in physical dimensions and in chosen portion is one step towards getting that better.

Now I have to run off and rewrite half of my blog system to practice what I have just preached ....  damn!!

Link to comment
Share on other sites

Responsive images is what makes them behave inside the layout once the html, css and images are loaded, so all this max-width etc.

Adaptive images is serving a resolution before it's loaded to fit screen size or bandwidth or whatever to not load unnecessary big images that wouldn't be needed for mobile for example.

Oliver's solution is about adaptive images as far as I understand.

Though yes it's arguably that the term can mean the same thing, but I thought it's how we make the difference in case of image delivery. 



Because I’ve never been really happy with the current strategies (I know) to deliver images the right solutions in responsive layouts, I lately started to work on my own approach. Other solutions like for example Wilcox’ Adaptive Images just rely on the screen resolution/window size or require additional (and manually added) data attributes or even js/noscript hacks in the markup.

For me it was important to have a solution, that is installed once and then just works. So I took some ideas from other stratgies and put something together that seems to work so far (but I still have to test it in older browsers). Feel free to give it a try. I’d love to get some feedback on this. For detailed info have a look at the README.

https://github.com/oliverwehn/Responsive-Images

Wilcox's solution doesn't require that much as you say, it's .htaccess with a cache folder, a script in head and you're done, no data-attributes required. I've used it and am quite happy with it. But will take a look at yet another solution if I got time. :) Thanks for sharing Oliver.

  • Like 1
Link to comment
Share on other sites

I called it “responsive” because the strategy doesn’t adapt the resolution once to a fixed value like screen/window size. The javascript part of my solution uses the actual styled layout context the image element will be rendered in to determine the adequate image size. Also it is able to load a higher resolution image later on window resize or orientation change (if you want it to). As it is therefor more “active” and “event-driven” than e.g. Adaptive Images, I thought “responsive” would be more accurate.

Link to comment
Share on other sites

Oliver, your solution looks pretty impressive. I think I found a small gotcha, admittedly an edge case: I visited your blog with JS on, the cookie got set, and the rest of the script worked its magic. So far, great. Now if I disable javascript, and reload the page, I'm only seeing the loading image, probably because the cookie is set and you did not account for this (rather unusual, I know) scenario: cookie set, JS off.

If I delete the cookie and keep JS off, the fallback (i.e. nothing happens and the fallback image is loaded), everything works expected.

A couple of other observations:  

  1. You mention on Github that "To keep the number of cached files low, the width value will be ceiled to match a multiple of a predefined pixel interval." How does that work? How many versions of the same image are typically generated and cached?
  2. Google says that some proxies do not cache assets with a query string. I wouldn't too worried about it as it probably affects a very small number of users. But what do you think?
Link to comment
Share on other sites

Thanks for your feedback on this. Even if the case you describe (cookie set and js disabled afterwards) is very unlikely to happen–if not intended–, I’ll try to set a very short expiration time for the cookie. I guess, that’s the only thing that might work here.

Regarding your question about the “predefined pixel interval”: You can set the interval as an option of the jquery plugin, when you call it on the matched images. Let’s say you set it to 50, the plugin will set the image sizes by determining the nearest higher multiple of 50. So if the needed image size is 710, 725 or 745 pixels, a 750 pixel cache image will be served. Setting the interval lower will lead to some saved kilobytes in bandwidth and to a lot more cache files. Setting it higher will save you disk space but may cause more traffic on image delivery.

I’m aware of the cache issue. To optimize that, I plan to append the parameters to the file name and change the url rewrite to take care of them. Currently the solution just takes care of providing a unique url for each image even if the query string is ignored/cut off when its cached.

Link to comment
Share on other sites

  • 1 year later...

I placed the different files and code snippets as follows:

  • responsive-images.php: /site/
  • 'sample' folder: /site/

.htaccess

<IfModule mod_rewrite.c>

  RewriteEngine On
  AddDefaultCharset UTF-8

  # ======================================================
  # https://github.com/oliverwehn/Responsive-Images
  # START ================================================

  RewriteRule \.(?:jpe?g|png|gif)$ responsive-images.php [QSA,L]

  # ======================================================
  # https://github.com/oliverwehn/Responsive-Images
  # END ==================================================

Javascript:

<?php
// Path to javascript files.
$jsPath = $config->urls->templates . 'styles/js/';
?>

<script>
      document.cookie='responsive=1';
</script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="<?= $jsPath . 'jquery.responsiveimages.min.js' ?>"></script>

However, the plugin does not seem to do anything. The cache folder is also empty.

I remember Processwire not allowing the execution of php files outside the site folder. Could that be the issue here?

I like the idea behind this plugin and I really want to see it in action. Any suggestions are highly appreciated!

Cheers,

Stefan

EDIT: I would love to see an implementation of this plugin in the wild. Can anyone send me a link?

Link to comment
Share on other sites

Hi Stefan, thanks for giving it a try! Hopefully I can help you with getting it to work. I implemented a lot of improvements since this post was created back then.

So, let’s have a look.

Usually I put responsive-images.php into the site root or the same level where the .htaccess is placed. As you would have to adjust some path settings in .htaccess and responsive-images.php, I recommend to stick to putting responsive.php into the root folder of your PW setup.

The sample folder can be ignored. It’s just an example page where the setup is tested.

If the script path is correct in your template, you have to address the images you want to be managed by the jQuery plugin. 

$(function() {
  // take care of all images
  $('body').responsiveImages({
    respondToResize: true, // if you want to load other image sizes on resize,
    respondToUpscaleOnly: true, // load other sizes only on upscale
    resolutionInterval: 50, // load image size of closest multiple of 50px (rendered 430px -> load 450px)
    imgSelector: 'img', // if you want to be more selective, change it
    loadingClass: 'is-loading', // add a class to img while loading
    callOnUpdate: null, // optional callback when images are updated
    callOnEach: null, //optional callback called for each images after loading
    debug: false // set to true to enable console output
  });
});

Try it and let me know if it works.

BTW: This site uses my plugin: www.bildbau.net.

Link to comment
Share on other sites

Oliver,

Thanks a lot for your detailed description.

After adding the function call to responsiveImages  inside the <head> section, the following happens:

  • The images do not load
  • Each image tag gets a class 'image-loading' attached, and the src attribute is not there anymore.
  • I get  404 (page not found) errors for every image. The image names in the error message are given with layout-specific image dimensions that were attached by the plugin, such as <original image name>s1366.p1300.r1.jpg?141050308

I did not delete the folder named sample that was part of the code on Github, which means it is still located in the root folder (same level as .htaccess). Permissions seem to be correct, with read and write access for owner and group, so I suppose Processwire does not allow access to that folder, but I am not sure.

I attached my complete .htaccess file. Maybe you can find something interesting there.

Cheers,

Stefan

htaccess.txt

Link to comment
Share on other sites

I moved the folder sample inside the templates folder and referenced it as follows:

/responsive-images.php

define('PATH_CACHE', dirname(__FILE__) . '/site/templates/sample/images_cache');
/**
 * PATH_PLACEHOLDER: placeholder image to be delivered before replacement
 * url
 */
define('URL_PLACEHOLDER', SITE_URI . '/site/templates/sample/images/transparent.gif');

However, it still doesn't work. I also noticed that Processwire is looking for the images in the assets folder, whereas I thought they would be placed inside the images_cache folder of this plugin:

GET http://localhost:8080/processwire/site/assets/files/1277/desert-rig_-_rig_18_033.440x295.s1366.p400.r1.jpg?141050775 404 (Page Not Found)

I hope this information might be helpful.

Cheers,

Stefan

Link to comment
Share on other sites

If you just want to try the sample, you can clone the repo to any directory within your local web server folder without changing anything.

But if you want to use Responsive Images with your PW setup you should change the path settings in responsive-images.php to:

define('PATH_CACHE', dirname(__FILE__) . '/site/assets/cache/images_cache'); //

/**
 * PATH_PLACEHOLDER: placeholder image to be delivered before replacement
 * url
 */
define('URL_PLACEHOLDER', SITE_URI . '/site/templates/img/transparent.gif'); //or whereever you want to put the gif

The cache dir will be created by the script.

The .htaccess rewrite rule should be added to the .htacces in your PW root, where the responsive-images.php is located, too. 

Link to comment
Share on other sites

I changed the path as you said:

 * SITE_PATH: Document root file system path
 * SITE_URI: URI from document root
 */
define('SITE_PATH', rtrim(dirname($_SERVER['SCRIPT_FILENAME']),'/'));
define('SITE_URI', rtrim(dirname($_SERVER['SCRIPT_NAME']), '/'));
/**
 * PATH_CACHE: directory where resized image versions are stored
 * file system path
 */
define('PATH_CACHE', dirname(__FILE__) . '/site/assets/cache/images_cache');

Unfortunately, I still get the same error messages. Also, there is not folder images_cache created in /site/assets/cache. I checked the permissions, owner and group have create and delete rights.

.htaccess and responsive-images.php both are located at the root.

Why is it that Processwire is looking for these images in /site/assets/files?

Cheers,

Stefan

Link to comment
Share on other sites

Could it be that responsive-images.php never gets called? I placed an echo statement at the top of the file, but there is no output.

This may not be an indicator - try:

error_log('reponsive-images.php called');

and see if that appears in your php error log.

Link to comment
Share on other sites

I placed you code at the top of responsive-images.php, reloaded the page and checked /site/assets/logs/errors.txt - but there was no new entry.

So I guess the file never got called. Now I wonder why that is.

Cheers,

Stefan

EDIT: Sorry, I only just realized you meant the Apache error_log file. I looked there, too, but there was not such entry, either.

Link to comment
Share on other sites

error_log won't send anything to the PW error log. They will go to the php error log. If you are using commercial hosting with cpanel there should be an error log you can view. If you are running a setup on a Mac, this command in terminal will get you the last 50 lines of your error log: 

tail -50 /var/log/apache2/error_log

 although it is possible the path may be different.

If you bootstrap that file to PW you could also do one of the following (https://processwire.com/talk/topic/3768-processwire-dev-branch/#entry36787):

$log->message("This saves this line to messages.txt"); 
$log->error("This saves this line to to errors.txt");

and those will send messages to /site/assets/logs/

Hope that helps.

Link to comment
Share on other sites

 Share

×
×
  • Create New...