CINXE.COM

Tooltips & Toggletips

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <title>Tooltips &amp; Toggletips</title> <meta name="description" content="" /> <meta name="HandheldFriendly" content="True" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="shortcut icon" href="/favicon.ico"> <link rel="stylesheet" type="text/css" href="/assets/css/styles.css?v=62e4fa65bf" /> <link href="https://fonts.googleapis.com/css?family=Miriam+Libre:700&text=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz%26" rel="stylesheet" media="none" onload="if(media!='all')media='all'"> <link href="https://fonts.googleapis.com/css?family=Asap:400,400i&subset=latin" rel="stylesheet" media="none" onload="if(media!='all')media='all'"> <link rel="canonical" href="http://inclusive-components.design/tooltips-toggletips/" /> <meta name="referrer" content="no-referrer-when-downgrade" /> <meta property="og:site_name" content="Inclusive Components" /> <meta property="og:type" content="article" /> <meta property="og:title" content="Tooltips &amp; Toggletips" /> <meta property="og:description" content="Tooltips — affectionately misnomered as &quot;tootlips&quot; by my friend Steve — are a precariously longstanding interface pattern. Literally &quot;tips for tools&quot;, they are little bubbles of information that clarify the purpose of otherwise ambiguous controls/tools. A common example is a control that is only represented by a cryptic icon, the meaning" /> <meta property="og:url" content="http://inclusive-components.design/tooltips-toggletips/" /> <meta property="article:published_time" content="2017-07-25T16:18:21.000Z" /> <meta property="article:modified_time" content="2018-05-19T08:35:35.000Z" /> <meta name="twitter:card" content="summary" /> <meta name="twitter:title" content="Tooltips &amp; Toggletips" /> <meta name="twitter:description" content="Tooltips — affectionately misnomered as &quot;tootlips&quot; by my friend Steve — are a precariously longstanding interface pattern. Literally &quot;tips for tools&quot;, they are little bubbles of information that clarify the purpose of otherwise ambiguous controls/tools. A common example is a control that is only represented by a cryptic icon, the meaning" /> <meta name="twitter:url" content="http://inclusive-components.design/tooltips-toggletips/" /> <meta name="twitter:label1" content="Written by" /> <meta name="twitter:data1" content="Heydon Pickering" /> <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "Article", "publisher": { "@type": "Organization", "name": "Inclusive Components", "logo": "http://inclusive-components.design/ghost/img/ghosticon.jpg" }, "author": { "@type": "Person", "name": "Heydon Pickering", "image": { "@type": "ImageObject", "url": "//www.gravatar.com/avatar/1243c62e1667bbda61f130589811346e?s=250&d=mm&r=x", "width": 250, "height": 250 }, "url": "http://inclusive-components.design/author/heydon/", "sameAs": [] }, "headline": "Tooltips &amp; Toggletips", "url": "https://inclusive-components.design/tooltips-toggletips/", "datePublished": "2017-07-25T16:18:21.000Z", "dateModified": "2018-05-19T08:35:35.000Z", "description": "Tooltips — affectionately misnomered as &quot;tootlips&quot; by my friend Steve — are a precariously longstanding interface pattern. Literally &quot;tips for tools&quot;, they are little bubbles of information that clarify the purpose of otherwise ambiguous controls/tools. A common example is a control that is only represented by a cryptic icon, the meaning", "mainEntityOfPage": { "@type": "WebPage", "@id": "http://inclusive-components.design" } } </script> <meta name="generator" content="Ghost 0.11" /> <link rel="alternate" type="application/rss+xml" title="Inclusive Components" href="https://inclusive-components.design/rss/" /> </head> <body> <a href="#main">skip to content</a> <header role="banner" class="reversed"> <nav aria-label="site"> <ul> <li><a href="/">Inclusive Components <span class="vh">Home</span></a></li> <li><a href="/#components">The components</a></li> <li><a href="/about-the-project">About the project</a></li> </ul> </nav> <div class="central center pad-top"> <h1> Tooltips &amp; Toggletips </h1> <time datetime="2017-07-25">25 July, 2017</time> <svg class="plug" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 90.71 254.86"><g transform="translate(1322.7 -2645.4)"><path style="fill:#fefefe" d="M-1309.57 2645.4v27h-13.13v90h22.5l3.22 27.15c12.96-.3 22.97-.3 38.12-.15l4.16-27h22.7v-90h-13.12v-27h-20v27h-24.45v-27h-20zm5 5h10v22h-10v-22zm44.45 0h10v22h-10v-22zm-39.72 47h45v3.57h-45v-3.57zm0 15.1h45v3.56h-45v-3.57zm0 15.08h45v3.57h-45v-3.57zm10.64 65.14v107.54h22.22v-107.54h-22.22z"/></g></svg> </div> </header> <main id="main" class="central"> <div class="book"> <div> <h2>Get the book!</h2> <p>The <a href="http://book.inclusive-components.design">Inclusive Components book</a> is now available, with <strong>updated and improved</strong> content and demos. </p> </div> <img src="/assets/images/on-light.svg?v=62e4fa65bf" alt="book cover with the strap line, accessible web interfaces piece by piece"> </div> <p>Tooltips — affectionately misnomered as "tootlips" by my friend <a href="https://twitter.com/stevefaulkner">Steve</a> — are a precariously longstanding interface pattern. Literally "tips for tools", they are little bubbles of information that clarify the purpose of otherwise ambiguous controls/tools. A common example is a control that is only represented by a cryptic icon, the meaning of which the user has yet to learn.</p> <p>When and how these bubbles transpire is apparently up for debate, since I've encountered many a tooltip and they all seem to behave slightly differently. I've come to the conclusion that these numerous implementations fall into two distinct groups: true tooltips, and a pattern I'm hesitantly calling the "toggletip", coined by the aforementioned Steve in some <a href="https://www.paciellogroup.com/blog/2016/01/simple-standalone-toggletip-widget-pattern/">research and experimentation</a> he did not long ago.</p> <p>Inclusive design is often about providing the user with the right tool for the job, and the right kind of tooltip to go with that tool. In this article, I'll be looking at situations which might call for a tooltip or else a toggletip, and formulating inclusive implementations for each.</p> <hr> <h2 id="thetitleattribute">The <code>title</code> attribute</h2> <p>We can't talk about tooltips without bringing up the <code>title</code> attribute: the HTML standard for providing contextual information bubbles. The Paciello Group blog pulls no punches in describing the <code>title</code> attribute's contribution to web interfaces:</p> <blockquote> <p>"If you want to hide content from mobile and tablet users as well as assistive tech users and keyboard only users, use the <code>title</code> attribute." — <a href="https://www.paciellogroup.com/blog/2013/01/using-the-html-title-attribute-updated/">The Paciello Group blog</a></p> </blockquote> <p>That's <em>pretty bad</em> in terms of inclusion. In fact, the only place I can think of where the <code>title</code> attribute works reliably in screen reader software is on form elements like <code>&lt;input&gt;</code>s. Even then, touch and keyboard users won't get to see the <code>title</code> message appear. In short: just provide a clearly worded, permanently visible label.</p> <p><img src="/content/images/2017/07/tooltips_inputs-2.svg" alt="An input with a big, clear, permanent label is marked good. An input with a tiny title revealed on hover is not." /></p> <p>I'm a big supporter of using standard HTML elements and attributes wherever they're available. It's the most efficient and performant way to build usable web interfaces. But, despite being a specification mainstay, the <code>title</code> attribute really isn't fit for purpose. </p> <p>Then again, we've yet to define that purpose. What <em>should</em> tooltips be used for? And even if we can design them to be usable by the many, do we need them at all?</p> <h2 id="acasefortooltips">A case for tooltips</h2> <p>As we already established, tooltips are for clarification; they are for providing <em>missing</em> information. But why should that information be missing in the first place? As I wrote in <a href="https://shop.smashingmagazine.com/products/inclusive-design-patterns">Inclusive Design Patterns</a>, icons can accelerate the understanding of an interface, and help to internationalize it. But icons provided in isolation are always in danger of completely confounding a user — because they don't <em>spell anything out</em>. To users who don't recognize or can't decipher the icon, information is missing.</p> <p>Most of the time, you should simply be providing text alongside icons. Like the perma-visible field labels I just mentioned, textual labels are the most straightforward way of labeling things and they're automatically screen reader accessible if provided as real text (not images of text).</p> <p>The usual excuse for <em>not</em> providing textual labels is, "there's no space". And there likely isn't, if you set out not to include textual labels in the first place. If you treat them as important from the beginning, you will find a way.</p> <figure role="group"> <img src="/content/images/2017/07/text_layouts-1.svg" alt="Left example has four labels next to one another on the same line, meaning the text has to be small. Right example puts them 2 by 2, leaving more space for bigger text." /> <figcaption>There's always room for text if you make it, but some configurations leave more space for text than others.</figcaption> </figure> <p>Tooltips are a last resort, where space really is at a premium — perhaps due to the sheer number of controls, like in the toolbar for a WYSIWYG editor. So, how would we go about designing them to be as inclusive as possible?</p> <h2 id="inclusivetooltips">Inclusive tooltips</h2> <p>The first thing to get right is making the text in the tooltip accessible to assistive technologies. There are a couple of different methods for associating the tooltip to the focused control, and we choose between them based on the specific role of that tooltip: Is the tooltip there to provide a primary label or an auxiliary clarification?</p> <p>A notifications control with a tooltip reading "Notifications" treats the tooltip as a primary label. Alternatively, a tooltip that reads "View notifications and manage settings" is supplementary.</p> <p><img src="/content/images/2017/07/primary_or_auxiliary.svg" alt="The left example says notifications and has the caption primary label. The right example has the longer view notifications and manage settings text and is captioned auxiliary description." /></p> <h3 id="tooltipasprimarylabel">Tooltip as primary label</h3> <p>To associate one element with another as its primary label, you can use <code>aria-labelledby</code>. The relationship is forged by the <code>aria-labelledby</code> and <code>id</code> attributes sharing the same value.</p> <pre><code>&lt;button class="notifications" aria-labelledby="notifications-label"&gt; &lt;svg&gt;&lt;use xlink:href="#notifications-icon"&gt;&lt;/use&gt;&lt;/svg&gt; &lt;/button&gt; &lt;div role="tooltip" id="notifications-label"&gt;Notifications&lt;/div&gt; </code></pre> <ul> <li>Note the use of the <code>tooltip</code> role. In practical terms, all this role offers is an assurance that <code>aria-describedby</code> works reliably where supported. As Léonie Watson writes, <a href="https://www.paciellogroup.com/blog/2017/07/short-note-on-aria-label-aria-labelledby-and-aria-describedby/">ARIA labels and descriptions sometimes don't work with all elements</a> unless you incorporate an appropriate role. In this case, the most important role is the implicit button role of the subject <code>&lt;button&gt;</code> element, but <code>role="tooltip"</code> may extend support for this labeling method in some software.</li> <li>Whatever text content is in the linked SVG, it won't be read out. The <code>aria-labelledby</code> association <em>supersedes</em> the text content of the button as the label.</li> </ul> <p>To a screen reader — and its user — the above is now functionally similar to using a simple text label, like this: </p> <pre><code>&lt;button class="notifications"&gt;Notifications&lt;/button&gt; </code></pre> <p>The tooltip text is available on focus, just as it would be on hover for sighted users. In fact, if all text appeared only on hover, a sighted mouse user's experience of an interface would be somewhat analogous to that of a blind screen reader user.</p> <div role="complementary"> <h4>Redundant tooltips</h4> <p>All the time as an interface design consultant, I see people providing <code>title</code> attributes to links with identical text nodes.</p> <pre><code>&lt;a href="/some/path" title="Heydon's special page">Heydon's special page&lt;/a> </code></pre> <p>Since the text node is already perfectly visible, this is completely redundant. It doesn't even add anything for screen readers except — in some cases — repetition.</p> </div> <h4 id="includingnotificationcount">Including notification count</h4> <p>What if the notifications button showed a count of unread notifications, as these things often do (I'm thinking, of course, of Twitter)? </p> <p><img src="/content/images/2017/07/notification_count-1.svg" alt="The count appears in a circle partly covering the icon." /></p> <p>Fortunately, <code>aria-labelledby</code> can accept multiple, space separated <code>id</code>s.</p> <pre><code>&lt;button class="notifications" aria-labelledby="notifications-count notifications-label"&gt; &lt;svg&gt;&lt;use xlink:href="#notifications-icon"&gt;&lt;/use&gt;&lt;/svg&gt; &lt;span id="notifications-count"&gt;3&lt;/span&gt; &lt;/button&gt; &lt;div role="tooltip" id="notifications-label"&gt;Notifications&lt;/div&gt; </code></pre> <p>Despite the <code>#notifications-count</code> element appearing inside the <code>&lt;button&gt;</code>, it does not form the label by itself: It forms the first part of the label as the first <code>id</code> listed in the <code>aria-labelledby</code> value. It is placed where it is so that the designer can take advantage of relative and absolute positioning to arrange the element visually.</p> <p>To screen reader users, the label is now "3 notifications". This succinctly acts as both a current count of notifications and a reminder that this is the notifications control.</p> <h3 id="tooltipasauxiliarydescription">Tooltip as auxiliary description</h3> <p>Now let's try setting up the tooltip as a supplementary description, which is the archetypal form. Like <code>&lt;input&gt;</code> placeholders, tooltips should be for added information and clarification. </p> <p>Some interactive elements may have accessible descriptions, but all interactive elements need accessible labels. If we're using <code>aria-describedby</code> to connect the tooltip text, we'll need another method for providing the "Notifications" label. Instead of <code>aria-labelledby</code> we can add a visually hidden span to the button's text node, alongside the existing "3" counter.</p> <pre><code>&lt;button class="notifications" aria-describedby="notifications-desc"&gt; &lt;svg&gt;&lt;use xlink:href="#notifications-icon"&gt;&lt;/use&gt;&lt;/svg&gt; &lt;span id="notifications-count"&gt;3&lt;/span&gt; &lt;span class="visually-hidden"&gt;Notifications&lt;/span&gt; &lt;/button&gt; &lt;div role="tooltip" id="notifications-desc"&gt;View and manage notifications settings&lt;/div&gt; </code></pre> <p>The <code>visually-hidden</code> class corresponds to some special CSS we've discussed before on Inclusive Components. It hides the <code>&lt;span&gt;</code> visually without stopping it from being read out in screen readers.</p> <pre><code>.visually-hidden { clip-path: inset(100%); clip: rect(1px, 1px, 1px, 1px); height: 1px; overflow: hidden; position: absolute; white-space: nowrap; width: 1px; } </code></pre> <p>The prescribed behavior of <code>aria-describedby</code> is to be announced as the last piece of information for the control, after the label and role. In this case: <em>"Notifications button&hellip; View and manage notifications settings"</em> (most screen readers will leave a pause before the description).</p> <h3 id="interaction">Interaction</h3> <p>To improve upon the notoriously awful <code>title</code> attribute, our custom tooltips should appear on focus as well as hover. By supplying the tooltip in an element adjacent to the button, we can do this with just CSS:</p> <pre><code>[role="tooltip"] { display: none; } button:hover + [role="tooltip"], button:focus + [role="tooltip"] { display: block; } </code></pre> <p>However, we may need to wrap the button and tooltip in a container element for positioning purposes:</p> <pre><code>.button-and-tooltip { position: relative; } [role="tooltip"] { position: absolute; /* left/top/right/bottom values as required */ } </code></pre> <h2 id="touchinteraction">Touch interaction</h2> <p>So far this simply doesn't work so well for touch screen users because the focus and active states happen simultaneously. In practice, this means you'll see the tooltip, but only as the button is being pressed.</p> <p>How <em>much</em> of a problem this is depends on the nature of the app to which the control belongs. How bad is it if the user presses the control without really knowing what it does the first time? How easily can they recover?</p> <p>There are other things you could try, of course. One might be to suppress the button's action on the first press so it <em>just</em> shows the tooltip that time around. You could take this "tutorial mode" idea further still and show the tooltips as inline text for newcomers, but streamline the interface to just show icons for established users. By then, they should have learned what the icons represent.</p> <figure> <img src="/content/images/2017/07/new_established.svg" alt="Left example for a new user has icons with text labels. Right example for an established user has just icons" /> <figcaption>In either case, the landing screen for each of the options should have a clear (<code>&lt;h1></code>) heading with the same wording as the labels. Then at least the user knows where the icon took them upon arrival.</figcaption> </figure> <p>This would be to do away with tooltips altogether, which is probably for the best anyway. However, the tooltip's sister component — the toggletip — can work for mouse, keyboard <em>and</em> touch users.</p> <h2 id="inclusivetoggletips">Inclusive toggletips</h2> <p>Toggletips are like tooltips in the sense that they can provide supplementary or clarifying information. However, they differ by making the control itself supplementary: toggletips exist to reveal information balloons, and serve no other purpose. </p> <p>Often they take the form of little "i" icons:</p> <p><img src="/content/images/2017/07/i-1.svg" alt="A round I icon disclosing a message that describes what notifications are." /></p> <p>To work by touch just as well as by mouse or keyboard, toggletips are revealed by click rather than by hover and focus. Crucially, this means the <code>aria-describedby</code> association is no longer appropriate. Why? Because a screen reader user would have access to the information before pressing the button, so pressing it would appear not to do anything. Technically, they have <em>access</em> to the information, making the control "accessible" — but the control simply wouldn't make sense. In other words, it's a user experience issue more than a strict accessibility one, but it's important.</p> <h3 id="toggletipswithliveregions">Toggletips with live regions</h3> <p>The trick is to make screen readers announce the information after the click event. This is a perfect use case for a <a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions">live region</a>. We can supply an empty live region, and populate it with the toggletip "bubble" when it is invoked. This will both make the bubble appear visually and cause the live region to announce the tooltip's information.</p> <p>To follow is the markup with the live region unpopulated. Note the <code>.tooltip-container</code> element, which is provided to help positioning. This element would have <code>position: relative</code>, allowing for absolutely positioning the generated <code>.toggletip-bubble</code> element nearby.</p> <pre><code>&lt;span class="tooltip-container"&gt; &lt;button type="button" aria-label="more info" data-toggletip-content="This clarifies whatever needs clarifying"&gt;i&lt;/button&gt; &lt;span role="status"&gt;&lt;/span&gt; &lt;/span&gt; </code></pre> <p>Note the <code>type="button"</code> attribution which is to stop some browsers mistaking the button as a submit button when placed inside forms. Here is the markup with the live region populated (after the toggletip button is clicked):</p> <pre><code>&lt;span class="tooltip-container"&gt; &lt;button type="button" aria-label="more info" data-toggletip-content="This clarifies whatever needs clarifying"&gt;i&lt;/button&gt; &lt;span role="status"&gt; &lt;span class="toggletip-bubble"&gt;This clarifies whatever needs clarifying&lt;/span&gt; &lt;/span&gt; &lt;/span&gt; </code></pre> <p>The accompanying script and codePen, with notes to follow:</p> <pre><code>(function() { // Get all the toggletip buttons var toggletips = document.querySelectorAll('[data-toggletip-content]'); // Iterate over them Array.prototype.forEach.call(toggletips, function (toggletip) { // Get the message from the data-content element var message = toggletip.getAttribute('data-toggletip-content'); // Get the live region element var liveRegion = toggletip.nextElementSibling; // Toggle the message toggletip.addEventListener('click', function () { liveRegion.innerHTML = ''; window.setTimeout(function() { liveRegion.innerHTML = '&lt;span class="toggletip-bubble"&gt;'+ message +'&lt;/span&gt;'; }, 100); }); // Close on outside click document.addEventListener('click', function (e) { if (toggletip !== e.target) { liveRegion.innerHTML = ''; } }); // Remove toggletip on ESC toggletip.addEventListener('keydown', function(e) { if ((e.keyCode || e.which) === 27) liveRegion.innerHTML = ''; }); }); }()); </code></pre> <iframe height='265' scrolling='no' title='Toggletip' src='//codepen.io/heydon/embed/zdYdQv/?height=265&theme-id=0&default-tab=js,result&embed-version=2' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'>See the Pen <a href='https://codepen.io/heydon/pen/zdYdQv/'>Toogletip</a> by Heydon (<a href='https://codepen.io/heydon'>@heydon</a>) on <a href='https://codepen.io'>CodePen</a>. </iframe> <h4 id="notes">Notes</h4> <ul> <li>Our button is not a toggle button — at least, not in the usual sense. Instead of clicking the button showing or hiding the bubble, it only shows it. Hiding the bubble is achieved by unfocusing the button, mouse clicking away from the button or pressing escape. </li> <li>When the button is clicked for a second (or third, fourth etc.) time, the live region is repopulated after a discreet interval, re-announcing the content in screen readers. This is simpler and more intuitive than implementing toggle states (a "message in on" state makes little sense, especially once it has already been read out).</li> <li>The "discreet interval" (see last item) is implemented using <code>setTimeout</code>. Without it, some setups are not able to register the repopulation of the live region and do not re-announce the contents.</li> <li>The <code>role="tooltip"</code> attribution is not applicable since we are using <code>role="status"</code> for the live region.</li> </ul> <h4 id="progressivelyenhancingtitle">Progressively enhancing <code>title</code></h4> <p>As discussed, the <code>title</code> attribute is <em>really</em> flaky. But it <em>does</em> at least provide an accessible label to some assistive technologies, available when the button is focused. We could provide the bubble content via <code>title</code> and use this to build the <code>data-toggletip-content</code> attribute on page load. Our script's initial hook now becomes the boolean <code>data-toggletip</code>:</p> <pre><code>&lt;button data-toggletip aria-label="more info" title="This clarifies whatever needs clarifying"&gt;i&lt;/button&gt; </code></pre> <p>In the script, we need to take the value from <code>title</code> to build <code>data-tooltip-content</code>, then destroy <code>title</code> because we don't need it and it might still appear / get announced if left festering.</p> <pre><code>var toggletips = document.querySelectorAll('[data-toggletip][title]'); Array.prototype.forEach(toggletips, function (toggletip) { var message = toggletip.getAttribute('title'); toggletip.setAttribute('data-tooltip-content', message); toggletip.removeAttribute('title'); }); </code></pre> <h4 id="betterprogressiveenhancement">Better progressive enhancement</h4> <p>A button that doesn't do anything and happens to have a title attribute isn't really a very good baseline. Instead, I would recommend displaying the toggletip's content inline and then enhancing by creating the toggletip button dynamically.</p> <p>Here's another codePen, which progressively enhances a simple paragraph into a toggletip:</p> <iframe height='265' scrolling='no' title='Toogletip from paragraph' src='//codepen.io/heydon/embed/Vzwdpy/?height=265&theme-id=0&default-tab=html,result&embed-version=2' frameborder='no' allowtransparency='true' allowfullscreen='true' style='width: 100%;'>See the Pen <a href='https://codepen.io/heydon/pen/Vzwdpy/'>Toogletip from paragraph</a> by Heydon (<a href='https://codepen.io/heydon'>@heydon</a>) on <a href='https://codepen.io'>CodePen</a>. </iframe> <h2 id="testsanderrormessages">Tests and error messages</h2> <p>Something I haven't talked about on Inclusive Components is writing tests, so let's do a little of that here. Don't worry, I don't mean unit tests.</p> <p>If our toggletip component is to belong to a design system, it may be borrowed and used by lots of different people. By writing tests and including warnings, we can try to ensure it isn't being used improperly.</p> <p>A toggletip button that isn't a <code>&lt;button&gt;</code> provides a deceptive role to assistive technologies and is not focusable by keyboard (unless it's another, inappropriate focusable element like a hyperlink). In our script, we can detect the element <code>nodeName</code> and return an error message if it is not <code>BUTTON</code>. We use <code>return</code> to stop the remainder of the IIFE (Immediately Invoked Function Expression) from executing.</p> <pre><code>if (toggletip.nodeName !== 'BUTTON') { console.error('Toggletip buttons need to be &lt;button&gt; elements.') return; } </code></pre> <p><img src="/content/images/2017/07/error_message.png" alt="The error message screenshot form developer tools" /></p> <h3 id="csstestsanderrormessages">CSS tests and error messages</h3> <p>In <a href="https://shop.smashingmagazine.com/products/inclusive-design-patterns">Inclusive Design Patterns</a> I write about creating deliberate visual regressions to highlight code errors, and providing error messages in the developer tools CSS inspector.</p> <p>The error we caught with JavaScript earlier can be caught using the CSS selector <code>[data-tooltip]:not(button)</code>. We can highlight the erroneous element with a red outline, and provide an error message using the made-up <code>ERROR</code> property:</p> <pre><code>[data-tooltip]:not(button) { outline: red solid 0.5em; ERROR: Toggletip buttons need to be &lt;button&gt; elements. } </code></pre> <p>Despite being an invalid property, the <code>ERROR</code> will appear in dev tools when the element is inspected.</p> <figure> <img src="/content/images/2017/07/red_outline.svg" alt="A red outline appears around the icon" /> <figcaption>The clear red outline shows there is an error present and guides the developer's DOM inspector cursor.</figcaption> </figure> <h2 id="conclusion">Conclusion</h2> <p>Most of the time, tooltips shouldn't be needed if you provide clear textual labeling and familiar iconography. Most of the time toggletips are a complex way of providing information that could just be part of the document's prose content. But I see each of these components all the time in auditing websites, so I wanted to provide some guidance on how to make the most of them. </p> <h3 id="checklist">Checklist</h3> <ul> <li>If you have space, don't use tooltips or toggletips. Just provide clear labels and sufficient body text.</li> <li>If it's a tooltip you are looking to use, decide whether the tip's content should be provided as the label or description and choose ARIA properties accordingly.</li> <li>Don't rely on <code>title</code> attributes. They are not keyboard accessible and are not supported in many screen reader setups.</li> <li>Don't describe toggletips with <code>aria-describedby</code>. It makes the subject button non-functional to screen reader users.</li> <li>Don't put interactive content such as close and confirm buttons or links in tooltips or toggletips. This is the job of more complex menu and dialog components.</li> </ul> <p><em>With thanks to <a href="https://twitter.com/backwardok">@backwardok</a> who spotted I'd created a repetitive label by using a text node for the same element's ARIA description. Whoops!</em></p> <a href="/#components" class="call-to-action smaller"> <span aria-hidden="true">&#x21a9;</span> Back to components list </a> </main> <footer class="central"> <!--<div class="sponsors"> <p>&mdash; Happily sponsored by &mdash;</p> <div> <a href="https://fronteers.nl/about"> <img src="/assets/images/fronteers.svg?v=62e4fa65bf" alt="fronteers conference"> </a> </div> </div>--> <div class="site-meta"> <p>Designed, built, and maintained by <a href="https://twitter.com/heydonworks">Heydon Pickering</a>.</p> <ul class="inline"> <li><a href="/rss"><img src="/assets/images/rss.svg?v=62e4fa65bf" alt=""> Subscribe</a></li> <li><a href="https://www.patreon.com/inclusicomps"><img src="/assets/images/patreon.svg?v=62e4fa65bf" alt=""> Support &amp; sponsor</a></li> <li><a href="https://twitter.com/inclusicomps"><img src="/assets/images/twitter.svg?v=62e4fa65bf" alt=""> Follow</a></li> </ul> </div> </footer> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10