From our sponsor: Meco is a distraction-free space for reading and discovering newsletters, separate from the inbox.
You have for sure already seen impress.js, a really great JavaScript library for creating extraordinary 3D presentations. The jQuery port jmpress.js let’s you use this library as a jQuery plugin with some added options. We want to show you today how to use this great plugin to create a responsive slideshow with 3D effects.
The icons used in the demo is by Artcore Illustration and they are licensed under the
Creative Commons BY-NC-ND 3.0 license.
So, let’s start!
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 Markup
We will have a main container which is a section with the class jms-slideshow. Inside, we’ll have sevaral divisions with the class step. These will be our single slides. Each step or slide will get a data-color class for it’s background color and some data attributes of jmpress.js. You can find all (inline) options here: jmpress.js Documentation – Options. We’ll use some attributes in order to define the position and rotation of the slides in 3D space:
<section id="jms-slideshow" class="jms-slideshow"> <div class="step" data-color="color-1"> <div class="jms-content"> <h3>Some headline</h3> <p>Some text</p> <a class="jms-link" href="#">Read more</a> </div> <img src="images/1.png" /> </div> <div class="step" data-color="color-2" data-y="500" data-scale="0.4" data-rotate-x="30"> <!-- ... --> </div> <!-- ... --> </section>
Let’s take care of the style.
The CSS
Since we want to make the slideshow responsive, we will give the main container a percentage width, with some min and max values:
.jms-slideshow { position: relative; width: 80%; max-width: 1400px; min-width: 640px; margin: 20px auto; height: 460px; }
The next wrapper is dynamically added, and this will be the visible slideshow wrapper:
.jms-wrapper { width: auto; min-width: 600px; height: 440px; background-color: #fff; box-shadow: 0 2px 6px rgba(0, 0, 0, .2); -webkit-background-clip: padding; -moz-background-clip: padding; background-clip: padding-box; border: 10px solid #fff; border: 10px solid rgba(255, 255, 255, 0.9); outline: none; transition: background-color 1s linear; }
The background color classes will be applied to the previous wrapper. The class is defined in the data atrribute data-color in each step. This gives us the possibility to add a background color for each slide and change it with a transition. (The duration of the transition will be re-defined in the JavaScript.)
.color-1 { background-color: #E3D8FF; background-color: rgba(227, 216, 268, 1); } .color-2 { background-color: #EBBBBC; background-color: rgba(235, 187, 188, 1); } .color-3 { background-color: #EED9C0; background-color: rgba(238, 217, 192, 1); } .color-4 { background-color: #DFEBB1; background-color: rgba(223, 235, 177, 1); } .color-5{ background-color: #C1E6E5; background-color: rgba(193, 230, 229, 1); }
The steps will have the following style:
.step { width: 900px; height: 420px; display: block; transition: opacity 1s; } .step:not(.active) { opacity: 0; }
Inactive steps will have 0 opacity. When the slides are moved, the opacity will be set to 1.
The inner parts of the slides will have the following style:
.jms-content{ margin: 0px 370px 0px 20px; position: relative; clear: both; } .step h3{ color: #fff; font-size: 52px; font-weight: bold; text-shadow: 1px 1px 1px rgba(0,0,0,0.1); margin: 0; padding: 60px 0 10px 0; } .step p { color: #fff; text-shadow: 1px 1px 1px rgba(0,0,0,0.1); font-size: 34px; font-weight: normal; position: relative; margin: 0; }
The “read more” link will have a little transition by itself: once a step becomes active, it will move up wile fading in:
a.jms-link{ color: #fff; text-transform: uppercase; background: linear-gradient(top, #969696 0%,#727272 100%); padding: 8px 15px; display: inline-block; font-size: 16px; font-weight: bold; color: #fff; text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3); box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5); border: 1px solid #444; border-radius: 4px; opacity: 1; margin-top: 40px; clear: both; transition: all 0.4s ease-in-out 1s; } .step:not(.active) a.jms-link{ opacity: 0; margin-top: 80px; }
The image will be positioned absolutely on the right side of each slide:
.step img{ position: absolute; right: 0px; top: 30px; }
The navigation dots will positioned at the bottom:
.jms-dots{ width: 100%; position: absolute; text-align: center; left: 0px; bottom: 20px; z-index: 2000; user-select: none; }
With “user-select: none” the text of an element and its sub-elements will appear as if they can’t be selected.
The span will be a dark little dot:
.jms-dots span{ display: inline-block; position: relative; width: 12px; height: 12px; border-radius: 50%; background: #777; margin: 3px; cursor: pointer; box-shadow: 1px 1px 1px rgba(0,0,0,0.1) inset, 1px 1px 1px rgba(255,255,255,0.3); }
And we’ll style a pseudo-element to look like a little white dot:
.jms-dots span.jms-dots-current:after{ content: ''; width: 8px; height: 8px; position: absolute; top: 2px; left: 2px; border-radius: 50%; background: linear-gradient(top, #ffffff 0%,#f6f6f6 47%,#ededed 100%); }
The arrow navigation spans will be positioned on the left and on the right side of the slideshow. We’ll use background images for the arrows:
.jms-arrows{ user-select: none; } .jms-arrows span{ position: absolute; top: 50%; margin-top: -40px; height: 80px; width: 30px; cursor: pointer; z-index: 2000; box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.1); border-radius: 3px; } .jms-arrows span.jms-arrows-prev{ background: #fff url(../images/arrow_left.png) no-repeat 50% 50%; left: -10px; } .jms-arrows span.jms-arrows-next{ background: #fff url(../images/arrow_right.png) no-repeat 50% 50%; right: -10px; }
Now we have styled the slideshow. Let’s move on to the JavaScript!
The JavaScript
We will be using the jmpress.js plugin to create our slideshow. Although you can make use of a lot of its functionality, we will just use the necessary parts to build our script. You can read more about the possibilities and options that jmpress.js offers here.
We will create a jQuery plugin for the slideshow. We can call the plugin like this:
$( '#jms-slider' ).jmslideshow();
The options for the jmpress plugin are defined as default options in our plugin (note that you can specify more than the ones listed):
jmpressOpts : { // set the viewport viewPort : { height : 400, width : 1300, maxScale: 1 }, fullscreen : false, hash : { use : false }, mouse : { clickSelects : false }, keyboard : { use : false }, animation : { transitionDuration : '1s' } },
You can either change them inside the slideshow plugin, or pass a specific value when you initialize the plugin. As an example:
// specify the jmpress options var jmpressOpts = { animation : { transitionDuration : '0.8s' } }; // call the jmslideshow plugin $( '#jms-slideshow' ).jmslideshow( $.extend( true, { jmpressOpts : jmpressOpts }, { autoplay : true, bgColorSpeed: '0.8s', arrows : false }));
The following are the set of available options that are available for the slideshow plugin:
$.JMSlideshow.defaults = { // options for the jmpress plugin. // you can add more options... jmpressOpts : { // set the viewport viewPort : { height : 400, width : 1300, maxScale: 1 }, fullscreen : false, hash : { use : false }, mouse : { clickSelects : false }, keyboard : { use : false }, animation : { transitionDuration : '1s' } }, // for this specific plugin we will have the following options: // shows/hides navigation arrows arrows : true, // shows/hides navigation dots/pages dots : true, // each step's bgcolor transition speed bgColorSpeed: '1s', // slideshow on / off autoplay : false, // time between transitions for the slideshow interval : 3500 };
Once the slideshow plugin is called, the first function to be executed is the init function:
_init : function( options ) { this.options = $.extend( true, {}, $.JMSlideshow.defaults, options ); // the slides this.$slides = $('#jms-slider').children('div'); // total number of slides this.slidesCount = this.$slides.length; // step's bgcolor this.colors = $.map( this.$slides, function( el, i ) { return $( el ).data( 'color' ); } ).join( ' ' ); // build the necessary structure to run jmpress this._layout(); // initialize the jmpress plugin this._initImpress(); // if support (function implemented in jmpress plugin) if( this.support ) { // load some events this._loadEvents(); // if autoplay is true start the slideshow if( this.options.autoplay ) { this._startSlideshow(); } } },
In the _layout function we are building the necessary structure for the jmpress plugin. Also, we will be adding the navigation arrows / dots in case these are set to true in the options.
_layout : function() { // adds a specific class to each one of the steps this.$slides.each( function( i ) { $(this).addClass( 'jmstep' + ( i + 1 ) ); } ); // wrap the slides. This wrapper will be the element on which we will call the jmpress plugin this.$jmsWrapper = this.$slides.wrapAll( '<div class="jms-wrapper"/>' ).parent(); // transition speed for the wrapper bgcolor this.$jmsWrapper.css( { '-webkit-transition-duration' : this.options.bgColorSpeed, '-moz-transition-duration' : this.options.bgColorSpeed, '-ms-transition-duration' : this.options.bgColorSpeed, '-o-transition-duration' : this.options.bgColorSpeed, 'transition-duration' : this.options.bgColorSpeed } ); // add navigation arrows if( this.options.arrows ) { this.$arrows = $( '<nav class="jms-arrows"/>' ); if( this.slidesCount > 1 ) { this.$arrowPrev = $( '<span class="jms-arrows-prev"/>' ).appendTo( this.$arrows ); this.$arrowNext = $( '<span class="jms-arrows-next"/>' ).appendTo( this.$arrows ); } this.$el.append( this.$arrows ) } // add navigation dots if( this.options.dots ) { this.$dots = $( '<nav class="jms-dots"/>' ); for( var i = this.slidesCount + 1; --i; ) { this.$dots.append( ( i === this.slidesCount ) ? '<span class="jms-dots-current"/>' : '<span/>' ); } if( this.options.jmpressOpts.start ) { this.$start = this.$jmsWrapper.find( this.options.jmpressOpts.start ), idxSelected = 0; ( this.$start.length ) ? idxSelected = this.$start.index() : this.options.jmpressOpts.start = null; this.$dots.children().removeClass( 'jms-dots-current' ).eq( idxSelected ).addClass( 'jms-dots-current' ); } this.$el.append( this.$dots ) } },
We will initialize the jmpress plugin in the _initImpress function. We will also redefine the “setActive” method of jmpress in order to switch the active navigation dot.
_initImpress : function() { var _self = this; this.$jmsWrapper.jmpress( this.options.jmpressOpts ); // check if supported (function from jmpress.js): // it adds the class not-suported to the wrapper this.support = !this.$jmsWrapper.hasClass( 'not-supported' ); // if not supported remove unnecessary elements if( !this.support ) { if( this.$arrows ) { this.$arrows.remove(); } if( this.$dots ) { this.$dots.remove(); } return false; } // redefine the jmpress setActive method this.$jmsWrapper.jmpress( 'setActive', function( slide, eventData ) { // change the pagination dot active class if( _self.options.dots ) { // adds the current class to the current dot/page _self.$dots .children() .removeClass( 'jms-dots-current' ) .eq( slide.index() ) .addClass( 'jms-dots-current' ); } // delete all current bg colors this.removeClass( _self.colors ); // add bg color class this.addClass( slide.data( 'color' ) ); } ); // add step's bg color to the wrapper this.$jmsWrapper.addClass( this.$jmsWrapper.jmpress('active').data( 'color' ) ); },
The _startSlideshow and _stopSlideshow will start and stop the slideshow respectively if the option autoplay is set to true.
// start slideshow if autoplay is true _startSlideshow : function() { var _self = this; this.slideshow = setTimeout( function() { _self.$jmsWrapper.jmpress( 'next' ); if( _self.options.autoplay ) { _self._startSlideshow(); } }, this.options.interval ); }, // stops the slideshow _stopSlideshow : function() { if( this.options.autoplay ) { clearTimeout( this.slideshow ); this.options.autoplay = false; } },
Finally, we load the events for the navigation arrows and dots. The touchend event is already defined in the jmpress plugin, but we will need to stop the slideshow in case this event is triggered:
_loadEvents : function() { var _self = this; // navigation arrows if( this.$arrowPrev && this.$arrowNext ) { this.$arrowPrev.on( 'click.jmslideshow', function( event ) { _self._stopSlideshow(); _self.$jmsWrapper.jmpress( 'prev' ); return false; } ); this.$arrowNext.on( 'click.jmslideshow', function( event ) { _self._stopSlideshow(); _self.$jmsWrapper.jmpress( 'next' ); return false; } ); } // navigation dots if( this.$dots ) { this.$dots.children().on( 'click.jmslideshow', function( event ) { _self._stopSlideshow(); _self.$jmsWrapper.jmpress( 'goTo', '.jmstep' + ( $(this).index() + 1 ) ); return false; } ); } // the touchend event is already defined in the jmpress plugin. // we just need to make sure the slideshow stops if the event is triggered this.$jmsWrapper.on( 'touchend.jmslideshow', function() { _self._stopSlideshow(); } ); }
And that’s it! I hope you enjoyed this tutorial and find it useful!
Damn hot one!
How do you change the transitions to something more simple like a “fade in” or “ease out” only…vs. the variation that’s on there now?
Hey! Thank you for the great sharing.
It’d definitely one of the best jQuery content slider I’ve ever seen.
Amazing!
Hello Mary,
Could you respond to what I said re: iPhone? It isn’t responsive, and from the body copy of this article it says that it is?
Can someone post how to add slider to the code so you get the slider animations in IE?
Hi.. Does this work on Samsung Galaxy Tabs?
Did you find any solution for IPHONE? Thx!
this gallery doesnt work on mobile devices, do you know some solution?
Mary Lou your posts are fantastic!
I cannot even begin to tell you how much time, frustration and hair pulling you have saved me.
Your work is extremely professional and FRIKKEN COOL.
Please don’t stop, keep it coming.
Thank you again!
Hi all, was trying to resize the dimension of the slideshow. but the text looks like jugged or pixelated? any ideas?
Looking forward.
Fantastic tutorial – thank you very much!
I just have one query – how can I set up the “dots” to each have a unique ID, instead of them all just being identical “span”s?
If they can somehow be given IDs then they can be styled to act as buttons.
Is this possible? Thanks in advance! 🙂
quick question: how can we set the time to stay the slide for about 5second? any ideas? thanks
jojo
add jmpress.duration plugin to jmpress.js
and regulate duration tru class=”step” data-duration=”5000″
Hi, How can I enable the click on the presentacion?… Another issue… I am putting some input text tags and its not posible to click on them…. Why?… How can I enable the click on any html5 tag?
@ Andreas Hecht
Works in IE7, IE8 and IE9 – of course not with the same effects, but the slider can be used with the Internet Explorer too.
Good job, Mary Lou!
Well, not exactly. You get this with IE8:
IE8 bug
And these with Safari:
Safari bug 1
Safari bug 2
All of them in ‘autoplay’ mode. Pity, because I think the slider is soooo good!!
Any tips to solve those?
Thanks in advance.
Ooooops, sorry, it seems I didn’t make link tags to work in my last post.
Images for bugs in ‘autoplay’ mode you can see at these urls:
IE8 bug: http://www.ficoprieto.com/rufus3/ie8_bug.jpg
Safari bug 1: http://www.ficoprieto.com/rufus3/Safari_bug.jpg
Safari bug 2: http://www.ficoprieto.com/rufus3/Safari_bug2.jpg
Thanks again.
@whitecreek
Thanks for pointing and discovering bug related to IE and autoplay.
I solved problem with if ( $.browser.msie )
I’m having the same problem as whitecreek had so I tried incorporating your code into my project however I’m not quite sure how to include it.
If you could help me out that would be great.
Thanks
I have the same problem with Chrome. If you could help me, thanks.
Yo!
Impressive work !! Very nice! it’s one of the best slideshow i ever seen!
Do you think you can add play/pause buttons easily ? it would be great !!! ^^
I used it to build an fullscreen slideshow presentation on google Canary, it’s amazing!
Thanks 🙂
Nice one!
The only problem I am having is that links (except the last slide one) do not work…
This is beautiful thank you!
I was able to get it to work for the most part in regards to customizing with images, except my links aren’t working either.
Is there something that I need to adjust?
This is so cool. I’m working on this within WordPress but I’m not too familiar with javascript. How can I pass the background color from PHP to be used in the javascript instead of using the CSS used in the example here?
The ‘Safari’ bugs mentioned also happen on Chrome on Win XP (the data-rotate-y and data-rotate-x commands cause it). In fact the animations don’t work on XP at all, but works fine with identical browser versions running on Win 7.
Hello,
Thanks for the slideshow !
– Is it possible to stop the slideshow onclick ?
– Is it possible to integrate a video ?
It’s nice but it doesn’t slide in IE9. I have seen many slides tutorials here but never one that works perfectly in all browsers.
Hi Cass, thanks for your feedback! I know, it’s sad but all the new CSS3 magic is simply not supported in IE9. We are trying more to leverage the power of new web technologies rather than focus on cross-browser compatibility (non-modern browsers) of the effect itself. Cheers, ML
Try to install an add-on called Chrome Frame on your IE9, it should work perfectly. Here’s the link: https://developers.google.com/chrome/chrome-frame/
HI Mary, i have a oneppage side and i need several of the slider(when you come to the page you see on slider(100%/100%)) now when you scroll down youll come to the next. my problem ist that i always see only the first slider and not the next ones. if i look through it with firebug i can see that the actual slider ist ther but is noch activated, so i guess the problem is that there is always only on activated slider but i need everyone to be active hmm any idea?
Gorgeous slider – I love the effects. Thank you!!
But I’m seeing some odd behavior in Firefox when I decrease the size on my browser window. The images either flicker or disappear entirely.
I’m concerned because the place I need to use it in my site is only about 900px wide, and when I view the demo at that width, I see the issue.
this.$start = this.$jmsWrapper.find( this.options.jmpressOpts.start ), idxSelected = 0;
Can anyone explain a little bit about what this snippet means?
I love this! However, I’ve done something to cause the .step image positioning to not work with Firefox… I’m guessing that it’s something to do with the scaling, but can’t work it out. Can anyone offer any suggestions? The site is not responsive, so I could remove that aspect if required?
http://momoled.com/home.php
Thanks!
My mistake. My FF was zoomed in, and thus creating the error…
Great slider, however I was wondering if is possible to auto-resume the slide when the mouse moves out of the slide object ? I tried but I can’t seem to find out how to do it 🙁
Mary Lou,
I have successfully integrated the plugin into a wordpress theme which is responsive to small screens. Every slider with the theme is compatible with all screens. But when I implemented this slideshow-with-jmpress-js and checked on small screens. I see it is not responsive and appearing as normal
Can you please tell me if I am missing something?
I really want these slider. 🙂
just a question, what will happen if it is viewed in ie6 or ie7? thanks
Yes man, its working in IE, but not with animation mode.
but we can compromise in this problem. because most of peoples f**ks IE 😉
You guys really awesome..
thanks !
Hi, excellent tutorial.
How can I change the size of the slideshow.
Thank you!
Miguel
Fantastic, but it looks bad in Explorer 7 and can not be viewed on the iPhone 4 (in the ipad 2 is perfect).
Thank you!
Anybody know how to use this Templates http://dontkry.com/jmpress.js/docs/#docs-templates with this? I am trying to use it with CMS, so I can’t set a Inline Attributes for each step manually.
Is it real to insert more then one slider per page?
@ Julian:
If you removed these: data-x=”2000″ data-y=”1000″ data-z=”3000″ data-rotate=”-20″
on “steps”, then only last button works. You need to keep them. I was trying to remove them since I don’t like animation (and just keep fade in/out) but no luck.
@jojo:
you can change it on line 41 on jquery.jmslideshow.js
just make changes to numbers on a line that looks like this:
interval : 7000
I have a question. Let’s say I want to use this gallery to be used for responsive content (not just images) like have blog posts, maybe some featured article etc. By being responsive in the layout, my height is going to change with each slide, because somewhere the text is going to break lines etc. How would I modify the plugin so instead of having fixed height and responsive width, I have responsive width AND responsive height? is that even possible in this case? Thanks
Hello there, thanks for a wonderful tutorial. I’m now trying to implement this in my website and I want it to be controlled by the keyboard “left” and “right” arrows too. But, when I change the value of keyboard : {use:false}, to keyboard : {use:false}, it doesn’t work. Can you or anybody help me?
Thank you guys for this amazing slider!
But I have a question: Is it possible to use only one effect? I would like to slide every time with a simple effect from left to right. No rotation or something else. Is that possible?
Best regards from Germany
Hi, How can i change The navigation dots bottom: to text menu . like i need to put some text replace that 5 dots.
please help.
Many Thanks.)
Incredible slideshow! Thanks for the aportation.
How can I do something like (onHoverStop:”on”). To stop or pause the transition/animation on hover.
Thanks,
Pablo
very nice indeed! does anybody know how to crosslink between slides? I have looked in the docs of jmpress jquery but I can’t seem to get it working
I finds it finally 🙂 for those interested, just use href=”#yourslideID” and give the step an ID, but don’t forget to set hash: { use : true }, wich was why it didn’t work for me
Hola, me encanta tu pagina y tu manera de explicar las cosas. Eres excelente.
Tus tutoriales son fantásticos !!!!!!!!!!
saludos ^^