cssAudio - Activefile-genericCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - Activehtmlicon-personicon-teamoctocatpop-outspinnerstartv

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>Simple Accessible Tabs</h1>

<div class="tab-widget js-tab-widget">
  <span id="tab-widget-description" class="visuallyhidden">Use left and right arrows to navigate between tabs.</span>
  
  <ul class="tab-widget__list">
    <li class="tab-widget__item">
      <a href="#tab-panel-1" class="tab-widget__link">Tab 1</a>
    </li>
    <li class="tab-widget__item">
      <a href="#tab-panel-2" class="tab-widget__link">Tab 2</a>
    </li>
    <li class="tab-widget__item">
      <a href="#tab-panel-3" class="tab-widget__link">Tab 3</a>
    </li>
  </ul>

  <div class="tab-widget__tabs">
    
    <div class="tab-widget__tab-content">
      <h2 id="tab-panel-1" tabindex="-1">Tab Panel 1</h2>
      <p>Lorem ipsum dolor sit amet, <a href="#">consectetur adipiscing elit</a>. Nullam et euismod elit. Nulla a elementum urna. Suspendisse viverra vehicula nulla.</p>          
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam et euismod elit. Nulla a elementum urna. <a href="#">Suspendisse</a> viverra vehicula nulla.</p>         
    </div>
    
    <div class="tab-widget__tab-content">
      <h2 id="tab-panel-2" tabindex="-1">Tab Panel 2</h2>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam et euismod elit. Nulla a elementum urna. Suspendisse viverra vehicula nulla.</p>          
    </div>
    
    <div class="tab-widget__tab-content">
      <h2 id="tab-panel-3" tabindex="-1">Tab Panel 3</h2>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam et euismod elit. Nulla a elementum urna. Suspendisse viverra vehicula nulla.</p>             
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam et euismod elit. <A href="#">Nulla a elementum urna</a>. Suspendisse viverra vehicula nulla.</p>         
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam et euismod elit. Nulla a elementum urna. Suspendisse viverra vehicula nulla.</p>         
    </div>
    
  </div>
</div>
            
          
!
            
              body {
  font-size: 2em;
  margin: 2em;
}

a {
  color: DarkViolet;
}

.tab-widget {}

.tab-widget__list {
    list-style-type: none;
    margin: 0;
    padding: 0;
}

.tab-widget__item {
    display: inline;
    margin-right: 5px;
}

.tab-widget__link {    
    background-color: DarkMagenta;
    border-radius: 5px 5px 0 0;
    color: White;
    font-weight: bold;
    line-height: 2.1;
    padding: .5em 1.5em;
    text-decoration: none;
}

.tab-widget__link--active {
    background-color: DarkViolet;
}

.tab-widget__tabs {
    background-color: MintCream;
    border: solid DarkViolet 1px;    
    border-radius: 0 5px 5px 5px;
    padding: 1em;
}

.tab-widget__tab-content {    
    display: none;
}

.tab-widget__tab-content--active,
.no-js .tab-widget__tab-content {
    display: block;
}

.visuallyhidden {
    border: 0;
    clip: rect(0 0 0 0);
    height: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0;
    position: absolute;
    width: 1px;
}
            
          
!
            
              (function (document, window, $, undefined) {
    'use strict';

    var $tabWidget = $('.js-tab-widget');

    var setupTabs = function($tab, $allTabs, $tabPanels, $tabListItems, i) {
        $tab
            .attr({
                'id': 'tab-link-' + i,
                'tabindex': '-1',
                'role': 'tab',
                'aria-selected': 'false',
                'aria-controls': 'tab-panel-' + i
            });

        if (i === 0) {
            $tab
                .attr({
                    'tabindex': '0',
                    'aria-selected': 'true',
                    'aria-describedby': 'tab-widget-description'
                })
                .addClass('tab-widget__link--active');
        }

        $tab.on('click', function(e) {
            e.preventDefault();

            tabClick($(this),  $allTabs, $tabPanels, i);
        });
      
        $tab.on('focus', function(e) {
            tabClick($(this),  $allTabs, $tabPanels, i);
        });

        $tab.on('keydown', function (e) {
            tabKeydown($(this), $allTabs, $tabPanels, $tabListItems, i, e);
        });
    };

    var setupTabPanels = function(tabPanel, i) {
        tabPanel
            .attr({
                'id': 'tab-panel-' + i,
                'role': 'tabpanel',
                'aria-hidden': 'true',
                'aria-labelledby': 'tab-link-' + i
            });

        if (i === 0) {
            tabPanel
                .attr('aria-hidden', 'false')
                .addClass('tab-widget__tab-content--active');
        }
    };

    var tabClick = function($thisTab, $allTabs, $tabPanels, i) {
        $allTabs
            .attr({
                'tabindex': -1,
                'aria-selected': 'false'
            })
            .removeAttr('aria-describedby')
            .removeClass('tab-widget__link--active');

        $thisTab
            .attr({
                'tabindex': 0,
                'aria-selected': 'true',
                'aria-describedby': 'tab-widget-description'
            })
            .addClass('tab-widget__link--active');

        $tabPanels
            .attr('aria-hidden', 'true')
            .removeClass('tab-widget__tab-content--active');

        $tabPanels.eq(i)
            .attr('aria-hidden', 'false')
            .addClass('tab-widget__tab-content--active');
    };

    var tabKeydown = function($thisTab, $allTabs, $tabPanels, $tabListItems, i, e) {
        var keyCode = e.which,
            $nextTab = $thisTab.parent().next().is('li') ? $thisTab.parent().next().find('a') : false,
            $previousTab = $thisTab.parent().prev().is('li') ? $thisTab.parent().prev().find('a') : false,
            $firstTab = $thisTab.parent().parent().find('li:first').find('a'),
            $lastTab = $thisTab.parent().parent().find('li:last').find('a');

        switch(keyCode) {
            // Left/Up
            case 37:
            case 38:
                e.preventDefault();
                e.stopPropagation();

                if (!$previousTab) {
                    $lastTab.focus();
                } else {
                    $previousTab.focus();
                }

                break;

            // Right/Down
            case 39:
            case 40:
                e.preventDefault();
                e.stopPropagation();

                if (!$nextTab) {
                    $firstTab.focus();
                } else {
                    $nextTab.focus();
                }

                break;

            // Home
            case 36:
                e.preventDefault();
                e.stopPropagation();

                $firstTab.focus();

                break;

            // End
            case 35:
                e.preventDefault();
                e.stopPropagation();

                $lastTab.focus();

                break;

            // Enter/Space
            case 13:
            case 32:
                e.preventDefault();
                e.stopPropagation();

                break;
        }
    };

    $tabWidget.each(function () {
        var $this = $(this),
            $tabList = $this.find('> ul'),
            $tabListItems = $tabList.find('li'),
            $allTabs = $tabListItems.find('a'),
            $tabPanels = $this.find('> div > div');

        $tabList.attr('role', 'tablist');
        $tabListItems.attr('role', 'presentation');

        $allTabs.each(function (i) {
            setupTabs($(this), $allTabs, $tabPanels, $tabListItems, i);
        });

        $tabPanels.each(function (i) {
            setupTabPanels($(this), i);
        });
    });

  $('html').addClass('js').removeClass('no-js');

})(document, window, jQuery);

            
          
!
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