Full Width Image Slider

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

Full Width Image Slider

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 );

Tagged with:

Manoela Ilic

Manoela is the main tinkerer at Codrops. With a background in coding and passion for all things design, she creates web experiments and keeps frontend professionals informed about the latest trends.

Stay up to date with the latest web design and development news and relevant updates from Codrops.

Feedback 147

Comments are closed.
  1. For the issue with the background not centering. The attribute for that was set up as an absolute in the javascript. you can over ride it in CSS styles

    div.JB_Slide div:first-child {
    background-repeat: no-repeat !important;
    background-position: center !important;
    }

    Wish I could take credit for figuring it out, rather simple for a developer, so I asked one. :0) Thought I would share.

  2. The centering of the images doesn’t seem to work. Has anyone another idea for that?

  3. Hi everybody! I need some autoplay for this code, that always works regardless of the mouse event. Is that possible? Just stop the autoplay if Iclick some of the navigation elements. And when I reach the last slide, go back to first. I’ll be very grateful for your help! Sorry for my poor English. 🙂

  4. Hi, Autoplay feature would make this AWESOME, one thing I did spot was that when you hovered over an area outside of the tablet you were still on a ‘#’ link..

  5. How do I make it auto slide, I sow some suggestions here but none of them worked. I need you to tell me exactly in which file it needs to be added.

    Thanks a lot of help!

  6. Here is how to make it autoplay using Özgür’s code.

    Put this right after CBPFWSlider.prototype = {
    autoplay : function(){ if((this.current) == (this.itemsCount-1)){ this.current = -1; } else{ this._navigate('next'); } }, interval : function(){ var that = this; setInterval(function(){ return that.autoplay(); },300); },

    Now the script before the closing body tag will now look like this:
    $( function() { $( '#cbp-fwslider' ).cbpFWSlider(); $( '#cbp-fwslider' ).cbpFWSlider('interval'); } );

    Thanks for everyone’s help! I love this slider.

  7. Hi!

    The auto play code above worked perfect! Thanx a lot!
    But I do have a question. When the last slide is showing the arrow to the right disappears and it is impossible to reach the first slide without going back the same way we come frome. Is it possible to make it “infinity”, so the right arrow wont disappear?

    Thanx alot

    /Adam

    • Hey.

      Seems like you got the slider to actually go back to the beginning after it finishes its first round.. Could you let me know how you did this ? 🙂 thanks heaps..

  8. 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

  9. 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

  10. 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

    • 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. 🙂

  11. 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?

    • 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.

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

    • 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

    • 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();

  13. 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!

  14. Hello,

    Slider in full screen does not work on mobile devices?

    Why might that be?

    Best regards.

  15. 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!

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

  17. 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’);

  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,

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

  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,

  21. 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,

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

  23. When i click on the previous arrow at the last slide it moves to empty slide..Taking the wrong position.

    How to fix this?

    Thanks in advance 🙂

  24. I was wondering if anyone was having problems with getting the transitions to work. Everything else seems to be working fine. Any Ideas on what I am missing?

  25. Hello, I’ve a simple question about this amazing slider 😉
    can we have text and links at right of images ??

    Thank you

  26. Issues in Chrome. The slider is working in all browsers except Chrome where the first image is not hiding it stays a background image as the other images slide over it. You can check it out here. The only change that I have made is that the slider pulls images from a database.

    http://www.westernwildlifeimages.com/index.asp

    Any help would be great!

    B

  27. How can i put an automation in this? So that it will slide every 10 seconds or so?
    Please help
    Thanks

  28. Hey, this is just what I had been looking for. Can’t believe I found a responsive image slider here right when I needed it, lol. Once again, this website pulls through. Amazing: it’s so simple and yet so functional.

    I do have a question for anyone who sees this. How would I make this loop back to the first item in the list when you’ve gotten to the last one and click “next”? Which is to say, I’d need the nav buttons to stay present for this to happen, too. I think this is all else I need it to do (but I’ve noted the autoplay stuff from the comments, too, just in case).

  29. Hello! Great plugin! However I seem to be having an issue with multiple sliders on one page. The first one fires the js and works totally fine, but all of the other sliders are just showing the images next to one another.

    Am I missing something? Or does the code need to be changed?

    • Hi Artem,
      this seems to work fine:
      <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> <div id="cbp-fwslider2" 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> <!--formatted-->

      $( '#cbp-fwslider' ).cbpFWSlider(); $( '#cbp-fwslider2' ).cbpFWSlider();

      Was it something like this you tried?

    • Hey Pedro,

      Thank you so much, I actually tried that and it did work out well! Thank you so much for taking the time to do that!

  30. When i click on the previous arrow at the last slide it moves to empty slide..Taking the wrong position.

    Am I missing something? Or does the code need to be changed?

  31. Using the autoplay function from these comments, how would I be able to pause the autoplay when the user has their mouse over the slide?

    This is the autoplay code using:

    autoplay : function(){
    if((this.current) == (this.itemsCount-1)){
    this.current = -1;
    }
    else{
    this._navigate(‘next’);
    }
    },
    interval : function(){
    var that = this;
    setInterval(function(){
    return that.autoplay();
    }, 3000);
    },

  32. hi there,

    can any one tell me how to change “EASE” to FadeIn with this slider

    Best, Harsha.Ch

  33. Hi all,

    The slider works great on my site, except for one thing. The last image in the list is about 15-20px below the rest of the images that came before it. Almost touching the dot nav. Any advice in changing the code to fix this issue? Thanks in advance for the help.

    – Emily

    • I was able to figure out the issue, I had 2 lines of codes missing in my css and forgot to apply the clearfix prior the slider. Hope that helps others that run into the same problem.

      – Emily

  34. Hello,

    Can someone please tell me why the last image in the slider becomes lower on the line then the previous images? Is there something in my script I should be making sure I have?

    Thanks.

    – Emily