Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new component: (mostly) accessible tooltip #72

Open
wants to merge 1 commit into
base: gh-pages
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions comparisons/components/tooltip/a11y.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Usage: The tooltip trigger must have the aria-describedby attribute, and its value must be a unique id which is given to its associated tooltip. The tooltip itself must have role="tooltip". The tooltip trigger must receive focus by the keyboard, and must trigger the tooltip on hover and focus. The tooltip itself should not recieve focus. It meets most of the guidelines set by the W3C ARIA Authoring Practices. What is missing is the tooltip being dismissed by the Esc key and the trigger on hover being announced by the screenreader.
116 changes: 116 additions & 0 deletions comparisons/components/tooltip/demo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>You Might Not Need JavaScript - Tooltip Demo</title>
<style>
.tooltip__container {
position: relative;
}

.tooltip__trigger {
border-bottom: 1px dashed #c69;
cursor: help;
/* using the general sibling selector in case someone inserts something like an icon between the two */
}

.tooltip__trigger:focus ~ [role="tooltip"],
.tooltip__trigger:hover ~ [role="tooltip"] {
opacity: 1;
visibility: visible;
-webkit-transform: translateY(0);
transform: translateY(0);
}

.tooltip__trigger:focus, .tooltip__trigger:hover {
outline: none;
background-color: wheat;
}

[role="tooltip"] {
position: absolute;
z-index: 10;
bottom: -2.25rem;
padding: .5rem .5rem 0.5rem .75rem;
margin-left: .25rem;
min-width: 12rem;
max-width: 320px;
background-color: #c69;
color: white;
border-radius: 3px;
opacity: 0;
pointer-events: none;
visibility: hidden;
-webkit-transform: translateY(1rem);
transform: translateY(1rem);
-webkit-transition: all 400ms;
transition: all 400ms;
will-change: opacity;
}

[role="tooltip"]::before {
content: '';
position: absolute;
z-index: 10;
left: -1.2rem;
top: .5rem;
border: .65rem solid transparent;
border-right-color: #c69;
}

/* general page style */
*, *:before, *:after {
box-sizing: inherit;
}

html {
height: 100%;
box-sizing: border-box;
}

body {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
height: 100vh;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
}

p {
position: relative;
max-width: 60rem;
padding: 1.5rem;
margin: 5rem auto;
line-height: 1.55;
font-family: monospace;
}

a {
border-bottom: 1px solid;
color: #c69;
text-decoration: none;
}
</style>
</head>
<body>
<p>Cat ipsum dolor sit amet,
<span class="tooltip__container">
<span class="tooltip__trigger" aria-describedby="tooltip-1" tabindex="0">fall over dead,</span>
<span class="tooltip__tip" role="tooltip" id="tooltip-1">(not really but gets sypathy)</span>
</span>
adipisicing elit. Velit repudiandae <a href="?">a link to show tabbing order is not affected</a> Love and coo around boyfriend who purrs and makes the perfect moonlight eyes so I can purr and swat
<span class="tooltip__container">
<span class="tooltip__trigger" aria-describedby="tooltip-2" tabindex="0">the glittery gleaming yarn to him.</span>
<span class="tooltip__tip" role="tooltip" id="tooltip-2">(the yarn is from a $125 sweater)</span>
</span>
Cat not kitten around plop down in the middle where everybody walks and claws in your leg.
</p>
</body>
</html>
6 changes: 6 additions & 0 deletions comparisons/components/tooltip/html.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<span class="tooltip__container">
<!-- the item (text, image, link, etc.) that triggers the tooltip should be keyboard-focusable. Tabindex 0 puts it in the tabbing order of the document, but does not affect the rest of the tabbing order. You should never use a tabindex above 0. Using aria-describedby will link the trigger to the tooltip so they are announced as a group by screenreaders. -->
<span class="tooltip__trigger" aria-describedby="tooltip-1" tabindex="0">the text / link / image that has a tooltip</span>
<!-- each tooltip must have the role of tooltip and be given a unique ID. That ID will be used above for its trigger with aria-described by. The tooltip itself should not receive focus and should only be triggered by keyboard or mouse events on the trigger. -->
<span class="tooltip__tip" role="tooltip" id="tooltip-1">the actual tooltip</span>
</span>
1 change: 1 addition & 0 deletions comparisons/components/tooltip/resources.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ARIA Authoring Practices: https://www.w3.org/TR/wai-aria-practices-1.1/#tooltip
31 changes: 31 additions & 0 deletions comparisons/components/tooltip/scss.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
.tooltip__container {
// so the tooltip is always positioned next to its trigger
position: relative;
}

.tooltip__trigger {
// these two are optional styles, but give the user an indication that the trigger is interactive
border-bottom: 1px dashed;
cursor: help;

// using the general sibling selector in case someone inserts something like an icon between the two
&:focus ~ [role='tooltip'],
&:hover ~ [role='tooltip'] {
visibility: visible;
// if you used opacity: 0 for the default style
opacity: 1;
}
}

// these are the only styles needed, and even opacity is not needed if you don't want to fade it in
// the rest would be up to the user to decide on
[role='tooltip'] {
// positioned absolutely to take it out of the normal document flow
position: absolute;
// keeps it hidden from screenreaders until the user focuses the trigger
visibility: hidden;
// prevents a glitch where sometimes hovering over a certain spot makes the tooltip flash in and out rapidly
pointer-events: none;
// opacity will hide it visually but not from screenreaders; allows us to give it a nice fade-in effect since visibiliy cannot be transitioned
opacity: 0;
}