From our sponsor: Leverage AI for dynamic, custom website builds with ease.
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 );