Implementing, Styling and Extending Flexslider

Looking for implementing a zoom function with flexslider? Then you want to go here.
So we all have adapted to responsive design now right? If you haven’t I strongly suggest you do!

You have your site all working nice and resposive and want a responsive sliding gallery to showcase some of your work, this is a usual story. There are many of these sliders out there and one of my favourites is Flexslider.

To use Flexslider is incredibly simple, you can go get the code put it in place and job done! But for most of us that isn’t enough, we want to make it fit with our design, to make it more “yours” a few people have asked me how recently and have also wanted to extend it to do things such as navigating to a certain slide. When giving these answers it was suggested I share it with the tinterweb world so here it is.

What is Flexslider?

In a nutshell flexslider is an awesome, fully responsive jQuery slider toolkit that has all of the following niceties.

  • Simple, semantic markup
  • Supported in all major browsers
  • Horizontal/vertical slide and fade animations
  • Multiple slider support, Callback API, and more
  • Hardware accelerated touch swipe support
  • Custom navigation options
  • Compatible with the latest version of jQuery

Let’s get started

Firstly and if it was not obvious enough you will want to go and get the files from woo themes and uplaod them to your site wherever you see fit (for examples in this article I will use my chosen structure, you will just need to adjust these).

The HTML Markup

All the code you need to implement a 3 item slider is this:

<div class="flex-container">
    <div class="flexslider">
        <ul class="slides">
            <li>
                <a href="#"><img src="img/slide1.jpg" /></a>
            </li>
            <li>
                <img src="img/slide2.jpg" />
            </li>
            <li>
                <img src="img/slide3.jpg" />
                <p>Designing The Well-Tempered Web</p>
            </li>
        </ul>
    </div>
</div>

Next we’ll include the jQuery library and the FlexSlider plugin. To load the slider include the following code, you can set the settings there too, for more setting visit the plugin website. All I have set in this one is to make the animation fade and the controls container to be the flexslider container, pretty standard stuff we will move onto more advanced things later.

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<script src="js/jquery.flexslider-min.js"></script>
<script>
    $(document).ready(function () {
        $('.flexslider').flexslider({
            animation: 'fade',
            controlsContainer: '.flexslider'
        });
    });
</script>

Style it up

Let’s add some basic reset styles to keep all margins, paddings etc consistent.

.flex-container a:active,
.flexslider a:active,
.flex-container a:focus,
.flexslider a:focus  { outline: none; }

.slides,
.flex-control-nav,
.flex-direction-nav {
    margin: 0;
    padding: 0;
    list-style: none;
}

.flexslider a img { outline: none; border: none; }

.flexslider {
    margin: 0;
    padding: 0;
}

Next we will hide the slides initally to stop the page from jumping as it loads and everyone seeing all the images.

.flexslider .slides > li {
    display: none;
    -webkit-backface-visibility: hidden;
}

.flexslider .slides img {
    width: 100%;
    display: block;

    -webkit-border-radius: 2px;
    -moz-border-radius: 2px;
    border-radius: 2px;
}

Then we will clear the floats from the slides.

.slides:after {
    content: ".";
    display: block;
    clear: both;
    visibility: hidden;
    line-height: 0;
    height: 0;
}

html[xmlns] .slides { display: block; }
* html .slides { height: 1%; }

Container styles

Let’s get a little snazzy but it is really simple stuff I promise! We can just add a white background and some rounded corners and a nice little shadow using good old box-shadow.

.flexslider {
    position: relative;
    zoom: 1;
    padding: 10px;
    background: #ffffff;

    -webkit-border-radius: 3px;
    -moz-border-radius: 3px;
    border-radius: 3px;

    -webkit-box-shadow: 0px 1px 1px rgba(0,0,0, .2);
    -moz-box-shadow: 0px 1px 1px rgba(0,0,0, .2);
    box-shadow: 0px 1px 1px rgba(0,0,0, .2);
}

In my demo version I have set a maximum and minimum width just so it did not stretch too far wide on larger screens. You can change or remove this to make them fit your design. I have also set a zoom to 1 just to stop mobile browsers from resiizing.

.flex-container {
    min-width: 150px;
    max-width: 960px;
}

.flexslider .slides { zoom: 1; }

Now for the arrows

This is where the styling gets a little more interesting. First the basics, we set the width and height etc. Then to make the arrows a little nice and to reward those with modern browsers I have added a subtle gradient using css3, nice ey! These then need to be position centered vertically, we just have to position then 50% from the top and then give them a negative margin half of the buttons height.

.flex-direction-nav a {
    display: block;
    position: absolute;
    margin: -17px 0 0 0;
    width: 35px;
    height: 35px;
    top: 50%;
    cursor: pointer;
    text-indent: -9999px;

    background-color: #bfab8b;
	background-image: -webkit-gradient(linear, left top, left bottom, from(#bfab8b), to(#f5e2c1));
	background-image: -webkit-linear-gradient(top, #bfab8b, #f5e2c1);
	background-image: -moz-linear-gradient(top, #bfab8b, #f5e2c1);
	background-image: -o-linear-gradient(top, #bfab8b, #f5e2c1);
	background-image: linear-gradient(to bottom, #bfab8b, #f5e2c1);
}

Next, to add the actual arrows into the boxes we use the :before pseudo selector. This pseudo selector allows us to include some content without adding a new tag in the html. Then you have a couple of options. If you want to be really snazzy and are not to worried about all browser support and just want to be really modern and cool, you can draw the arrows yourself using a series of gradients like this:

.flex-direction-nav a:before {
	display: block;
	position: absolute;
	content: '';
	width: 9px;
	height: 13px;
	top: 11px;
	left: 11px;
	background-image:
        linear-gradient(-45deg, #dac6a6 4px, transparent 4px),
        linear-gradient(-135deg, #dac6a6 4px, transparent 4px),
        linear-gradient(-45deg, #69604f 6px, transparent 6px),
        linear-gradient(-135deg, #69604f 6px, transparent 6px);

}

.flex-direction-nav a.flex-prev:before {
	background-image:
        linear-gradient(45deg, #dac6a6 4px, transparent 4px),
        linear-gradient(135deg, #dac6a6 4px, transparent 4px),
        linear-gradient(45deg, #69604f 6px, transparent 6px),
        linear-gradient(135deg, #69604f 6px, transparent 6px);
}

Or to be more supportive and the more standard way of doing it is to create a little sprite with the arrows in and just using this as a background image (you can see the sprite in my demo if you want to set it up the same).

.flex-direction-nav a:before {
    display: block;
    position: absolute;
    content: '';
    width: 9px;
    height: 13px;
    top: 11px;
    left: 11px;
    background: url(../img/arrows.png) no-repeat;
}

To create the nice wrap ribbon effect we can use another pseudo selector :after. Then to create the actual shape we can use pure css with a little border trick that makes the triangle shape.
While we are at it let’s give them buttons some nice rounded corners. I have also included some of the positional styling below.

.flex-direction-nav .flex-next {
    right: -5px;

    -webkit-border-radius: 3px 0 0 3px;
    -moz-border-radius: 3px 0 0 3px;
    border-radius: 3px 0 0 3px;
}

.flex-direction-nav .flex-prev {
    left: -5px;

    -webkit-border-radius: 0 3px 3px 0;
    -moz-border-radius: 0 3px 3px 0;
    border-radius: 0 3px 3px 0;
}

.flex-direction-nav .flex-next:before { background-position: -9px 0; left: 15px; }
.flex-direction-nav .flex-prev:before { background-position: 0 0; }

.flex-direction-nav .flex-next:after {
    right: 0;
    border-bottom: 5px solid transparent;
    border-left: 5px solid #31611e;
}

.flex-direction-nav .flex-prev:after {
    left: 0;
    border-bottom: 5px solid transparent;
    border-right: 5px solid #31611e;
}

The controls AKA Pagination Icons

The slider controls are the little circles at the end of the slider that allows you to click on a slide. We’ll position this container at the bottom of the slider. Then we will create the circles using the “border-radius” and “box-shadow” property. For the active slide circle we will remove the box shadow and add the same CSS3 gradient that we used on the buttons.

.flexslider .flex-control-nav {
	position: absolute;
	width: 100%;
	bottom: -40px;
	text-align: center;
	margin: 0 0 0 -10px;
}

.flex-control-nav li {
	display: inline-block;
	zoom: 1;
}

.flex-control-paging li a {
	display: block;
	cursor: pointer;
	text-indent: -9999px;
	width: 12px;
	height: 12px;
	margin: 0 3px;
	background-color: #b6b6b6 9;

	-webkit-border-radius: 12px;
	-moz-border-radius: 12px;
	border-radius: 12px;

	-webkit-box-shadow: inset 0 0 0 2px #b6b6b6;
	-moz-box-shadow: inset 0 0 0 2px #b6b6b6;
	box-shadow: inset 0 0 0 2px #b6b6b6;
}

.flex-control-paging li a.flex-active {
	background-color: #bfab8b;
	background-image: -webkit-gradient(linear, left top, left bottom, from(#bfab8b), to(#f5e2c1));
	background-image: -webkit-linear-gradient(top, #bfab8b, #f5e2c1);
	background-image: -moz-linear-gradient(top, #bfab8b, #f5e2c1);
	background-image: -o-linear-gradient(top, #bfab8b, #f5e2c1);
	background-image: linear-gradient(to bottom, #bfab8b, #f5e2c1);

	-webkit-box-shadow: none;
	-moz-box-shadow: none;
	box-shadow: none;
}

Captions, Should you choose

A lot of people like to use captions with these sliders too, you do not have to but if you want them then here is how you can style them. To actually have captions all you need to do is include a paragraph in the slide.

.flexslider .slides p {
    display: block;
    position: absolute;
    left: 0;
    bottom: 0;
    padding: 0 5px;
    margin: 0;

    font-family: Helvetica, Arial, sans-serif;
    font-size: 12px;
    font-weight: bold;
    text-transform: uppercase;
    line-height: 20px;
    color: white;

    background-color: #222222;
    background: rgba(0,0,0, .9);

    -webkit-border-radius: 2px;
    -moz-border-radius: 2px;
    border-radius: 2px;
}

Before we look at extending Flexslider here is a demo of your basic Flexslider all styled up and looking rather beautiful.

Extending Flexslider

Now how can you get more out of Flexslider? Well one thing that gets asked a lot of me is URL manipulation so that a user can get a link and it will take them straight to slide 3 for example.

This is where the “after” and “startAt” function used with Flexslider comes in really handy! You can use them mixed with a hash url function to get this to work easily.

$(window).load(function() {

	var index = 0, hash = window.location.hash;
	if (hash) {
            index = /d+/.exec(hash)[0];
            index = (parseInt(index) || 1) - 1;  
        }

var $slideshow = $('#slider');
$slideshow.flexslider({
    animation: 'fade',
    controlsContainer: '.flexslider'
    startAt: index, //now foo.html#3 will load item 3
    after:function(slider){
        window.location.hash = slider.currentSlide+1;
    });
});

That’s great but you want more!! So you have a little showcase slider and you want an opening cover then when you go through each slide you need a div to show the products featured on that slide… no problem! With some simple if and else statements we can get the slider to know what slide it is on and then run whatever function you see fit. The example below uses a div with the class of “products_slide” and then each would have a unique id. This is so the function can hide all the product divs first and then show a specific one that relates to the slide in view.

$(window).load(function() {

	var index = 0, hash = window.location.hash;
	if (hash) {
            index = /d+/.exec(hash)[0];
            index = (parseInt(index) || 1) - 1;  
        }

var $slideshow = $('#slider');
$slideshow.flexslider({
    animation: 'fade',
    controlsContainer: '.flexslider'
    startAt: index, //now foo.html#3 will load item 3
    after:function(slider){
        window.location.hash = slider.currentSlide+1;
        if (slider.currentSlide == 0) {
            $(".products_slide").hide();
            $("#products_slide1").show();
        }
        else if (slider.currentSlide == 1) {
            $(".products_slide").hide();
            $("#products_slide2").show();
        }	
        else if (slider.currentSlide == 2) {
            $(".products_slide").hide();
            $("#products_slide3").show();
        }			
    });
});

Pretty neat! Maybe on the cover it has a magazine type layout too and there are areas you want clickable to jump through to certian slides. For example you have a “find out more” link that shows you more detail on slide 3, then you would simply write this function:

$('.find-out-more').click(function(){
    $slideshow.flexslider(3);
});

Hope You Had Fun!

That should give you enough to get your teeth into and hopefully shows you that you can get a ready made plugin but then adapt to suit you more or make it more powerful. Know any more cool ways of extending Flexslider or other sliders? Then let me know, I want to know!!

A lot of you lovely folk have been asking how you can have a zoom function within flexslider, if that is what you are looking for then you might want to visit here.