Elastic Content Slider

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

From our monthly sponsor: Automate manual QA and catch visual bugs with Percy’s all-in-one visual testing and review platform.

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:

Mary Lou

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.

http://www.codrops.com

Receive our bi-weekly Collective or official newsletter right in your inbox.

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 learning CSS now.

Feedback 60

Comments are closed.
  1. 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.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Thx

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