From our sponsor: Ready to show your plugin skills? Enter the Penpot Plugins Contest (Nov 15-Dec 15) to win cash prizes!
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; }
Tiny break: 📬 Want to stay up to date with frontend and trends in web design? Subscribe and get our Collective newsletter twice a tweek.
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 );
Hello!
This is a beautiful plugin! I’m using it to develop a website and on my localhost it works flawless. However, it doesn’t seem to work when I copy a mirror of my layout to a server. I’m not the kind of person to ask for this kind of help on websites, but it’s beyond my skillz.
Is there a way to find out what is creating the conflict? The relative paths and such are working fine. Could there be any possibilities of plugin conflict for this plugin that you know of? Thank you!
Hi,
How can I make this fade rather than slide?
My problem is Modernizr is undefined.How can i fix it.Thank you
This is a great tutorial and slider. How can I implement timed transitions?
Hi! Thanks, it best slider. But please, ask me, how add easing effect change slide “FADE”?
The demo for this is broken because of mixed content warnings, trying to load jQuery over http://
Hi Justin,
thanks so much for letting us know! We’ll fix it asap.
Cheers
This is not full width… just placing the forward and backward arrows at their end doesn’t cut it. Full width is when the image is automatically stretched to the full width of the screen.