cssAudio - Activefile-genericCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - Activehtmloctocatspinnerstartv

Pen Settings

CSS Base

Vendor Prefixing

Add External CSS

These stylesheets will be added in this order and before the code you write in the CSS editor. You can also add another Pen here, and it will pull the CSS from it. Try typing "font" or "ribbon" below.

Quick-add: + add another resource

Add External JavaScript

These scripts will run in this order and before the code in the JavaScript editor. You can also link to another Pen here, and it will run the JavaScript from it. Also try typing the name of any popular library.

Quick-add: + add another resource

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

            
              <h1><a href="http://websemantics.uk/articles/accessible-tab-navigation/">Accessible tab navigation to meet <abbr title="Web Content Accessibility Guidelines">WCAG</abbr> 2 using <abbr title="Accessible Rich Internet Applications">ARIA</abbr> roles</a></h1>

<p>Use the <kbd>Tab</kbd> key to jump link to visible link, and the arrow keys to navigate across the tabs.</p>
<p>A white focus outline is applied to aid visualisation.</p>

<div class=tl_container>
  
  <!-- A plain set of anchor links in HTML -->
  
  <ul class="tl_list">
    <li><a href="#A" class=a>Section A</a></li>
    <li><a href="#B" class="b ON">Section B</a></li>
    <li><a href="#C" class=c>Section C</a></li>
  </ul>

  <section id=A class="tl_section a">
    <h2>Content heading A</h2>
    <p>Copy with an <a href="#">Example focusable link</a> as content for A1.</p>
  </section>
  
  <section id=B class="tl_section b">
    <h2>Content heading B</h2>
    <p>Copy with an <a href="#">Example focusable link</a> as content for B1.</p>
  </section>
  
  <section id=C class="tl_section c">
    <h2>Content heading C</h2>
    <p>Copy without a focusable link as content for C1.</p>
  </section>
  
</div>

 <p>There's an option to allow mouse hover to activate a tab by adding the class "hoverable" to the  tablist <code>ul</code>. Not sure it's such a good idea though.</p>

<p>As used on the <a href="http://www.tesco.com/easter/" target=_blank title="[new window]">Tesco Easter 2016 hub</a> (Opening hours results). <a href="http://websemantics.uk/tesco/easter.2016/" target=_blank title="[new window]">Permanent copy</a></p>

<p id=addToggle></p>

<h2>Alternatively</h2>
<p>Please read and consider Thierry Koblentz's article: <a href="http://cssmojo.com/tab-panel-the-right-way/?mc_cid=29c24aed5b&mc_eid=278af32c16#visual-clutter-started-it-all">Tab Panel, the right way&hellip;</a> which doesn't use anchors as tab activators. Pankaj Parashar has a supporting CodePen <a href="https://codepen.io/pankajparashar/pen/oJEAF">Awesome Accessible Tabpanel</a>.</p>

<p id=report class=report>report</p>


<p class=smaller><a href="http://codepen.io/2kool2">Pens by Mike Foskett</a> &mdash; <a href="https://websemantics.uk/">webSemantics</a></p>
            
          
!
            
              /* Tab styling (optional) */

.tl_container {margin: 2rem 0;}

.tl_list {
  display: flex;
  padding: 0;
  margin: 0;
  align-items: center;
  justify-content: left;
  list-style: none;
}

.tl_list li {
  margin: 0;
  width: 33.3333%;
  text-align: center;
  border-radius: 4px 4px 0 0;
}

.tl_list a {
  color: #fff;
  padding: 1rem 0.5rem;
  display: block;
  border: none;
  text-decoration: none;
  text-shadow: none;
}
.tl_list a:hover,
.tl_list a:focus {
  text-shadow: 0 2px 4px #000
}


/* White focus ring - so you can see when it's focussed (not required) */
.tl_section h2:focus {
  outline: 1px solid currentcolor;
}


/* Section styling (optional) */

.tl_section {
  padding: 1rem 1.5rem;
  min-height: 8rem;
  border-radius: 0 0 4px 4px;
  text-shadow: none;
}
.tl_section h2 {
  margin-top: 1rem;
}


/* tab & panel colour */

.a,
.a:hover,
.a:focus {background-color: rgba(255,85,160,.3);}
.b,
.b:hover,
.b:focus  {background-color: rgba(160,255,85,.3);}
.c,
.c:hover,
.c:focus  {background-color: rgba(85,160,255,.3);}


/* 
Section styling (required)
Removes hidden sections from the keychain. 
Only used when JavaScript is available.
*/
[role="tabpanel"][aria-hidden="true"] {
  display: none;
}


            
          
!
            
              /*
Simple Accessible Tab control v6 11-07-2016
Author: Mike Foskett
Incept: 09-03-2016
Article: http://websemantics.uk/articles/accessible-tab-navigation/
Furtherence of: Heydon Pickering - http://heydonworks.com/practical_aria_examples/#tab-interface

  Uses ARIA attributes (via CSS) to control what's visible.

  Requires (tested):
    addEventListener (IE8+)
    preventDefault (IE9+)
    classList (IE10+)
    querySelectorAll (IE9+)

  Required parameter:
    none

  Optional parameters:

    tabListClass : "tl_list" (default)

    onClass : "ON" (default)
            Customisable, set default tab on.
            Used for initialisation only.

    hoverableClass : "tl-hoverable" (default)
            Customisable, allow mouse-hover to switch tabs.
            Apply to the navigation ul.

  Version 6.1 - 16-08-2016
  Version 6 - 10-07-2016
  Version 5.2 - 17-03-2016
  Version 5 - 09-03-2016
  Version 4 - 27-01-2012
  Version 3 - 25-01-2012
  Version 1 - 27-05-2010
*/
var accessibleTabs6 = (function () {

  "use strict";

  var d = document;
  var tabListClass;
  var tabs;
  var onClass;
  var hoverableClass;
  //var useHover;

  var _setTab = function (tab, switchOn) {
    d.getElementById(tab.panelId).setAttribute("aria-hidden", !switchOn);
    tab.setAttribute("aria-selected", switchOn);
    tab.setAttribute("tabindex", switchOn ? "0" : "-1");
  };

  var _setTabsOff = function () {
    var i = tabs.length;
    while (i--) {
      _setTab(tabs[i], false);
    }
  };

  var _activateTab = function (e) {
    var tab = e.target;
    if (e.preventDefault) {
      e.preventDefault();
      _setTabsOff();
      _setTab(tab, true);
      d.getElementById(tab.panelId).children[0].focus();
    }
  };

  var _keypressed = function (e) {

    var tab = e.target;
    var newNo = -1;
    var maxNo = tabs.length - 1;

    if (e.keyCode === 37) { // left arrow
      newNo = (tab.no === 0) ? maxNo : tab.no - 1;
    }
    if (e.keyCode === 39) { // right arrow
      newNo = (tab.no === maxNo) ? 0 : tab.no + 1;
    }
    if (newNo > -1) {
      _setTabsOff();
      _setTab(tabs[newNo], true);
      tabs[newNo].focus();
    }
  };
  
  var _tabHovered = function (e) {
    var a = e.target;
    var useHover = a.tabList.classList.contains(hoverableClass);
    if (useHover) {
      _activateTab(e);
    }
  };

  var _events = function (tab) {
    tab.addEventListener("click", _activateTab, false);
    tab.addEventListener("keydown", _keypressed, false);
    tab.addEventListener("mouseover", _tabHovered, false);
  };

  var _initialiseAriaAttributes = function (tab) {

    var tabPanel = d.getElementById(tab.panelId);

    tab.parentNode.setAttribute("role", "presentation");
    tab.setAttribute("role", "tab");
    tab.setAttribute("aria-controls", tab.panelId);

    tabPanel.setAttribute("role", "tabpanel");
    tabPanel.setAttribute("aria-labelledby", tab.id);

    // Make first <section> object keyboard focussable
    // preferably a heading
    tabPanel.children[0].setAttribute("tabindex", "0");
  };

  var _setUpConfig = function (cfg) {
    tabListClass = cfg.tabListClass || "tl_list";
    onClass = cfg.onClass || "ON";
    hoverableClass = cfg.hoverableClass || "tl-hoverable";
  };

  var _setUpTab = function (tab, panelId, count) {
    tab.no = count;
    tab.id = "tab-" + panelId;
    tab.panelId = panelId;
    _initialiseAriaAttributes(tab);
    _events(tab);
  };


  var _initialiseTabList = function (tabList) {

    var defaultTab = 0;
    var panelId;
    var tabPanel;
    var i;

    if (tabList) {

      tabList.setAttribute("role", "tablist");
      tabs = tabList.getElementsByTagName("a");
      i = tabs.length;

      while (i--) {
        
        tabs[i].tabList = tabList;

        panelId = tabs[i].href.slice(tabs[i].href.lastIndexOf("#") + 1);
        tabPanel = d.getElementById(panelId);

        if (tabPanel) {
          _setUpTab(tabs[i], panelId, i);
          if (tabs[i].classList.contains(onClass)) {
            defaultTab = i;

            // onClass only used to declare intial state, so remove from DOM
            tabs[i].classList.remove(onClass);
            d.getElementById(panelId).classList.remove(onClass);
          }
        }
      }
      _setTabsOff();
      _setTab(tabs[defaultTab], true);
    }
  };

  var _isMustardCut = function (e) {
    // check browser feature support (IE10+)
    return (
      (typeof d.querySelectorAll === "function") &&
      d.addEventListener &&
      !!d.documentElement.classList // IE10+
    );
  };

  var init = function (cfg) {
    var tabLists;
    var i;

    if (_isMustardCut()) {
      _setUpConfig(cfg);
      tabLists = d.getElementsByClassName(tabListClass);
      i = tabLists.length;
      while (i--) {
        _initialiseTabList(tabLists[i]);
      }
    }
  };

  return {
    init: init
  };

}());


accessibleTabs6.init({
  tabListClass : "tl_list",   // default, may omit
  onClass : "ON",               // default, may omit
  hoverableClass : "tl-hoverable"  // default, may omit
});





(function(){

  // button to toggle the "on-hover tab-switching" behaviour
  
  function toggler (e) {
    // toggle content objs class
    var btn = e.target;
    var listClass = btn.getAttribute("data-listClass");
    var toggleClass = btn.getAttribute("data-toggleClass");
    var objs = document.querySelectorAll("." + listClass);
    var i = objs.length;
    while (i--) {
      objs[i].classList.toggle(toggleClass);
    }
    
    // change btn attr
    var pressed = btn.getAttribute("aria-pressed");
    if (pressed === "false") {
      btn.innerHTML = "Remove &#8220;hoverable&#8221; class";
      btn.setAttribute("aria-pressed", "true");
    } else {
      btn.innerHTML = "Add &#8220;hoverable&#8221; class";
      btn.setAttribute("aria-pressed", "false");
    }
  }
  
  var p = document.getElementById("addToggle");
  if (p) {
    p.innerHTML = "<button id=toggler class=toggler data-listClass='tl_list' data-toggleClass='tl-hoverable' aria-pressed=false>Add &#8220;hoverable&#8221; class</button> " + p.innerHTML;
    var btn = document.getElementById("toggler");
    btn.addEventListener("click", toggler, false);
  }
  
}(document));


            
          
!
999px
Close

Asset uploading is a PRO feature.

As a PRO member, you can drag-and-drop upload files here to use as resources. Images, Libraries, JSON data... anything you want. You can even edit them anytime, like any other code on CodePen.

Go PRO

Loading ..................

Console