Monkey Do

An Event Apart and The <Picture> Element

At the end of last week, we posted a fresh update to An Event Apart, including a lot of new copy and layout on the homepage and other minor changes to design elements that appear throughout the site.

As a part of the refresh, we also wanted to improve the display of the larger photos we use throughout the site. A primary problem was that the image and tagline often ended up in awkward juxtaposition in smaller screen sizes. Secondly, we needed the ability to serve the right image resolution and size to the various devices that people use to access the site.

With all the talk around the emergence of the <picture> element as a possible solution, it occurred to us that this might be the perfect test case to see how it worked.

Of course, there’s a catch: there is no native browser support for <picture> at this time, so we turned to the Picturefill responsive image script developed by the Filament Group.

In the prior design, the main image was a 1188x360 photo that scaled as a background image in a container. The background-size: cover property was used to ensure that the image scaled and cropped to the size of the container. This meant that every breakpoint in the design, the image fit well within the layout.

In the original designs the art direction was different, featuring a single speaker placed approximately 2/3 to the third in the composition. This meant that at the smallest size, the speaker would occupy the right side of the image container while the tag line was left-aligned. Just before that design was launched, however, the decision was made to use photos of event attendees instead, which meant that the tag line often obscured (or somewhat awkwardly juxtaposed) the subjects of the photo.

Using <picture> means we now have more control over how the image fits into the container. The first part of the process was to decide just which images we need to serve.

The image container responds to one major breakpoint in the design: at 600 pixels and above the container switches from 300 to 360 pixels tall. This was the breakpoint to build our image library around.

Since the photo is centered inside the container, the maximum size needed for this breakpoint is 600x300. For viewports wider than 600 pixels, we’ll switch to the 1188x360 photo. We’ll also create 2x versions of the images for HiDPI displays, requiring the addition of 1200x600 and 2376x720 images.

The large default image.
An image for screens smaller than 600 pixels wide.

(Interestingly, the 2x images are approximately the same byte size as the 1x files, since we followed the thinking of Daan Jobsis in his Retina Revolution article, and compressed the 2x images quite a bit more than the 1x variants.)

Then, we set up a custom field in ExpressionEngine that allows us to define the set of images that get referenced in the corresponding srcset definitions, along with a caption for the image set.

Image variants in Expression Engine.

The default image size of 1188x360 is referenced in the tag, and it becomes a fallback image for users without JavaScript. ExpressionEngine inserts the appropriate references into the srcset definitions for the smallest media query and our (min-width: 600px) media query.

<picture class="eventImage" data-credit-title="{photo:title}" data-credit-name="{photo:author}" data-credit-location="{photo:location}">
	<!--[if IE 9]><video style="display: none;"><![endif]-->
	<source srcset="{photo}{url}{/photo} 1x, {photo_large_2x}{url}{/photo_large_2x} 2x" media="(min-width: 600px)">
	<source srcset="{photo_small}{url}{/photo_small} 1x, {photo_small_2x}{url}{/photo_small_2x} 2x">
	<!--[if IE 9]></video><![endif]-->
	<img src="{photo}{url}{/photo}" alt="{photo:title}">

For a full explanation of the <picture> syntax, including the conditional comments, see the Picturefill documentation.

The final piece of the puzzle for An Event Apart specifically was to make the images center themselves as the window resizes, rather than resizing proportionately. A couple of CSS rules for the img tag takes care of that, using absolute position and the transform property.

.eventPhotos img, .eventHero img {
	height: 100%;
	width: auto; 
	max-width: none;
	position: absolute;
	left: 50%;
	-webkit-transform: translate(-50%, 0);
	-moz-transform: translate(-50%, 0);
	-ms-transform: translate(-50%, 0);
	-o-transform: translate(-50%, 0);
	transform: translate(-50%, 0);

.lt-ie9 .eventPhotos img {
	margin-left: -594px;

For Internet Explorer 8 and below, we’re using a pixel-based negative margin as a fallback to the transform. The srcset images don’t seem to load in IE8, and as a matter of progressive enhancement we’re not too worried about optimizing the image and tagline layout in those use cases.

The result is a much nicer small-screen composition. In the new layout, we’ve pulled back the crop in order to get the attendees’ faces up higher in the frame, and also re-centered the crop so that they stay centered on the smallest view.The flexibility of <picture> element allows us to create a much better juxtaposition of tagline and photo.

The old layout. Now with <picture>!
The old layout. The old layout. <>> The old layout. Now with <picture>!
The old layout. Now with <picture>!