Jump to main navigation, main content

Archived entry | Matt Wilcox .net

Different Flexsliders at different display sizes

See the demo

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 smiley icon: smile

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

Comments

skip to comment form
  1. Rose posted 92 days, 13hrs, 56mins after the entry and said:

    Hi 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. smiley icon: smile

    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!

From the archives

Other enteries filed under:

Web Development

Site information

Built with valid XHTML and CSS, designed with web standards and accessibility in mind. Best viewed in a modern browser [Firefox, Safari, Opera]

This domain and all content is a copy of my old website, for historical purposes only.