Adaptive Images in ExpressionEngine With CE Image

by {"name"=>"Aaron Gustafson", "twitter"=>"AaronGustafson", "googleplus"=>"AaronGustafson"} on 21 November 2014

One of the biggest headaches of responsive design has been dealing with images. Thankfully our work on the Responsive Images Issues Community Group has resulted in a rock-solid set of elements and attributes to address all of your adaptive image needs. My company, Easy Designs, recently redesigned Nichols College’s website and that project just happened to coincide adaptive images landing in Blink (the rendering engine that powers Chrome and Opera). Naturally, we jumped at the opportunity to use them.

Most Nichols College sites run on EllisLab’s ExpressionEngine, a solid little workhorse of a CMS we’ve been using for years. We love it because it gives us complete control over the markup it generates. Now EE offers some pretty decent file management and image manipulation utilities out of the box, but the options it provides were not enough to handle our adaptive image needs; we needed backup. Causing Effect’s CE Image add-on is reasonably priced and offered exactly the functionality we needed to make our adaptive image dreams a reality.

I won’t bore you with how to set up CE Image as there is documentation on that, but I will walk you through two different responsive image use-cases we had and how we addressed them using this add-on.

Header images

The first use case we had was a series of large, focal images. You can find different examples of them on the homepage and landing pages (like this one for Admissions). The first pass on making these images adaptive involved the picture element for which the spec is known. The markup we were generating was based on the pattern outlined for Picturefill, a JavaScript polyfill that implements adaptive images in browsers that don’t do it natively:

To get to that point, however, we needed to use CE Image to generate (and cache) the specific sizes we needed:

Not what’s a lot of code, so let’s just look at one segment of that jumble:

This is an example using CE Image’s tag pair option, which lets you control the markup output. In the opening tag, we set several properties:

Then, within the tag pair is the source element with the srcset value set to the path to the file CE Image generated (referenced by the made variable) and the associated media query.

Multiply that a few times for the different sizes and you have the full picture element.

Now that’s all well and good, but shortly after launch, Eric Portis wrote an amazing post explaining how the srcset and sizes attributes operate and it cleared up a lot of my confusion on the matter. He convinced me that the age-old img element, with these new attributes, would be far more maintainable. With a fire in my belly, I rewrote the markup:

The CE Image behavior is exactly the same, but the resulting markup is much clearer:

The added bonus of this approach is that I am not hard-coding any media queries and the browser gets to make the ultimate decision of which image to request. All I am doing is telling the browser the image options and their respective widths within the srcset attribute. As all of the images take up 100% of their containers, I didn’t even need to use the sizes attribute. Easy peasy.

“Nice to Have” Images

Not every image adds something to the page. Some are purely optional, a visual enhancement. In order to reduce the size of pages on smaller screens, we often choose to “lazy load” certain image assets after page load, when we know there is enough room to display the image or when we feel it would be an enhancement to the design.

Now some of you might be wondering: Why not just display:none below a certain threshold? Well, I’ll tell you: images that are hidden with CSS are still requested by the browser. That means users who don’t see the images are still paying to download them (whether in terms of time waiting for the page to render or actual money on a metered connection). That kinda sucks for them. We should show our users a bit more respect and only request the images when we need them.

We wrote a lazy-loading image script a few years back and have battle tested it on numerous sites to great success. It’s all based on a simple markup pattern:

The data-img-src attribute defines the path to the “nice to have” image and then the JavaScript adds the image element into the page when the appropriate conditions are met:

Pretty simple. It even supports srcset:

The full documentation is up on Github.

Implementing this in the context of CE Image was a breeze and builds on the source pattern I showed earlier:

We are only just beginning to scratch the surface of what’s possible with adaptive images and I am sure we will come up with newer, better ways to do this stuff. Heck, there may even be an adaptive images add-on in the pipeline for ExpressionEngine. But, in the meantime, if you are trying to implement adaptive images with ExpressionEngine, CE Image is a good way to go.