Responsive Full Width Tabs

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

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 );

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 103

Comments are closed.
  1. Hi you can change the icons into names… just removed the and inside the tag and insert the desired name.. then try to view it but make sure use <meta name="viewport" and width ="device-width" to support mobile browser… 🙂

  2. Hi! =) This is all very interesting. Quick question. How does one set the tab when opening the page? Say I want it to open to tab 3 or tab 5, on the loading of the page?

    I’ve tried modifying the code and using parts that calls it from a link/external link. But it didn’t work for me. And I admit i’ve been up for like 24hrs working on something else, so my brain is fried. =)

    I’m going to work on it some more. =) But what is the easiest way to do this? Will help me learn the ins and outs and the technique of doing this.

    It’s really the only portion I’ve yet to understand, do I have to call something in your javascript? Probably? Or can it be external? Or both?

    Might crack this nut for a lot of people here. Or it might be totally easy. =) And I need caffeine. =)

    Thanks!

  3. Hi you can disregard my earlier question. =) After a mountain dew/caffeine. I opened up the js file for the tabs and found this:

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

    You can set the current tab here. Depending on your script/code/desire. Unless I need more caffeine. =)

    After reading through the comments I see there’s also similar one above, but the magic is here. As start is used below.

    So you could using php echo, or ruby to set this, or you could use jQuery or javascript or even create a function in the js code to set it. Sorry about the earlier note. Cheers, -C

  4. Here’s what I did. The quickest fastest way to open the page on a certain tab/section. Or to call a tab from a link or external page’s link.

    Is not to mess with the author’s code or change it. It does what it does. Hat’s off to them.

    But instead to stay outside of it and use it. Here’s the code to open on a certain tab/section.

    Change:
    new CBPFWTabs( document.getElementById( ‘tabs’ ) );

    to:

    new CBPFWTabs( document.getElementById( ‘tabs’ ),{ start : 3 } );

    You can then extrapolate that to use, php, ruby, javascript, jquery etc…to set the options, with no need to edit the tabs script. Wonder why this wasn’t suggested earlier. =) Why all the mechanization’s?

  5. thank for this script, i have width problem use with higcharts on 1 mediabox (i changed width 100% ), 1. section ok but other sections have this problem,

  6. As usual, great resource!
    Thank you a lot Mary Lou for sharing 🙂

    I’m using it (with some personal design custom) in my website and it works well!

    You can see it in action just here !

    Thank you again for all this work.

    Regards,
    Étien’

  7. How to make the tabs carousel when there are many tabs? Especially in mobile view?

  8. What elements cause the tab text to vanish as the brower window size shrinks?
    Also, I added a 6th tab and now when I resize the last tab wraps around and down. I have been unable to correct this.

  9. Hi Mary,Apologies as a newbie on sharepoint designing,how can i deploy this on my test environment. i know that i need to have the js,css and link both from the html and create a content editor webpart. how can i use ? please advise.

  10. It doesn’t seem to work in IE (I’m on version 11). Is there anything to add that will make it work?

  11. Hello,
    First of all thank you for this beautify template and code.
    Please tell me how to change the color of full width blue line after the nav
    Thanks

    • remove backgroud: #… from

      .tabs nav li.tab-current:before,
      .tabs nav li.tab-current:after {

      }

      or change the color

  12. Hi.
    First off – thank you for the great simple script. Works like a charm.
    Now, I have one question – would it be possible to open another tab from a link within a tab ?

    Ok, that got cryptic, let me try again:
    If I have a link within one of the tabs that update information inside a second tab.
    I would like to give focus automatically to that second tab, and open it.
    Does your script allow this or do I have to write the code myself 🙂 ?

  13. Hello, I’d love to add this to my site, but I don’t know hot to add this utility and also I can’t find an install guida. Please, anyone could point me to any guide to follow or an install process?

    Thanks a lot!

  14. Hi, Thanks for this demo.

    I would like to add an animation when the content appears (like Fade In)
    I try in CSS but it doesn’t work.

    How can I do ?
    Thanks

  15. Great tabs, trying to get it so that no icons show though, as the tabs I have are small so ‘A-E’ ‘F-J’ etc.

    Want those letters to show when in mobile view but it defaults to the icon and I can’t see a way around it? Any help most welcome.

  16. hello, it would be nice to add jquery transitions, like slidedown fadein etc to the content. thoughts?

  17. this worked for me but its janky, i really want slideDown, not fadeIn

    section {-moz-animation-name: fadeIn;
    -moz-animation-timing-function: ease-in;
    -moz-animation-duration: 1s;
    -webkit-animation-name: fadeIn;
    -webkit-animation-timing-function: ease-in;
    -webkit-animation-duration: 1s }

    @keyframes fadeIn{
    from {
    opacity: 0;

    }
    to {
    opacity: 1;
    }
    }

  18. Can anyone help me with css for displaying text in tablet and smartphones instead of icons?

  19. TypeError: this.el is null
    this.tabs = [].slice.call( this.el.querySelectorAll( ‘nav > ul > li’ ) );

    el is null ….

  20. What an amazing blueprint. Thank you so much.

    I would like to use different images next to the span text in the tabs. The images are from flaticon and when I try to use them it breaks the tab borders.

    What do I have to do to get them to work in place of the images you have here?

    Please show me the code.

    Thanks,

    Vin