Some ideas on responsive jQuery slideshows

Some ideas on responsive jQuery slideshows

I'm currently testing some new ideas for creating responsive jQuery slideshows for mobile devices.

The main problem with responsive jQuery slideshows is the calculation process of the dimensions of each slide. Using CSS Media Queries is useful only to set the dimensions of the outermost containers but it's rather unpractical when it comes to define the dimensions of each slide, especially when you don't know in advance how much content will be hosted within your slideshow.

The most used CSS technique to get a responsive width is as follows:


#slideshow {
	width: 100%;
	max-width: 960px;
}

Now our slideshow can be 960 pixel wide only if the browser's viewport is large enough to make it stretch to that maximum width. In all other cases, our container will be as wide as the browser's viewport.

Then we come to the problem of the maximum height and image ration. A slideshow whose images are 960 x 400 pixels wide cannot be viewed on a mobile device without adjusting its dimensions. We could detect mobile devices with jQuery and resize the images:


if(window.orientation) {
	$(window).on('orientationchange', function() {
		var mode = window.orientation;
		switch(mode) {
			case 0:
				// portrait
				// resize for portrait mode
				break;
			case 90:
			case -90:
				// landscape
				// resize for landscape mode
				break;
			default:
				break;
		}
	});
}

This is an expensive solution but it's not enough: we also need to resize the innermost container of the slides to make it wrap the slides and their images:


// after resizing the slides
var totalWidth = $('div.slide:first', '#slideshow').width() * $('div.slide', '#slideshow').length;
var totalHeight = $('div.slide:first', '#slideshow').height();

$('#slide-wrapper').css({
	width: totalWidth,
	height: totalHeight
});

Does another solution exist? Yes, but it's totally experimental:


<div id="slideshow">
	<div id="slide-wrapper">
		<div class="slide" data-img="img/1.jpg">
			<img src="img/1.jpg"/>
		</div>
		<div class="slide" data-img="img/2.jpg">
			<img src="img/2.jpg"/>
		</div>
		<div class="slide" data-img="img/3.jpg">
			<img src="img/3.jpg"/>
		</div>
	</div>
</div>

We can remove the img elements from the slides so that we can use them as background images by taking advantage of the CSS background-size property set to cover. With this value the proportions of the images won't be broken when we change their dimensions:


// only for mobile

$('div.slide').each(function() {
	var $slide = $(this);
	var $img = $('img', $slide);
	var bgURL = $slide.data('img');
	$slide.css('backgroundImage', 'url(' + bgURL + ')');
	$img.remove();
});

And in our CSS:


@media screen and (orientation:portrait) {
	div.slide {
		height: 200px;
		background-size: cover;
		background-repeat: no-repeat;
	}
}

@media screen and (orientation:landscape) {
	div.slide {
		height: 350px;
		background-size: cover;
		background-repeat: no-repeat;
	}
}

Our images will be automatically scaled by CSS so that they will always fit their container. There's no actual need for additional JavaScript code in this particular case.