Responsive Full Width Tabs

100% width tabbed content with some example media queries for smaller screens.

BlueprintFullWidthTabs

View demo Download source

A full width tab component with some example media queries for adjusting the icons of the tabs and the content layout. The main idea is to show only icons for the mobile view and allow the text to appear when there’s enough space. The content columns and the containing media boxes have three different layouts.

The food shapes in the content images are from PsdBlast. The icons used in the tabs are by DesignModo and the icon font was created using the Icomoon App.

The HTML

<div id="tabs" class="tabs">
	<nav>
		<ul>
			<li><a href="#section-1" class="icon-shop"><span>Shop</span></a></li>
			<li><a href="#section-2" class="icon-cup"><span>Drinks</span></a></li>
			<li><a href="#section-3" class="icon-food"><span>Food</span></a></li>
			<li><a href="#section-4" class="icon-lab"><span>Lab</span></a></li>
			<li><a href="#section-5" class="icon-truck"><span>Order</span></a></li>
		</ul>
	</nav>
	<div class="content">
		<section id="section-1">
			<div class="mediabox">
				<img src="img/01.png" alt="img01" />
				<h3>Sushi Gumbo Beetroot</h3>
				<p>Sushi gumbo beet greens corn soko endive gumbo gourd. Parsley shallot courgette tatsoi pea sprouts fava bean collard greens dandelion okra wakame tomato.</p>
			</div>
			<div class="mediabox">
				<img src="img/02.png" alt="img02" />
				<h3>Pea Sprouts Fava Soup</h3>
				<p>Lotus root water spinach fennel kombu maize bamboo shoot green bean swiss chard seakale pumpkin onion chickpea gram corn pea.</p>
			</div>
			<div class="mediabox">
				<img src="img/03.png" alt="img03" />
				<h3>Turnip Broccoli Sashimi</h3>
				<p>Nori grape silver beet broccoli kombu beet greens fava bean potato quandong celery. Bunya nuts black-eyed pea prairie turnip leek lentil turnip greens parsnip.</p>
			</div>
		</section>
		<section id="section-2">
			<div class="mediabox">
				<img src="img/04.png" alt="img04" />
				<h3>Asparagus Cucumber Cake</h3>
				<p>Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. </p>
			</div>
			<div class="mediabox">
				<img src="img/05.png" alt="img05" />
				<h3>Magis Kohlrabi Gourd</h3>
				<p>Salsify taro catsear garlic gram celery bitterleaf wattle seed collard greens nori. Grape wattle seed kombu beetroot horseradish carrot squash brussels sprout chard.</p>
			</div>
			<div class="mediabox">
				<img src="img/06.png" alt="img06" />
				<h3>Ricebean Rutabaga</h3>
				<p>Celery quandong swiss chard chicory earthnut pea potato. Salsify taro catsear garlic gram celery bitterleaf wattle seed collard greens nori. </p>
			</div>
		</section>
		<section id="section-3">
			<div class="mediabox">
				<img src="img/02.png" alt="img02" />
				<h3>Noodle Curry</h3>
				<p>Lotus root water spinach fennel kombu maize bamboo shoot green bean swiss chard seakale pumpkin onion chickpea gram corn pea.Sushi gumbo beet greens corn soko endive gumbo gourd.</p>
			</div>
			<div class="mediabox">
				<img src="img/06.png" alt="img06" />
				<h3>Leek Wasabi</h3>
				<p>Sushi gumbo beet greens corn soko endive gumbo gourd. Parsley shallot courgette tatsoi pea sprouts fava bean collard greens dandelion okra wakame tomato.</p>
			</div>
			<div class="mediabox">
				<img src="img/01.png" alt="img01" />
				<h3>Green Tofu Wrap</h3>
				<p>Pea horseradish azuki bean lettuce avocado asparagus okra. Kohlrabi radish okra azuki bean corn fava bean mustard tigernut wasabi tofu broccoli mixture soup.</p>
			</div>
		</section>
		<section id="section-4">
			<div class="mediabox">
				<img src="img/03.png" alt="img03" />
				<h3>Tomato Cucumber Curd</h3>
				<p>Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. </p>
			</div>
			<div class="mediabox">
				<img src="img/01.png" alt="img01" />
				<h3>Mushroom Green</h3>
				<p>Salsify taro catsear garlic gram celery bitterleaf wattle seed collard greens nori. Grape wattle seed kombu beetroot horseradish carrot squash brussels sprout chard.</p>
			</div>
			<div class="mediabox">
				<img src="img/04.png" alt="img04" />
				<h3>Swiss Celery Chard</h3>
				<p>Celery quandong swiss chard chicory earthnut pea potato. Salsify taro catsear garlic gram celery bitterleaf wattle seed collard greens nori. </p>
			</div>
		</section>
		<section id="section-5">
			<div class="mediabox">
				<img src="img/02.png" alt="img02" />
				<h3>Radish Tomato</h3>
				<p>Catsear cauliflower garbanzo yarrow salsify chicory garlic bell pepper napa cabbage lettuce tomato kale arugula melon sierra leone bologi rutabaga tigernut.</p>
			</div>
			<div class="mediabox">
				<img src="img/06.png" alt="img06" />
				<h3>Fennel Wasabi</h3>
				<p>Sea lettuce gumbo grape kale kombu cauliflower salsify kohlrabi okra sea lettuce broccoli celery lotus root carrot winter purslane turnip greens garlic.</p>
			</div>
			<div class="mediabox">
				<img src="img/01.png" alt="img01" />
				<h3>Red Tofu Wrap</h3>
				<p>Green horseradish azuki bean lettuce avocado asparagus okra. Kohlrabi radish okra azuki bean corn fava bean mustard tigernut wasabi tofu broccoli mixture soup.</p>
			</div>
		</section>
	</div><!-- /content -->
</div><!-- /tabs -->
<script src="js/cbpFWTabs.js"></script>
<script>
	new CBPFWTabs( document.getElementById( 'tabs' ) );
</script>

The CSS

@font-face {
	font-family: 'icomoon';
	src:url('../fonts/icomoon/icomoon.eot?pvm5gj');
	src:url('../fonts/icomoon/icomoon.eot?#iefixpvm5gj') format('embedded-opentype'),
		url('../fonts/icomoon/icomoon.woff?pvm5gj') format('woff'),
		url('../fonts/icomoon/icomoon.ttf?pvm5gj') format('truetype'),
		url('../fonts/icomoon/icomoon.svg?pvm5gj#icomoon') format('svg');
	font-weight: normal;
	font-style: normal;
} /* Icons created with icomoon.io/app */

.tabs {
	position: relative;
	width: 100%;
	overflow: hidden;
	margin: 1em 0 2em;
	font-weight: 300;
}

/* Nav */
.tabs nav {
	text-align: center;
}

.tabs nav ul {
	padding: 0;
	margin: 0;
	list-style: none;
	display: inline-block;
}

.tabs nav ul li {
	border: 1px solid #becbd2;
	border-bottom: none;
	margin: 0 0.25em;
	display: block;
	float: left;
	position: relative;
}

.tabs nav li.tab-current {
	border: 1px solid #47a3da;
	box-shadow: inset 0 2px #47a3da;
	border-bottom: none;
	z-index: 100;
}

.tabs nav li.tab-current:before,
.tabs nav li.tab-current:after {
	content: '';
	position: absolute;
	height: 1px;
	right: 100%;
	bottom: 0;
	width: 1000px;
	background: #47a3da;
}

.tabs nav li.tab-current:after {
	right: auto;
	left: 100%;
	width: 4000px;
}

.tabs nav a {
	color: #becbd2;
	display: block;
	font-size: 1.45em;
	line-height: 2.5;
	padding: 0 1.25em;
	white-space: nowrap;
}

.tabs nav a:hover {
	color: #768e9d;
}

.tabs nav li.tab-current a {
	color: #47a3da;
}

/* Icons */
.tabs nav a:before {
	display: inline-block;
	vertical-align: middle;
	text-transform: none;
	font-weight: normal;
	font-variant: normal;
	font-family: 'icomoon';
	line-height: 1;
	speak: none;
	-webkit-font-smoothing: antialiased;
	margin: -0.25em 0.4em 0 0;
}

.icon-food:before {
	content: "\e600";
}

.icon-lab:before {
	content: "\e601";
}

.icon-cup:before {
	content: "\e602";
}

.icon-truck:before {
	content: "\e603";
}

.icon-shop:before {
	content: "\e604";
}

/* Content */
.content section {
	font-size: 1.25em;
	padding: 3em 1em;
	display: none;
	max-width: 1230px;
	margin: 0 auto;
}

.content section:before,
.content section:after {
	content: '';
	display: table;
}

.content section:after {
	clear: both;
}

/* Fallback example */
.no-js .content section {
	display: block;
	padding-bottom: 2em;
	border-bottom: 1px solid #47a3da;
}

.content section.content-current {
	display: block;
}

.mediabox {
	float: left;
	width: 33%;
	padding: 0 25px;
}

.mediabox img {
	max-width: 100%;
	display: block;
	margin: 0 auto;
}

.mediabox h3 {
	margin: 0.75em 0 0.5em;
}

.mediabox p {
	padding: 0 0 1em 0;
	margin: 0;
	line-height: 1.3;
}

/* Example media queries */

@media screen and (max-width: 52.375em) {
	.tabs nav a span {
		display: none;
	}

	.tabs nav a:before {
		margin-right: 0;
	}

	.mediabox {
		float: none;
		width: auto;
		padding: 0 0 35px 0;
		font-size: 90%;
	}

	.mediabox img {
		float: left;
		margin: 0 25px 10px 0;
		max-width: 40%;
	}

	.mediabox h3 {
		margin-top: 0;
	}

	.mediabox p {
		margin-left: 40%;
		margin-left: calc(40% + 25px);
	}

	.mediabox:before,
	.mediabox:after {
		content: '';
		display: table;
	}

	.mediabox:after {
		clear: both;
	}
}

@media screen and (max-width: 32em) {
	.tabs nav ul,
	.tabs nav ul li a {
		width: 100%;
		padding: 0;
	}

	.tabs nav ul li {
		width: 20%;
		width: calc(20% + 1px);
		margin: 0 0 0 -1px;
	}

	.tabs nav ul li:last-child {
		border-right: none;
	}

	.mediabox {
		text-align: center;
	}

	.mediabox img {
		float: none;
		margin: 0 auto;
		max-width: 100%;
	}

	.mediabox h3 {
		margin: 1.25em 0 1em;
	}

	.mediabox p {
		margin: 0;
	}
}

The JavaScript

/**
 * cbpFWTabs.js v1.0.0
 * http://www.codrops.com
 *
 * Licensed under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 * 
 * Copyright 2014, Codrops
 * http://www.codrops.com
 */
;( function( window ) {
	
	'use strict';

	function extend( a, b ) {
		for( var key in b ) { 
			if( b.hasOwnProperty( key ) ) {
				a[key] = b[key];
			}
		}
		return a;
	}

	function CBPFWTabs( el, options ) {
		this.el = el;
		this.options = extend( {}, this.options );
  		extend( this.options, options );
  		this._init();
	}

	CBPFWTabs.prototype.options = {
		start : 0
	};

	CBPFWTabs.prototype._init = function() {
		// tabs elemes
		this.tabs = [].slice.call( this.el.querySelectorAll( 'nav > ul > li' ) );
		// content items
		this.items = [].slice.call( this.el.querySelectorAll( '.content > section' ) );
		// current index
		this.current = -1;
		// show current content item
		this._show();
		// init events
		this._initEvents();
	};

	CBPFWTabs.prototype._initEvents = function() {
		var self = this;
		this.tabs.forEach( function( tab, idx ) {
			tab.addEventListener( 'click', function( ev ) {
				ev.preventDefault();
				self._show( idx );
			} );
		} );
	};

	CBPFWTabs.prototype._show = function( idx ) {
		if( this.current >= 0 ) {
			this.tabs[ this.current ].className = '';
			this.items[ this.current ].className = '';
		}
		// change current
		this.current = idx != undefined ? idx : this.options.start >= 0 && this.options.start < this.items.length ? this.options.start : 0;
		this.tabs[ this.current ].className = 'tab-current';
		this.items[ this.current ].className = 'content-current';
	};

	// add to global namespace
	window.CBPFWTabs = CBPFWTabs;

})( window );

View demo Download source

Previous:
Next:

Tagged with:

Mary Lou (Manoela Ilic) 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.

View all contributions by

Website: http://tympanus.net/

Related Articles

Feedback 70

    • 2

      Well, use your imagination ;)

      Fitting wide navigation into narrow screen is a problem with no obvious or best solution. This article showcases one idea. If you have a different layout and purpose, then think differently. The first idea that comes to mind is to stack navigation items on top of each other similar to way the paragraphs in the demo are being stacked.

  1. 3

    Hi everyone!
    I don’t think I’ve seen my question answered…
    What I want to do:
    Open the url where my tabs are in from another page, but forcing it to show a specific tab…

    for example: I’m in page1.html where there’s a link called “toTab3″. I want that link to get me to page2.html, where I have 4 tabs, showing the 3rd one.

    Makes sense?…. thanks in advance!

    • 4

      This is a common task but goes beyond the purposes of the demo which is to demonstrate an idea of a responsive tabbed nav.

      All you need to do is to set a class “active” (in this case “tab-current”) to the navigation item that you want highlighted as active. But how you do it depends on your website setup. One way is to set the back-end code appropriately, another is to use named anchor tags (http://www.w3.org/TR/html401/struct/links.html#h-12.2.1) along with javascript to check window.location.hash of the document and apply the active class to the corresponding navigation item.

    • 5

      I used these tabs on a site for a client and they were amazed by them!

      If you or anyone else is still looking for a way to force open a certain tab from a different page, here is my solution.

      Put a # and a number from 0 to how many tabs you have after the links to certain tabs.
      For example: i have 4 tabs and 4 links, one for each tab. I put #0, #1, #2, #3 after each link in order to open a specific tab.

      <a href="link-to-tab-1.php#0">tab 1</a>
      <a href="link-to-tab-2.php#1">tab 2</a>
      <a href="link-to-tab-3.php#2">tab 3</a>
      <a href="link-to-tab-4.php#3">tab 4</a>

      The js code needs some slight modifications as well.

      var x = window.location.hash;
      var last = x.slice(-1);

      CBPFWTabs.prototype.options = {
      start : last
      };

      Add the two lines of code above the prototype.options. The first line sets the variable x with the content from the URL after and including the #. The second line of code slices away just the last character of the link, in my case the numbers from 0 to 3.

      The start : last then sets the starting position tab according to the link pressed and voila, the tabs open accordingly to the pressed links.

      My tabs can be visible here uhy.si

  2. 6

    I’m trying to figure out how embed a youtube video inside of the media box, but I’m running into some problems.
    What are the best practices for this specific template?
    I haven’t been able to get the video to appear and I was wondering if you had any recommendations?

  3. 7

    The last 2 tabs in the demo do not extend the full width when in desktop mode.
    The left blue underline stops short from the browser edge…

    How do I go about fixing this?

  4. 8

    i using the Third tab when i reload the page the current tab will come once again to initial position of the tab

    example :

    in third tab current section have a textbox and other controls in a submit click the page reload in that situation it come to the First Tab

    Please Resolve it Say the way to rectify it

  5. 9

    Hi Mary Lou, Great script !! I have recently used this script on http://www.inspiredcreditmanagement.com.au and I was wondering if you know of a fix so that when viewing on desktop if you click a tab it takes you back to the top of that section? At present clicking any tab takes you to the scroll position/location within the next tab (if that makes sense). To test simply scroll to the bottom of the first tab and then click the second tab. Any ideas/solutions would be super appreciated :) Cheers, Phil.

  6. 10

    Hi,
    This works well but not in IE8 there is this error IE throws i tried modify .js but doesnt work still? can you pls check the .js,

    Message: JScript object expected
    Line: 37
    Char: 3
    Code: 0
    URI: file:///C:/ProjectTasks/FullWidthTabs/FullWidthTabs/cbpFWTabs.js

    thanks,

  7. 11

    HI
    This was work very well and great use full on my site.
    but i want fade effect on show item how to fix this one please reply as soon as possible.

  8. 12

    Not working on IE8, due to this “Array.prototype.slice: ‘this’ is not a JavaScript object”

    CBPFWTabs.prototype._init = function() {
    // tabs elemes
    this.tabs = [].slice.call( this.el.querySelectorAll( ‘nav > ul > li’ ) )
    [error]Array.prototype.slice: ‘this’ is not a JavaScript object[error]
    // content items
    this.items = [].slice.call( this.el.querySelectorAll( ‘.content > section’ ) );

Follow this discussion

Leave a Comment

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>