Coding & Design

All about coding and designing for the web — from HTML, jQuery and CSS to the deep recesses of the art of coding.

Responsive Photosets

Terry Mun
Coding & Design
Published in
13 min readDec 15, 2013

--

The requirements

HTML markup

<div class="photoset">
<div class="photoset-row">
<figure class="photoset-item">
<a href=""><img src="" alt="" title="" /></a>
<figcaption></figcaption>
</figure>
<!-- multiple images per row is possible -->
</div>
<!-- Additional rows are possible -->
<div class="photoset-row">
<!-- more photoset items -->
</div>
</div>
.photoset {
overflow: hidden;
width: 100%;
}
/* Rows */
.photoset .photoset-row {
margin-bottom: .5rem;
overflow: hidden;
width: 150%; /* See comment after code for reason */
}
.photoset .photoset-row:last-child { margin: 0; }
/* Images on each row, known as an "item" */
.photoset .photoset-item {
display: block;
float: left;
margin: 0 .25rem;
}
.photoset .photoset-item:first-child { margin-left: 0; }
.photoset .photoset-item:last-child { margin-right: 0; }
/* Images and captions are contained within <figure> */
.photoset figure {
margin: 0;
overflow: hidden;
position: relative;
width: 100%;
height: 100%;
}
.photoset figcaption {
background-color: rgba(255, 255, 255, .75);
box-sizing: border-box;
font-size: .75rem;
padding: .5rem;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
-webkit-transform: translateY(100%);
transform: translateY(100%);
transition: all .5s ease-in-out;
}
.photoset a:hover figcaption {
-webkit-transform: translateY(0);
transform: translateY(0);
}
.photoset img {
display: block;
max-width: 100%;
transition: all .125s ease-in-out;
}

Width exceeding 100% prevents floats from wrapping

jQuery coming to the rescue

Mathematical basis

There is only one variable to be computed.
The rest are relative.

Simple example of two images. The total width can be easily calculated with known aspect ratios.
A slightly more complicated scenario involving fractional aspect ratios.

Wait for DOM to get ready

// Functionality for calculations
// and event binding can be done on DOM ready
$(function (){
// Rest of the code goes here
});
// Trigger the actual calculations when resources are loaded
$(window).load(function (){
// Trigger resize event to perform calculations
$(window).resize();
});

Store original image dimensions in data objects

// Store original image dimensions
$('.photoset-item img').each(function () {
$(this).load(function (){
$(this)
.data('org-width', $(this)[0].naturalWidth)
.data('org-height', $(this)[0].naturalHeight)
.css({ opacity: 1 });
});
});
 // Store original image dimensions
$('.photoset-item img').each(function () {
var img = new Image();
$(this)
.data('org-width', img.width)
.data('org-height', img.height)
});

Listen to resize event

$(window).resize(function (){
// Perform calculation for each row independently
$('.photoset-row').each(function() {
// Rest of the code here
});
});
// Declare some variables
var $pi = $(this).find('.photoset-item'),
cWidth = $(this).parent('.photoset').width();
// Generate array
var ratios = $pi.map(function() {
var orgWidth = $(this).find('img').data('org-width'),
orgHeight = $(this).find('img').data('org-height');
return orgWidth/orgHeight;
}).get();
// Sum aspect ratios
var sumRatios = 0,
minRatio = Math.min.apply(Math, ratios);
for (var i=0; i<$pi.length; i++){
sumRatios += ratios[i]/minRatio;
}
// Sum all horizontal margins
var sumMargins = 0;
$pi.each(function (){
sumMargins += parseInt($(this).css(‘margin-left’)) + parseInt($(this).css(‘margin-right’));
});
// Calculate dimensions
$pi.each(function (i){
var minWidth = (cWidth-sumMargins)/sumRatios;
$(this).find('img')
.width(Math.floor(minWidth * (ratios[i] / (Math.min.apply(Math, ratios)))))
.height(minWidth / Math.min.apply(Math, ratios));
});

It is safer to underestimate the width of individual items

Extending into a WordPress theme function

Basic design principles

[photoset id="12,15,17,26,46,45" layout="1,3,2"]

The code

Much more to yearn for

Further improvements

Closing note

--

--

Coding & Design
Coding & Design

Published in Coding & Design

All about coding and designing for the web — from HTML, jQuery and CSS to the deep recesses of the art of coding.

Terry Mun
Terry Mun

Written by Terry Mun

Amateur photographer, enthusiastic web developer, whimsical writer, recreational cyclist, and PhD student in molecular biology. Sometimes clumsy. Aarhus, DK.

Responses (1)