Full Width Image Slider

A very simple 100% width slider that scales down to mobile.

Full Width Image Slider

View demo Download source

This slider has a 100% width layout and it is responsive. It operates with CSS transitions and the image is wrapped with an anchor. The anchor can be replaced by a division if no linking is needed. With a max-width set to 100%, the image will size down for smaller screens.

The HTML

<div id="cbp-fwslider" class="cbp-fwslider">
	<ul>
		<li><a href="#"><img src="images/1.jpg" alt="img01"/></a></li>
		<li><a href="#"><img src="images/2.jpg" alt="img02"/></a></li>
		<li><a href="#"><img src="images/3.jpg" alt="img03"/></a></li>
		<li><a href="#"><img src="images/4.jpg" alt="img04"/></a></li>
		<li><a href="#"><img src="images/5.jpg" alt="img05"/></a></li>
	</ul>
</div>

The CSS

.cbp-fwslider {
	position: relative;
	margin: 0 0 10px;
	overflow: hidden;
	padding: 40px 0 60px;
}

.cbp-fwslider ul {
	margin: 0;
	padding: 0;
	white-space: nowrap;
	list-style-type: none;
}

.cbp-fwslider ul li {
	transform: translateZ(0);
	float: left;
	display: block;
	margin: 0;
	padding: 0;
}

.cbp-fwslider ul li > a,
.cbp-fwslider ul li > div {
	display: block;
	text-align: center;
	outline: none;
}

.cbp-fwslider ul li > a img {
	border: none;
	display: block;
	margin: 0 auto;
	max-width: 75%;
}

.cbp-fwslider nav span {
	position: absolute;
	top: 50%;
	width: 50px;
	height: 100px;
	background: #47a3da;
	color: #fff;
	font-size: 50px;
	text-align: center;
	margin-top: -50px;
	line-height: 100px;
	cursor: pointer;
	font-weight: normal;
}

.cbp-fwslider nav span:hover {
	background: #378fc3;
}

.cbp-fwslider nav span.cbp-fwnext {
	right: 0px;
}

.cbp-fwslider nav span.cbp-fwprev {
	left: 0px;
}

.cbp-fwdots {
	position: absolute;
	bottom: 0px;
	white-space: nowrap;
	text-align: center;
	width: 100%;
}

.cbp-fwdots span {
	display: inline-block;
	width: 18px;
	height: 18px;
	background: #ddd;
	margin: 4px;
	border-radius: 50%;
	cursor: pointer;
}

.cbp-fwdots span:hover {
	background: #999;
}

.cbp-fwdots span.cbp-fwcurrent {
	background: #47a3da;
	box-shadow: 0 0 0 2px #47a3da;
	transition: box-shadow 0.2s ease-in-out;
}

The JavaScript

;( function( $, window, undefined ) {

	'use strict';

	// global
	var Modernizr = window.Modernizr;

	$.CBPFWSlider = function( options, element ) {
		this.$el = $( element );
		this._init( options );
	};

	// the options
	$.CBPFWSlider.defaults = {
		// default transition speed (ms)
		speed : 500,
		// default transition easing
		easing : 'ease'
	};

	$.CBPFWSlider.prototype = {
		_init : function( options ) {
			// options
			this.options = $.extend( true, {}, $.CBPFWSlider.defaults, options );
			// cache some elements and initialize some variables
			this._config();
			// initialize/bind the events
			this._initEvents();
		},
		_config : function() {

			// the list of items
			this.$list = this.$el.children( 'ul' );
			// the items (li elements)
			this.$items = this.$list.children( 'li' );
			// total number of items
			this.itemsCount = this.$items.length;
			// support for CSS Transitions & transforms
			this.support = Modernizr.csstransitions && Modernizr.csstransforms;
			this.support3d = Modernizr.csstransforms3d;
			// transition end event name and transform name
			var transProperties = {
				'WebkitTransition' : { transitionEndEvent : 'webkitTransitionEnd', tranformName : '-webkit-transform' },
				'MozTransition' : { transitionEndEvent : 'transitionend', tranformName : '-moz-transform' },
				'OTransition' : { transitionEndEvent : 'oTransitionEnd', tranformName : '-o-transform' },
				'msTransition' : { transitionEndEvent : 'MSTransitionEnd', tranformName : '-ms-transform' },
				'transition' : { transitionEndEvent : 'transitionend', tranformName : 'transform' }
			};
			if( this.support ) {
				this.transEndEventName = transProperties[ Modernizr.prefixed( 'transition' ) ].transitionEndEvent + '.cbpFWSlider';
				this.transformName = transProperties[ Modernizr.prefixed( 'transition' ) ].tranformName;
			}
			// current and old itemĀ“s index
			this.current = 0;
			this.old = 0;
			// check if the list is currently moving
			this.isAnimating = false;
			// the list (ul) will have a width of 100% x itemsCount
			this.$list.css( 'width', 100 * this.itemsCount + '%' );
			// apply the transition
			if( this.support ) {
				this.$list.css( 'transition', this.transformName + ' ' + this.options.speed + 'ms ' + this.options.easing );
			}
			// each item will have a width of 100 / itemsCount
			this.$items.css( 'width', 100 / this.itemsCount + '%' );
			// add navigation arrows and the navigation dots if there is more than 1 item
			if( this.itemsCount > 1 ) {

				// add navigation arrows (the previous arrow is not shown initially):
				this.$navPrev = $( '<span class="cbp-fwprev"><</span>' ).hide();
				this.$navNext = $( '<span class="cbp-fwnext">></span>' );
				$( '<nav/>' ).append( this.$navPrev, this.$navNext ).appendTo( this.$el );
				// add navigation dots
				var dots = '';
				for( var i = 0; i < this.itemsCount; ++i ) {
					// current dot will have the class cbp-fwcurrent
					var dot = i === this.current ? '<span class="cbp-fwcurrent"></span>' : '<span></span>';
					dots += dot;
				}
				var navDots = $( '<div class="cbp-fwdots"/>' ).append( dots ).appendTo( this.$el );
				this.$navDots = navDots.children( 'span' );

			}

		},
		_initEvents : function() {
			
			var self = this;
			if( this.itemsCount > 1 ) {
				this.$navPrev.on( 'click.cbpFWSlider', $.proxy( this._navigate, this, 'previous' ) );
				this.$navNext.on( 'click.cbpFWSlider', $.proxy( this._navigate, this, 'next' ) );
				this.$navDots.on( 'click.cbpFWSlider', function() { self._jump( $( this ).index() ); } );
			}

		},
		_navigate : function( direction ) {

			// do nothing if the list is currently moving
			if( this.isAnimating ) {
				return false;
			}

			this.isAnimating = true;
			// update old and current values
			this.old = this.current;
			if( direction === 'next' && this.current < this.itemsCount - 1 ) {
				++this.current;
			}
			else if( direction === 'previous' && this.current > 0 ) {
				--this.current;
			}
			// slide
			this._slide();

		},
		_slide : function() {

			// check which navigation arrows should be shown
			this._toggleNavControls();
			// translate value
			var translateVal = -1 * this.current * 100 / this.itemsCount;
			if( this.support ) {
				this.$list.css( 'transform', this.support3d ? 'translate3d(' + translateVal + '%,0,0)' : 'translate(' + translateVal + '%)' );
			}
			else {
				this.$list.css( 'margin-left', -1 * this.current * 100 + '%' );	
			}
			
			var transitionendfn = $.proxy( function() {
				this.isAnimating = false;
			}, this );

			if( this.support ) {
				this.$list.on( this.transEndEventName, $.proxy( transitionendfn, this ) );
			}
			else {
				transitionendfn.call();
			}

		},
		_toggleNavControls : function() {

			// if the current item is the first one in the list, the left arrow is not shown
			// if the current item is the last one in the list, the right arrow is not shown
			switch( this.current ) {
				case 0 : this.$navNext.show(); this.$navPrev.hide(); break;
				case this.itemsCount - 1 : this.$navNext.hide(); this.$navPrev.show(); break;
				default : this.$navNext.show(); this.$navPrev.show(); break;
			}
			// highlight navigation dot
			this.$navDots.eq( this.old ).removeClass( 'cbp-fwcurrent' ).end().eq( this.current ).addClass( 'cbp-fwcurrent' );

		},
		_jump : function( position ) {

			// do nothing if clicking on the current dot, or if the list is currently moving
			if( position === this.current || this.isAnimating ) {
				return false;
			}
			this.isAnimating = true;
			// update old and current values
			this.old = this.current;
			this.current = position;
			// slide
			this._slide();

		},
		destroy : function() {

			if( this.itemsCount > 1 ) {
				this.$navPrev.parent().remove();
				this.$navDots.parent().remove();
			}
			this.$list.css( 'width', 'auto' );
			if( this.support ) {
				this.$list.css( 'transition', 'none' );
			}
			this.$items.css( 'width', 'auto' );

		}
	};

	var logError = function( message ) {
		if ( window.console ) {
			window.console.error( message );
		}
	};

	$.fn.cbpFWSlider = function( options ) {
		if ( typeof options === 'string' ) {
			var args = Array.prototype.slice.call( arguments, 1 );
			this.each(function() {
				var instance = $.data( this, 'cbpFWSlider' );
				if ( !instance ) {
					logError( "cannot call methods on cbpFWSlider prior to initialization; " +
					"attempted to call method '" + options + "'" );
					return;
				}
				if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) {
					logError( "no such method '" + options + "' for cbpFWSlider instance" );
					return;
				}
				instance[ options ].apply( instance, args );
			});
		} 
		else {
			this.each(function() {	
				var instance = $.data( this, 'cbpFWSlider' );
				if ( instance ) {
					instance._init();
				}
				else {
					instance = $.data( this, 'cbpFWSlider', new $.CBPFWSlider( options, this ) );
				}
			});
		}
		return this;
	};

} )( jQuery, window );

View demo Download source

Previous:
Next:

Tagged with:

ML is a freelance web designer and developer with a passion for interaction design. She studied Cognitive Science and Computational Logic and has a weakness for the smell of freshly ground peppercorns.

View all contributions by

Website: http://www.codrops.com

Related Articles

CSS Reference

Learn about all important CSS properties from the basics with our extensive and easy-to-read CSS Reference.

It doesn't matter if you are a beginner or intermediate, start leanirng CSS now.

Feedback 144

Comments are closed.
  1. 1

    Great Bluprint !
    i use it on my website but i’m new to jquery, I added 20 page and i want that when you click on a text link called “image 1 for example” the slider go to the corresponding
    Thank you

  2. 2

    How do I change the left and right text on the image navigation buttons? I can’t see to find the js script that is generating this text.

    Thanks

  3. 3

    Hi!

    I am desperate. I need to make the slider to a carousell which goes round and round. Is their any way to do this?

    Thanx

    Adam

    • 4

      loving this slider… but yea if a function could be made so it goes in a circular motion rather than going back it would be perfect. :)

  4. 5

    also, when the image slides, it uses like 100% width to transition the image. i would like to constrain the width of the transitions. how do i go about this?

    • 6

      this.$items.css( ‘width’, 100 / this.itemsCount + ‘%’ );

      Search for that line. It handles the width of each element. Changing that will help you solve your problem. :) Hope that is what you asked.

  5. 7

    how can apply autoplay, and how can i modified the arrows for preview and next buttons ?

    • 8

      Auto play is already implemented in previous comments… check the 1-2 pages and you will find your answer.

      Also if you want to preview the arrow then in the javascript file search for the line below,

      this.$navPrev.on( ‘click.cbpFWSlider’, $.proxy( this._navigate, this, ‘previous’ ) ).hide();

      This will show the button on load and then if you want it to display continuously in the _toggleNavControls : function() you will have to change the switch statement. Changing all the hides to show will do the trick. Caution though when the buttons are displayed but if there is no next or prev slide it breaks the functionality so you will have to implement some javascript to handle it. :) hope is helps cheers

    • 9

      switch( this.current ) {
      case 0 : this.$navNext.show(); this.$navPrev.show(); break;
      case this.itemsCount – 1 : this.$navNext.show(); this.$navPrev.show(); break;
      default : this.$navNext.show(); this.$navPrev.show(); break;
      }

      and

      this.$navPrev = $( ‘<‘ ).show();

  6. 10

    Really awesome stuff!

    Weird question, though and apologies if this is the wrong place to ask: is there a way to change the background color of the entire document when you advance slide? Essentially, where would i plug in $(this).css(‘background-color’, ‘red’); or something similar?

    Thanks for any feedback!

  7. 13

    Hello,

    Slider in full screen does not work on mobile devices?

    Why might that be?

    Best regards.

  8. 14

    Hi,
    This might be a silly question but how do I make it so what ever screen resolution/size you have the image will proportionally stretch to it (even if it gets pixely) instead of having white on both sides once you have reach the actual size of the image?

    Thanks!

  9. 15

    Can someone please help me….How do I change the transition effect to make it “fade” instead of “slide”.

  10. 16

    In case you’re looking for custom previous and next buttons that can appear in the slides themselves, here’s a snippet of code that you can assign to an element ID:

    nextSlide : function(){
    if((this.current) == (this.itemsCount-1)){
    this.current = -1;
    }
    else{
    this._navigate(‘next’);
    }
    },

    nextButton : function(){
    var that = this;
    $(“#next”).click(function(){
    return that.nextSlide();

    });
    },

    And call this one in your document ready code:

    $( ‘#cbp-fwslider’ ).cbpFWSlider(‘nextButton’);

  11. 18

    Thank you for this awesome slider.
    One issue for my part: how could I include the slider twice in one page it doesn’t work at my end ?

    Regards,

  12. 19

    This is full width and also full height of browser. How this slider height can be limit to certain height.

  13. 20

    Does anyody know how to autohide the arrows? so when you hover over, then the nav arrows show? I can’t find anything in the comments!

    Thanks,

  14. 22

    Hi,

    i’m getting an issue using this script with the Facebook Like Box. The entire page blinks when the transition is done. Someone else? Any idea to solve this problem?

    The script is awesome, by the way. Congratulations!

    Thanks,

  15. 24

    I have a Problem. The Slider dosen’t show the transition in IE9.
    Is there a fix for the Problem.

Comments are closed.