Different Flexsliders at different display sizes
A design I was working on called for a mobile sized display to have a single slide visible at all times, but a larger display to have two slides visible at the same time. It also required each view to scale fluidly without revealing a partial slide or looking squiffy (the default flexslider2 reveals partial slides when fluid). Here’s how I managed it.
Note 1: I am no JavaScript expert and there is likely a better way of achieving this, but the principles seem useful so I’m sharing it. Let me know if there are ways to improve the code
Note 2: I’m using a beta version of FlexSlider2 because FlexSlider1 does not allow multiple slides viewable at the same time.
The markup
This is just a basic slider exactly as the standard FlexSlider documentation suggests:
<div class="flexslider-container">
<div class="flexslider">
<ul class="slides">
<li>
<img src="demo-stuff/inacup_samoa.jpg" />
</li>
<li>
<img src="demo-stuff/inacup_pumpkin.jpg" />
</li>
<li>
<img src="demo-stuff/inacup_donut.jpg" />
</li>
<li>
<img src="demo-stuff/inacup_vanilla.jpg" />
</li>
</ul>
</div>
</div>
The CSS
Is the default FlexSlider theme. I am, however, using a CSS technique from Jeremy Keith to put a pseudo-element after the body tag to declare which design breakpoint is currently in use. The JS will use this; it has no visible effect.
/* breakpoint_1 */
body:after { display: none; content: 'breakpoint_1'; }
.flexslider { max-width: 1080px; margin : 0 auto; }
/* breakpoint_2 */
@media all and (min-width: 480px) {
body:after { display: none; content: 'breakpoint_2'; }
}
/* breakpoint_3 */
@media all and (min-width: 720px) {
body:after { display: none; content: 'breakpoint_3'; }
}
The Javascript
Watches for a window resize event (and initial page load), inspects the value of the pseudo-element the CSS placed on the body tag, matches that value with a breakpoint, and than applies only the required JS.
To ensure performance is good on all browsers, the script checks for a resize event every 1/4 second, to avoid poor performance during a resize event (it can fire continuously otherwise).
When breakpoints change, the script destroys old flex-slider elements and re-creates new ones that better match the design at that given size.
$(document).ready(function(){
var currentBreakpoint; // default's to blank so it's always analysed on first load
var didResize = true; // default's to true so it's always analysed on first load
var raw_slider = $(".flexslider").html(); // grab the unaltered HTML and store it
// on window resize, set the didResize to true
$(window).resize(function() {
didResize = true;
});
// every 1/4 second, check if the browser was resized
// we throttled this because some browsers fire the resize even continuously during resize
// that causes excessive processing, this helps limit that
setInterval(function() {
if(didResize) {
didResize = false;
// inspect the CSS to see what breakpoint the new window width has fallen into
var newBreakpoint = window.getComputedStyle(document.body, ':after').getPropertyValue('content');
/* tidy up after inconsistent browsers (some include quotation marks, they shouldn't) */
newBreakpoint = newBreakpoint.replace(/"/g, "");
newBreakpoint = newBreakpoint.replace(/'/g, "");
// if the new breakpoint is different to the old one, do some stuff
if (currentBreakpoint != newBreakpoint) {
// remove the old flexslider (which has attached event handlers and adjusted DOM nodes)
$(".flexslider").remove();
// now re-insert clean mark-up so flexslider can run on it properly
$(".flexslider-container").append("<div class='flexslider'></div>");
$(".flexslider").html(raw_slider);
// execute JS specific to each breakpoint
if (newBreakpoint === 'breakpoint_1') {
// the narrowset breakpoint is now the current breakpoint
currentBreakpoint = 'breakpoint_1';
// Slider with one slide
$(".flexslider").flexslider({
animation: "slide",
animationLoop: false,
itemWidth: 360,
itemMargin: 0,
minItems: 1,
maxItems: 1,
controlNav: false
});
}
if (newBreakpoint === 'breakpoint_2') {
// the second largest breakpoint is now the current one
currentBreakpoint = 'breakpoint_2';
// Slider with two slides
$(".flexslider").flexslider({
animation: "slide",
animationLoop: false,
itemWidth: 360,
itemMargin: 0,
minItems: 2,
maxItems: 2,
controlNav: false
});
}
if (newBreakpoint === 'breakpoint_3') {
// the second largest breakpoint is now the current one
currentBreakpoint = 'breakpoint_3';
// Slider with two slides
$(".flexslider").flexslider({
animation: "slide",
animationLoop: false,
itemWidth: 360,
itemMargin: 0,
minItems: 3,
maxItems: 3,
controlNav: false
});
}
}
}
}, 250);
}); // $(document).ready
Entry Information
- Posted:
- Sat, 5th May 2012 at 16:05 UTC
- Filed under:
- Tags:
Comments
skip to comment formHi Matt, I'm trying to implement a Flexslider to my blog (http://hd-cardiza.blogspot.com/). It's not the one that you posted here though. But I'm going to ask anyway since you may know the answer.
If you look at the slider, the image is being stretched. My question is How can I modify the slider image size? The size of my images are 827 x 413px.
Thanks in advance!