jojoTabs is a jQuery plugin for responsive and accessible tabs that leverages ARIA roles, States and Properties
A Pen by Joe Watkins on CodePen.
| <h1>jojoTabs.js<span>Easy Responsive & Accessible Tabs</h1> | |
| <ul role="tablist"> | |
| <li id="tab_1" aria-controls="panel_1" aria-selected="true" role="tab">Tab 1</li> | |
| <li id="tab_2" aria-controls="panel_2" role="tab">Tab 2</li> | |
| <li id="tab_3" aria-controls="panel_3" role="tab">Tab 3</li> | |
| <li id="tab_4" aria-controls="panel_4" role="tab">Tab 4</li> | |
| </ul> | |
| <div id="panel_1" aria-labelledby="tab_1" aria-hidden="false" role="tabpanel"> | |
| <h2>Tabbed Content 1</h2> | |
| <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam nesciunt expedita blanditiis voluptates perferendis amet distinctio dolor qui.</p> | |
| <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam nesciunt expedita blanditiis voluptates perferendis amet distinctio dolor qui.</p> | |
| </div> | |
| <div id="panel_2" aria-labelledby="tab_2" aria-hidden="true" role="tabpanel"> | |
| <h2>Tabbed Content 2</h2> | |
| <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam nesciunt expedita blanditiis voluptates perferendis amet distinctio dolor qui.</p> | |
| <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam nesciunt expedita blanditiis voluptates perferendis amet distinctio dolor qui.</p> | |
| </div> | |
| <div id="panel_3" aria-labelledby="tab_3" aria-hidden="true" role="tabpanel"> | |
| <h2>Tabbed Content 3</h2> | |
| <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam nesciunt expedita blanditiis voluptates perferendis amet distinctio dolor qui.</p> | |
| <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam nesciunt expedita blanditiis voluptates perferendis amet distinctio dolor qui.</p> | |
| </div> | |
| <div id="panel_4" aria-labelledby="tab_4" aria-hidden="true" role="tabpanel"> | |
| <h2>Tabbed Content 4</h2> | |
| <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam nesciunt expedita blanditiis voluptates perferendis amet distinctio dolor qui.</p> | |
| <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam nesciunt expedita blanditiis voluptates perferendis amet distinctio dolor qui.</p> | |
| </div> |
jojoTabs is a jQuery plugin for responsive and accessible tabs that leverages ARIA roles, States and Properties
A Pen by Joe Watkins on CodePen.
| /*! | |
| * jojoTabs.js | |
| * Author: Joe Watkins - joe-watkins.io | |
| * Licensed under the MIT license | |
| * | |
| */ | |
| (function($){ | |
| $.fn.jojoTabs = function(options) { | |
| var defaults = { | |
| wrapper: this, | |
| tab: '[role="tablist"] li', | |
| tabPanel: '[role="tabpanel"]', | |
| breakPoint: 768, | |
| tabActiveClass: 'on', | |
| smallScreenClass: 'small-screen-tabs', | |
| tabPanelHiddenClass: 'visually-hidden', | |
| smallScreenScroll: true, | |
| smallScreenScrollSpeed : 400 | |
| } | |
| var options = $.extend(defaults, options); | |
| var o = options; | |
| var $tab = o.wrapper.find(o.tab), | |
| $tabPanel = o.wrapper.find(o.tabPanel), | |
| $breakPoint = o.breakPoint, | |
| tabActiveClass = o.tabActiveClass, | |
| smallScreenClass = o.smallScreenClass, | |
| tabPanelHiddenClass = o.tabPanelHiddenClass; | |
| // active class to first tab | |
| $tab.eq(0).addClass(tabActiveClass); | |
| // visually hide each tab panel | |
| $tabPanel.not(':first').addClass(tabPanelHiddenClass); | |
| $tab.each(function(index,element){ | |
| var $tabTrigger = $(this), | |
| tabPosition = index; | |
| $tabTrigger.click(function(e){ | |
| e.preventDefault(); | |
| $tab.removeClass(tabActiveClass).attr('aria-selected','false'); | |
| $(this).addClass(tabActiveClass).attr('aria-selected','true'); | |
| $tabPanel.addClass(tabPanelHiddenClass); | |
| $tabPanel.attr('aria-hidden','true'); | |
| $tabPanel.each(function(index,element){ | |
| var tabPanelPosition = index; | |
| if(tabPosition == tabPanelPosition){ | |
| $(this).removeClass(tabPanelHiddenClass); | |
| $(this).attr('aria-hidden','false'); | |
| if(_smallScreenCheck()){ | |
| _scrollTop(tabPanelPosition,o.smallScreenScroll,o.smallScreenScrollSpeed); | |
| } | |
| } | |
| }); | |
| }); | |
| }); | |
| function _scrollTop(position,smallScreenScroll,smallScreenScrollSpeed){ | |
| if(smallScreenScroll){ | |
| $("html,body").animate({scrollTop: $tabPanel.eq(position).offset().top},smallScreenScrollSpeed); | |
| }else{ | |
| $(window).scrollTop($tabPanel.eq(position).offset().top); | |
| } | |
| } | |
| function _smallScreenCheck(){ | |
| if($('.'+smallScreenClass).size() === 1){ | |
| return true; | |
| } | |
| } | |
| function _handleResize(namedFunction,time){ | |
| window.onresize = function(event) { | |
| clearTimeout(this.id); | |
| this.id = setTimeout(namedFunction, time); | |
| } | |
| } | |
| function _addSmallScreenClass(){ | |
| if($(window).innerWidth() < $breakPoint){ | |
| $('body').addClass(smallScreenClass); | |
| }else{ | |
| $('body').removeClass(smallScreenClass); | |
| } | |
| } | |
| // add small scree class if needed | |
| _addSmallScreenClass(); | |
| _handleResize(_addSmallScreenClass,500); // resize | |
| }; // $.fn | |
| }(jQuery)); | |
| $('body').jojoTabs({ | |
| animate : true, | |
| breakPoint : 768, | |
| tabActiveClass : 'on', | |
| tabPanelHiddenClass : 'visually-hidden', | |
| smallScreenScroll : true, | |
| smallScreenScrollSpeed : 400 | |
| }); |
| @import "compass"; | |
| $breakpoint: 48em; | |
| [role="tablist"]{ | |
| margin: 0; | |
| padding: 0; | |
| width: 100%; | |
| overflow: hidden; | |
| position: relative; | |
| li { | |
| list-style: none; | |
| margin: 0 0 .3em 0; | |
| line-height: 1.3em; | |
| padding: .4em; | |
| background: lighten(black, 80%); | |
| color: black; | |
| text-decoration: none; | |
| cursor:pointer; | |
| @media(min-width:$breakpoint){ | |
| width: 17%; | |
| margin: 0 .3em 0 0; | |
| float: left; | |
| } | |
| &.on { | |
| background: lighten(black, 70%);; | |
| } | |
| } | |
| } | |
| [role="tabpanel"]{ | |
| background: lighten(black, 70%); | |
| padding:1.3em; | |
| } | |
| .visually-hidden { | |
| position: absolute; | |
| overflow: hidden; | |
| clip: rect(0 0 0 0); | |
| height: 1px; width: 1px; | |
| margin: -1px; padding: 0; border: 0; | |
| } | |
| body { | |
| max-width:70%; | |
| margin:1em auto; | |
| padding:0 2em; | |
| font-family: 'Open Sans', sans-serif; | |
| background:#eee; | |
| } | |
| h1 span { | |
| display:block; | |
| font-size:70%; | |
| color:lighten(black,20%); | |
| } | |
| h2 { | |
| margin:0px; | |
| } |