Skip to content

Instantly share code, notes, and snippets.

@geraldfullam
Last active August 29, 2015 14:15
Show Gist options
  • Save geraldfullam/1639ef122d3771de4c99 to your computer and use it in GitHub Desktop.
Save geraldfullam/1639ef122d3771de4c99 to your computer and use it in GitHub Desktop.
jQuery tooltip: accessibility friendly
<div class="button-list namespace">
<h2>$('selector').tooltip()</h2>
<ul>
<li>
<span>Lorem Ipsum Dolar Sit</span>
<button type="button">+
<span class="tooltip" role="tooltip">Hello World again and again and again and again.</span>
</button>
</li>
<li>
<span>Lorem Ipsum Dolar Sit</span>
<button type="button">+
<span class="tooltip" role="tooltip">Hello World</span>
</button>
</li>
<li>
<span>Lorem Ipsum Dolar Sit</span>
<button type="button">+
<span class="tooltip" role="tooltip">Hello World</span>
</button>
</li>
<li>
<span>Lorem Ipsum Dolar Sit</span>
<button type="button">+
<span class="tooltip" role="tooltip">Hello World</span>
</button>
</li>
<li>
<span>Lorem Ipsum Dolar Sit</span>
<button type="button">+
<span class="tooltip" role="tooltip">Hello World</span>
</button>
</li>
</ul>
</div>

jQuery tooltip: accessibility friendly

Purpose: provide a tooltip that meets the following requirements:

  1. Is accessible to screen readers
  2. Is accessible to sighted keyboard users
  3. Shows on hover and on focus
  4. Doesn't obstruct other clickable elements
  5. Gracefully degrades to IE8

A Pen by Gerald on CodePen.

License.

// Fully accessible tooltip jQuery plugin with delegation.
// Ideal for view containers that may re-render content.
(function ($) {
$.fn.tooltip = function() {
this
// Delegate to tooltip, Hide if tooltip receives mouse or is clicked (tooltip may stick if parent has focus)
.on('mouseenter click', '.tooltip', function (e) {
e.stopPropagation();
$(this).removeClass('isVisible');
})
// Delegate to parent of tooltip, Show tooltip if parent receives mouse or focus
.on('mouseenter focus', ':has(>.tooltip)', function () {
$(this)
.find('.tooltip')
.addClass('isVisible');
})
// Delegate to parent of tooltip, Hide tooltip if parent loses mouse or focus
.on('mouseleave blur', ':has(>.tooltip)', function () {
$(this)
.find('.tooltip')
.removeClass('isVisible');
});
return this;
};
}(jQuery));
// Bind event listener to container element
$('.namespace').tooltip();
html {
font-size: 62.5%;
}
body {
font-family: Calibri, Candara, Segoe, 'Segoe UI', Optima, Arial, sans-serif;
font-size: 1.6em;
}
h2 {
font-size: 2.4rem;
line-height: 1;
margin: 0 0 1em;
}
div {
display: inline-block;
margin: 1rem;
padding: 1rem;
border: 1px solid #bcbec0;
border-radius: 3px;
}
ul {
display: inline-block;
margin: 0;
padding: 0;
list-style: none;
}
li {
padding: .2em;
border-top: 1px solid #ccc;
}
li:first-child {
border-top: none;
}
button {
position: relative;
}
/* Predefine tooltip styles, content; Hide by default */
.tooltip {
position: absolute;
box-sizing: border-box;
z-index: 2;
top: 110%;
top: calc(100% + 5px);
left: 50%;
overflow: hidden;
clip: rect(0,0,0,0);
width: 1px;
height: 1px;
padding: 10px 15px;
-webkit-transform: translateX(-50%);
-ms-transform: translateX(-50%);
transform: translateX(-50%);
transition: opacity .3s ease-in .3s;
font-family: Helvetica, Arial, sans-serif;
font-size: 14px;
font-size: 1.4rem;
text-align: center;
white-space: pre;
opacity: 0;
color: #fff;
border: 1px solid #6d6e71;
border-top-color: #373739;
background-color: #373739;
}
/* Up arrow */
.tooltip:after {
position: absolute;
top: -10px;
left: 50%;
display: block;
width: 0;
height: 0;
margin-left: -10px;
content: ' ';
pointer-events: none;
border-right: 10px solid transparent;
border-bottom: 10px solid #373739;
border-left: 10px solid transparent;
}
/* Toggled by jQuery for show/hide */
.tooltip.isVisible {
overflow: visible;
clip: auto;
width: auto;
height: auto;
opacity: 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment