Skip to content

Instantly share code, notes, and snippets.

@nico3333fr
Last active October 12, 2021 18:44
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nico3333fr/2043855fe5f854edee6a to your computer and use it in GitHub Desktop.
Save nico3333fr/2043855fe5f854edee6a to your computer and use it in GitHub Desktop.
Jquery tabs using ARIA
I've set up a very light jquery tab system for a website:
starting from this HTML code:
<ul class="pates-tabs__list">
<li class="pates-tabs__item">
<a href="#presentation" id="label_presentation" class="pates-tabs__link">Présentation</a>
</li>
<li class="pates-tabs__item">
<a href="#ingredients" id="label_ingredients" class="pates-tabs__link">Ingrédients</a>
</li>
<li class="pates-tabs__item">
<a href="#preparation" id="label_preparation" class="pates-tabs__link">Préparation</a>
</li>
<li class="pates-tabs__item">
<a href="#conditionnement" id="label_conditionnement" class="pates-tabs__link">Conditionnement</a>
</li>
</ul>
<div id="presentation" class="pates-tabs__tabcontent">
1
</div>
<div id="ingredients" class="pates-tabs__tabcontent">
2
</div>
<div id="preparation" class="pates-tabs__tabcontent">
3
</div>
<div id="conditionnement" class="pates-tabs__tabcontent">
4
</div>
Styles CSS are based on ARIA attributes :
[aria-hidden=true] {
display: none;
}
and jQuery code will do the rest:
/* loading aria attribute on pates tabs */
$('.pates-tabs__list').attr('role', 'tablist'); // ul
$('.pates-tabs__item').attr('role', 'presentation'); // li
$('.pates-tabs__link').attr('role', 'tab'); // a
$('.pates-tabs__link').each(function() { // controls attribute
$this = $(this);
controls = '' + $this.attr('href');
controls = controls.replace('#','');
$this.attr('aria-controls', controls);
$this.attr('tabindex', '-1');
});
$('.pates-tabs__tabcontent').attr('role', 'tabpanel'); // contents
$('.pates-tabs__tabcontent').attr('aria-hidden', 'true'); // all hidden
$('.pates-tabs__tabcontent').each(function() { // label by link
$this = $(this);
labelledby = 'label_' + $this.attr('id');
$this.attr('aria-labelledby', labelledby);
});
// hash => select the good one
hash = window.location.hash;
hash = hash.replace('#','');
$('.pates-tabs__tabcontent').each(function() {
$this = $(this);
if ( hash == $this.attr('id') ){
selector = '#' + hash;
// affichage
$(selector).removeAttr('aria-hidden');
// selection menu
selector = '#label_' + hash;
$(selector).attr('aria-selected', 'true');
$(selector).attr('tabindex', '0');
return false; // on sort du each
}
});
// if no selected => select first
if ($('.pates-tabs__link[aria-selected]').length == 0) {
$('.pates-tabs__link:first').attr('aria-selected', 'true');
$('.pates-tabs__link:first').attr('tabindex', '0');
$('.pates-tabs__tabcontent:first').removeAttr('aria-hidden');
}
/* click on a link */
$('.pates-tabs__link').click(
function() {
$this = $(this);
// remove aria selected on all links + remove focusable
$('.pates-tabs__link').removeAttr('aria-selected');
$('.pates-tabs__link').attr('tabindex', '-1');
// add aria selected on $this + focusable
$this.attr('aria-selected', 'true');
$this.attr('tabindex', '0');
// add aria-hidden on all tabs
$('.pates-tabs__tabcontent').attr('aria-hidden', 'true');
// remove aria-hidden on tab linked
id_to_show = '#' + $this.attr('aria-controls');
$(id_to_show).removeAttr('aria-hidden');
return false;
}
);
$('body').on('keydown','.pates-tabs', function(event) {
// strike up or left in the tab
if (event.keyCode == 37 || event.keyCode == 38) {
// find previous tab
// if we are on first => activate last
$activated = $('.pates-tabs__link[aria-selected="true"]').parent();
if($activated.is('.pates-tabs__item:first-child')) {
$('.pates-tabs__item:last-child a').click().focus();
}
else { // else activate previous
$activated.prev().children('.pates-tabs__link').click().focus();
}
event.preventDefault();
}
// strike down or right in the tab
if (event.keyCode == 40 || event.keyCode == 39) {
// find next tab
// if we are on last => activate first
$activated = $('.pates-tabs__link[aria-selected="true"]').parent();
if($activated.is('.pates-tabs__item:last-child')) {
$('.pates-tabs__item:first-child a').click().focus();
}
else { // else activate next
$activated.next().children('.pates-tabs__link').click().focus();
}
event.preventDefault();
}
//event.stopPropagation();
//return false;
}
);
/*********************************************************************************************************/
There it is.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment