Elastic Content Slider

A fluid content slider that will adjust in width and height depending on the size of its parent.

Elastic Content Slider

This Blueprint is a simple jQuery content slider. It has a sliding area for content and a tab-like navigation at the bottom. The slider is fluid, meaning that it will adjust to the parent’s container width and height. A couple of media queries show how to minimalise the look by just leaving icons for the navigation when the screen is very small. The content area will become scrollable if there isn’t enough space available. Every list item is a slide and and it has a corresponding link element in the navigation.

Note that we don’t show vendor prefixes here, but you’ll find them in the files. Also note that we use box-sizing: border-box by default for all elements.

The HTML

<div id="cbp-contentslider" class="cbp-contentslider">
	<ul>
		<li id="slide1">
			<h3 class="icon-wolf">Wolf</h3>
			<div>
				<div class="cbp-content">
					<p><!-- ... --></p>
				</div>
			</div>
		</li>
		<li id="slide2">
			<h3 class="icon-rabbit">Rabbit</h3>
			<div>
				<div class="cbp-content">
					<p>Chicory collard greens tatsoi cress bamboo shoot broccoli rabe lotus root earthnut pea arugula okra welsh onion leek shallot courgette. Chard garlic fava bean pea sprouts gram spinach plantain tomatillo. Chicory garlic black-eyed pea gourd chickpea cucumber lotus root.</p>
					<p>Daikon artichoke gumbo azuki bean bok choy avocado winter purslane gram earthnut pea broccoli salsify squash plantain wattle seed wakame broccoli rabe bamboo shoot. Zucchini lotus root azuki bean epazote dulse pumpkin rutabaga spinach. Endive mung bean gumbo maize plantain rock melon.</p>
				</div>
			</div>
		</li>
		<li id="slide3">
			<!-- ... -->
		</li>
		<li id="slide4">
			<!-- ... -->
		</li>
		<li id="slide5">
			<!-- ... -->
		</li>
	</ul>
	<nav>
		<a href="#slide1" class="icon-wolf"><span>Wolf</span></a>
		<a href="#slide2" class="icon-rabbit"><span>Rabbit</span></a>
		<a href="#slide3" class="icon-aligator"><span>Aligator</span></a>
		<a href="#slide4" class="icon-turtle"><span>Turtle</span></a>
		<a href="#slide5" class="icon-platypus"><span>Platypus</span></a>
	</nav>
</div>

The CSS

@font-face {
	font-family: 'icomoon';
	src:url('../fonts/icomoon.eot');
	src:url('../fonts/icomoon.eot?#iefix') format('embedded-opentype'),
		url('../fonts/icomoon.svg#icomoon') format('svg'),
		url('../fonts/icomoon.woff') format('woff'),
		url('../fonts/icomoon.ttf') format('truetype');
	font-weight: normal;
	font-style: normal;
}

/* Needed for a fluid height: */
html, body, .container, .main { height: 100%;}

/* main wrapper */
.cbp-contentslider {
	width: 100%;
	height: 70%;
	margin: 1em auto;
	position: relative;
	border: 4px solid #47a3da
}

.cbp-contentslider > ul {
	list-style: none;
	height: 100%;
	width: 100%;
	overflow: hidden;
	position: relative;
	padding: 0;
	margin: 0;
}

.cbp-contentslider > ul li {
	position: absolute;
	width: 100%;
	height: 100%;
	left: 0;
	top: 0;
	padding: 1em;
	background: #fff;
}

/* Whithout JS, we use :target */
.cbp-contentslider > ul li:target {
	z-index: 100;
}

.cbp-contentslider nav {
	position: absolute;
	bottom: 0;
	left: 0;
	right: 0;
	height: 3.313em;
	z-index: 1000;
	border-top: 4px solid #47a3da;
	overflow: hidden;
}

.cbp-contentslider nav a {
	float: left;
	display: block;
	width: 20%;
	height: 100%;
	font-weight: 400;
	letter-spacing: 0.1em;
	overflow: hidden;
	color: #47a3da;
	background: #fff;
	outline: none;
	text-align: center;
	line-height: 3;
	position: relative;
	padding-left: 3.125em;
	text-transform: uppercase;
	border-right: 4px solid #47a3da;
	-webkit-transition: color 0.2s ease-in-out, background-color 0.2s ease-in-out;
	-moz-transition: color 0.2s ease-in-out, background-color 0.2s ease-in-out;
	transition: color 0.2s ease-in-out, background-color 0.2s ease-in-out;
}

.cbp-contentslider nav a span {
	display: block;
}

.cbp-contentslider nav a:last-child {
	border: none;
	box-shadow: 1px 0 #47a3da; /* fills gap caused by rounding */
}

.cbp-contentslider nav a:hover {
	background-color: #47a3da;
	color: #fff;
}

.cbp-contentslider nav a.rc-active {
	background-color: #47a3da;
	color: #fff;
}

/* Iconfont for navigation and headings */
.cbp-contentslider [class^="icon-"]:before, 
.cbp-contentslider [class*=" icon-"]:before {
	font-family: 'icomoon';
	font-style: normal;
	text-align: center;
	speak: none;
	font-weight: normal;
	line-height: 2.5;
	font-size: 2em;
	position: absolute;
	left: 10%;
	top: 50%;
	margin: -1.250em 0 0 0;
	height: 2.500em;
	width: 2.500em;
	color: rgba(0,0,0,0.1);
	-webkit-font-smoothing: antialiased;
}

.cbp-contentslider .icon-wolf:before {
	content: "56";
}

.cbp-contentslider .icon-rabbit:before {
	content: "52";
}

.cbp-contentslider .icon-turtle:before {
	content: "54";
}

.cbp-contentslider .icon-platypus:before {
	content: "42";
}

.cbp-contentslider .icon-aligator:before {
	content: "41";
}

.cbp-contentslider [class^="icon-"].rc-active:before, 
.cbp-contentslider [class*=" icon-"].rc-active:before,
.cbp-contentslider nav a:hover:before {
	color: rgba(255,255,255,0.9);
}

.cbp-contentslider h3 {
	font-size: 4em;
	height: 2em;
	line-height: 1.7;
	font-weight: 300;
	margin: 0 0 0.3em;
	position: relative;
	color: #47a3da;
	text-transform: uppercase;
	text-align: right;
	letter-spacing: 0.3em;
	padding: 0 0.2em 0 0;
	border-bottom: 4px solid #47a3da;
}

.cbp-contentslider h3[class^="icon-"]:before, 
.cbp-contentslider h3[class*=" icon-"]:before {
	top: 0;
	left: 0;
	width: 2em;
	line-height: 1;
	height: 1.2em;
	margin: 0;
	color: #47a3da;
}

.cbp-contentslider li > div {
	position: absolute;
	top: 9em;
	bottom: 3.313em;
	width: 100%;
	left: 0;
	padding: 0 1em;
	overflow-x: hidden;
	overflow-y: auto;
}

.cbp-contentslider .cbp-content {
	-webkit-column-rule: 1px dashed #47a3da;
	-moz-column-rule: 1px dashed #47a3da;
	column-rule: 1px dashed #47a3da;
	-webkit-column-count: 2;
	-moz-column-count: 2;
	-o-column-count: 2;
	column-count: 2;
	-webkit-column-gap: 1em;
	-moz-column-gap: 1em;
	-o-column-gap: 1em;
	column-gap: 1em;
	vertical-align: top;	
	padding: 1em 0;
}

.cbp-contentslider p {
	color: #47a3da;
	padding: 0 0.5em 0.4em;
	margin: 0;
	font-size: 1.2em;
	font-weight: 300;
	text-align: justify;
	line-height: 1.6;
}

/* Media queries */

@media screen and (max-width: 70em) { 
	.cbp-contentslider p {
		font-size: 100%;
	}
}

@media screen and (max-width: 67.75em) {

	.cbp-contentslider { font-size: 85%; }

	.cbp-contentslider nav a[class^="icon-"]:before, 
	.cbp-contentslider nav a[class*=" icon-"]:before {
		left: 50%;
		margin-left: -1.250em;
	}

	.cbp-contentslider nav a span {
		display: none;
	}
}

@media screen and (max-width: 43em) {

	.cbp-contentslider h3 {
		font-size: 2em;
	}

	.cbp-contentslider .cbp-content {
		-webkit-column-count: 1;
		-moz-column-count: 1;
		-o-column-count: 1;
		column-count: 1;
	}

	.cbp-contentslider li > div {
		top: 5em;
	}

}

@media screen and (max-width: 25em) { 
	.cbp-contentslider nav a { padding: 0;}
	.cbp-contentslider h3[class^="icon-"]:before, 
	.cbp-contentslider h3[class*=" icon-"]:before { display: none;}
}

The JavaScript

;( function( $, window, undefined ) {

	'use strict';

	// global
	var Modernizr = window.Modernizr;

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

	// the options
	$.CBPContentSlider.defaults = {
		// default transition speed (ms)
		speed : 500,
		// default transition easing
		easing : 'ease-in-out',
		// current item´s index
		current : 0
	};

	$.CBPContentSlider.prototype = {
		_init : function( options ) {

			// options
			this.options = $.extend( true, {}, $.CBPContentSlider.defaults, options );
			// the items
			this.$items = this.$el.find( 'ul > li' ).hide();
			// the tabs
			this.$tabs = this.$el.find( 'nav > a' );
			// total tabs
			var tabsCount = this.$tabs.length;
			// set each tab width
			this.$tabs.css( 'width', 100 / tabsCount + '%' );
			// current and old item´s index
			this.current = this.options.current;
			this.old = 0;
			// check if the items are currently moving
			this.isAnimating = false;
			// support for CSS Transitions
			this.support = Modernizr.csstransitions;
			// transition end event name
			var transEndEventNames = {
				'WebkitTransition' : 'webkitTransitionEnd',
				'MozTransition' : 'transitionend',
				'OTransition' : 'oTransitionEnd',
				'msTransition' : 'MSTransitionEnd',
				'transition' : 'transitionend'
			};
			this.transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ] + '.cbpContentSlider';
			// set the transition to the items
			if( this.support ) {
				this.$items.css( 'transition', 'left ' + this.options.speed + 'ms ' + this.options.easing );
			}
			// update current tab
			this._updateTabs();
			// show current item
			this.$items.eq( this.current ).show();
			// initialize/bind the events to the tabs
			this._initEvents();

		},
		_updateTabs : function() {
			this.$tabs.eq( this.old ).removeClass( 'rc-active' ).end().eq( this.current ).addClass( 'rc-active' );
		},
		_initEvents : function() {

			var self = this;
			this.$tabs.on( 'click.cbpContentSlider', function( event ) {
			
				var idx = $( this ).index();
				
				if( idx !== self.current && !self.isAnimating ) {
					
					self.isAnimating = true;

					var direction = idx > self.current ? 'right' : 'left',
						$oldItem = self.$items.eq( self.current ),
						$newItem = self.$items.eq( idx );
					
					// update current and old value
					self.old = self.current;
					self.current = idx;

					// apply initial style..
					if( self.support ) {
						// translate might be more efficient here. Left out because of a rounding and rendering problem in Chrome (Version 24.0.1312.52)
						$newItem.css( 'left', direction === 'right' ? '100%' : '-100%' );
					}
					$newItem.show();

					// ..and bind the transitionend event
					var transitionendfn = function() {
						$oldItem.off( self.transEndEventName ).hide();
						self.isAnimating = false;
					};

					if( self.support ) {
						$oldItem.on( self.transEndEventName, transitionendfn );
					}
					else {
						transitionendfn.call();
					}
					
					// apply final style
					if( self.support ) {
						setTimeout( function() {
							// translate might be more efficient here. Left out because of a rounding and rendering problem in Chrome (Version 24.0.1312.52)
							$oldItem.css( 'left', direction === 'right' ? '-100%' : '100%' );
							$newItem.css( 'left', '0%' );
						}, 25 );
					}

					// update current tab
					self._updateTabs();

				}

				event.preventDefault();

			} );

		},
		destroy : function() {
			if( this.support ) {
				this.$items.css( 'transition', 'none' );
			}
			this.$items.css( 'left', 0 ).show();
			this.$tabs.off( '.cbpContentSlider' ).removeClass( 'rc-active' );
		}
	};

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

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

Comments are closed.
  1. Hmm very interesting and insightful.

    I would like to suggest another tutorial though, a three column (or 1+n columns) elastic list slider that has on each column an image and text. How can this be implemented and be responsive?

  2. This component is very useful, though I think it’s better if on smaller screens the tabs are floated to the right aligned vertically on each other !!

  3. Hi there! i am new in web design, i was wondering how can i change the icons? for sure its something easy but i don know how to do it, help me please!

  4. interesting use of font dingbats as icons

    where do the values come from?
    i.e. content: “\56”;

  5. is there a function that calls directly a tab?

    Like

    $cbpContentSlider.goToTab(‘3’);

    ?

  6. I am working on a website using this blueprint and it is working very nicely – just what I needed. I have one question, however – a number of the slides have a links on them, and it would be ideal if after visiting a given link the browser would return to the same slide if the back button was pressed. When I navigate back with the back button now, the browser always resets to the first slide. I there a way around this?

  7. Greetings from argentina!
    hello! Nice tutorial. It’really good!
    But how can i change the icons!? I like animals 🙂 but i need others!
    I noticed tha you used iconmoon icons! How can i use other icons from there?

  8. Hello, i need to add a link to open a different page but neither “” tags or input buttons are not working when i put into
    How is it posibble?
    Can you help me please?

    Thanks again for the tutorial!

  9. Hi from Uruguay! Great site! I can´t see scrollbars when viewing in a smartphone…. How can I solve this? Thanks

    • Yes, I have the same problem (almost the same)… When I try my custom page offline it works just fine (on IE10), but when I set it online (calling the page with an PHP include), the script doesn’t work well on IE10!

      Please help!

  10. I loved the slider, but I found that the navigation at the bottom is hit and miss. It sometimes works, and it sometimes doesn’t…

    • There’s a isAnimating flag for when the slider is animating. While the slider is animating, the navigation is not active. So if you set a longer transition time, the navigation will not work while animating. I guess this could be the problem you described, but this is normal behaviour if you think of it.

  11. What would be the best way to implement a history function or the ability to have the user be able to use the back button?

  12. Hi. Nice, but I the scroll bar in the div content did not appear on my mobile device and the div itself not high enough to show more than 2 lines of text. So, couldn’t get it to work effectively. Perhaps it’s my mobile devices navigator platform. It’s Android. Scroll bars do appear on the laptop size version and looks great.

    Any ideas about the lack of scroll bars and the reduced height of the content div on the mobile device ?

    Cheers.

  13. This script (or another on Codrops) are kinda useless because the contributors doesn’t give support of any kind! Ther’re lot of people asking for questions or help and Mary Lou doesn’t give any support… It’s a pitty.

    • I see your frustration Davis, but calling them “useless” is a bit harsh, don’t you think? We have hundreds of support requests every day via mail and comments, we simply can’t provide support on this level. We are working hard every day so that we can provide new tutorials and Blueprints for free each week. If we would provide support, we wouldn’t be able to do that. If there are major problems concerning our code we of course try to correct and improve it, but we can’t help with extending things, integrating them or with modifications. There are many community-based websites where you can ask for support and help. I hope you understand. Cheers, ML

    • It was a bit harsh. Mary Lou (or other programmers) provides free tutorials, codes because of passion. They are not obliged to give any support. If you want a 24/7 support, then you should hire a programmer and ask him/her.

      You are getting something for without spending a cent. Be greatful to it.

    • As usual, beautiful work Mary! Thank you!

      A note for those seeking support. As per Mary’s comment, providing support would be nearly impossible for the team.

      The tools implemented in these tutorials are commonly used and not special to Tympanus. You can easily find support in other places. For instance, try stackexchange.com. Open up a ticket, provide the code you used, explain your attempts to fix it, and ask nicely. You’d be amazed how many (and how quickly) people are willing to help out.

  14. Dear Mary Lou . I am JIang.

    I came upon your site and noticed your meke ELASTIC CONTENT SLIDER. I would like to use. I plan on using ELASTIC CONTENT SLIDER for Individual business and would like to know if I may have permission to do so or if it would be possible for a small fee. If the price is right, I may think about this as an option as well.
    JIang.

  15. This is great slider for full screen. But it is not auto slide. Is any option for auto slide ?

  16. HI Mary. thanks for you. i was browsing and i find this useful for my little presentation.

    I have one question. Can you or anyone here can solve this for me. At the bottom, there is a big white space. Can this space be removed. I think its somethings to do with the component.css

    /* Needed for a fluid height: */
    html, body, .container, .main { height: 100%;}

    i tried playing around with it but i just cant figure out how to remove that white

    • I separated the code to be like this:

      html, body, .container, {
      height: 100%;
      }

      .main {
      height: SET SPECIFIC PX HEIGHT HERE;
      }

      Worked for me.

  17. Hi Mary, thanks for sharing this tutorial… but i need help with content slide – when i try add inside ul/li element is not working:

    VALUE #1

    CPU
    RAM

    as you can see script add style to li element making it non visible. It is any way to fix it?

    Thanks for your help.

  18. Mary,

    Great work here. I love the concepts! I am having trouble implementing some of the content on my website. I keep getting 403-permission denied once everything is uploaded. Any idea how I can fix that?

    Johnny

  19. How Can set slide to X outside nav tag manually ? ( via a tag or via javascript manually or other methods )

  20. Hi Mary, this is Andrea 🙂
    I don’t expect any kind of support for a free product, and I thank you really much for this freebie;
    but I’d like to know how is possible to autoplay the slider, if it’s possible 😉
    Thanks again.

  21. Love the plugin Mary Lou (as well as all of your other contributions) – I’m currently building a site using this plugin. However, on the first slide I am trying to nest the Fixed Background Scrolling Layout plugin – inevitably there are a number of conflicts. What advise would you give to try and achieve this? Would using iframes resolve this issue? Thanks!

  22. Really, I stuck for a moment after visit all the awesome creativity.

    Still we love to open source and only due to the people like you live in this world.

    I have proud of you and your intelligent mind’s creativity.

    Hearty Thank you so much..
    Best Luck,
    Praful

  23. I really like this content slider. However, I’d like to change the class for each section and have a different color or background image for each one. How can I go about doing this? I see the this.current section and was able to change the class for ALL tabs but how about individual tabs? Thanks!

  24. I am not a code person, but I would love to learn how to add this code to a wordpress page or post.

    Here is how I thought I could use it:
    I use Royal Custom CSS for changing/adding CSS, and I know I can place the Html on the Text tab, where do I place the Java?

  25. Hi Mary Lou

    Great Work.

    How to make it as auto height?
    How to make it as two menu tabs(i.e. header and footer menu tabs).

    Waiting for your reply.

    Thank You.
    Thanks and Regards
    Padmanathan

  26. Any way to make it scroll in IE9? It simply jumps from one screen to the next, doesn’t ‘slide’.

    Thx

  27. Thanks for creating and posting these blueprints. I’m fairly new (OK very new) to web design and this has been a big help to my learning process.
    The method you used to display the icons was new to me. I checked out the icomoon website so I think I get now. Seems like a good way to make the code flow a little better. code flow 🙂 Enjoyed the vegetable list as well 🙂
    Thanks

  28. this is a great plugin, but it does not work with Android phone with its standard browsers that it comes with, it however works on the chrome.

  29. Hi, i want two content slider component on single page. is this possible? I had tried but only one is working.

    • I found a work around, by destroying one slider but the problem is that on second slider class “rc-active” is not added on second slider.

    • I found it:

      Just add a second and give it anohter ID

      $(function() {
      $( ‘#contentslider_work’ ).cbpContentSlider();
      });

      $(function() {
      $( ‘#contentslider_about’ ).cbpContentSlider();
      });

  30. Hi…

    Great plugin!! Would really like to use this as a part of the navigation im working on..
    Therefor want to ajax the content of the sub-pages for better performance..
    Unfortunaly just found out hash doesn’t work…

    Any advice??
    Many thanks in advance :D!!

  31. Hi.,
    This is very nice and also helpful to improve my knowledge in Jquery.. And thanks once again

  32. I have added it to website but it kinda works. I have a problem with the detailed part of it. It displays the bottom icons and text but it will not show the information and other stuff in the panel above. Help!!

  33. This is a great plugin and I really want to use it on a website at work but I need to keep the href attribute free to link to other pages. Is there anyway this can be adapted so that onmouseover can be used on the nav to trigger the slider… thanks!