Ally to the people, right on: Part two.

<p><span class="drop-cap">A</span> while ago I wrote a blog post about colors in web design and their effect on usability, more specifically on accessibility. There is always more to talk about when it comes to A11y (accessibility’s cool abbreviation). I’m not an expert on the matter, in fact I’m learning all the time, but I still want to share what I know, because the more we talk about this, and the more we build a consciousness about this, <em>then the more web designers and developers will start to take accessibility into account when designing their new projects</em>, and, soon, we’ll get the web to be truly for everyone.</p> <p>Today’s topic will be…</p> <h2>Chapter two: keyboard navigation </h2> <p>Many users don’t use the mouse/touchpad to navigate the web. They’re either oldschool or don’t have another option in terms of navigating, but to use the <em>almighty</em> keyboard. Sometimes the websites are not ready for it, and the almighty keyboard ends up being not that almighty after all. Here are a few tips to keep in mind so that you can make sure your keyboard users don’t get frustrated and leave your site the minute after they came to check it out.</p> <h3>Before we begin: What’s the deal with the <em>focus</em>? </h3> <p>Let me paint a picture here. You’re browsing a site with your mouse and see a button. You can click on it, interact with it. Now that element is <em>focusable</em>. If you were navigating with a keyboard, you should be able to hit the TAB key and interact with that element as well.</p> <p>Out of the box, these are the <a href="https://allyjs.io/data-tables/focusable.html">most common tabbable elements</a> (meaning you can get to them by pressing TAB on your keyboard):</p> <ul> <li>Buttons: &lt;button&gt;</li> <li>Anchors: &lt;a&gt;</li> <li>Inputs: &lt;input&gt;</li> </ul> <p>There are ways to make other elements tabbable, and to make even these I just listed not tabbable too. It’s the magic word <em>tabindex.</em></p> <p>From <a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/button_role#best_practices">what I’ve learned</a> it’s best to just use the elements the way that they are built and not tweak their standard behaviors. However, it is possible to do that, so if you didn’t have a choice, you could change the <em>tabbable</em> condition of any element by changing their <em>tabindex</em> attribute.</p> <p>Here’s how it works:</p> <h4>tabindex=0</h4> <p>This attribute makes an element focusable by keyboard navigation. So for example, a &lt;span&gt; with a tabindex=0 attribute will be tabbable:</p> <pre> <code class="language-xml"> &lt;span tabindex=0&gt;&lt;/span&gt;</code></pre> <h4>tabindex=-1</h4> <p>This attribute removes the tabbable condition from any element. Used on a button for example, it will make the button unreachable by keyboard, and reachable only by clicking or focusing by JS.</p> <h4>tabindex greater than 0</h4> <p>Using tabindex=1, tabindex=2, tabindex=3, etc. is permitted, but not recommended. The numbers indicate the order of the navigation. This might be useful for you as a developer, but will quickly become confusing for your users, so the general rule is to <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex">avoid it.</a></p> <p>Summing up what we learned so far, all of these are tabbable:</p> <pre> <code class="language-xml">&lt;!-- Natively: --&gt; &lt;a&gt;link&lt;/a&gt; &lt;button&gt;button text&lt;/button&gt; &lt;input type="text"&gt; &lt;!-- Forced by using tabindex=0 --&gt; &lt;h1 tabindex="0"&gt;heading example&lt;/h1&gt; &lt;h2 tabindex="0"&gt;heading example&lt;/h2&gt; &lt;h3 tabindex="0"&gt;heading example&lt;/h3&gt; &lt;div tabindex="0"&gt;block&lt;/div&gt; &lt;span tabindex="0"&gt;element&lt;/span&gt; &lt;img tabindex="0" &gt; &lt;p tabindex="0"&gt;Some long text&lt;/p&gt;</code></pre> <p>And on the other hand, none of these are (tabbable):</p> <pre> <code class="language-xml">&lt;!-- Natively: --&gt; &lt;a tabindex="-1"&gt;link&lt;/a&gt; &lt;button tabindex="-1"&gt;button text&lt;/button&gt; &lt;input type="text" tabindex="-1"&gt; &lt;!-- Forced by using tabindex=0 --&gt; &lt;h1&gt;heading example&lt;/h1&gt; &lt;h2&gt;heading example&lt;/h2&gt; &lt;h3&gt;heading example&lt;/h3&gt; &lt;div&gt;block&lt;/div&gt; &lt;span&gt;element&lt;/span&gt; &lt;img &gt; &lt;p&gt;Some long text&lt;/p&gt;</code></pre> <h3>Visual feedback</h3> <p>So you know what tabbing into an element means now: you hit on TAB, and… and what? Yes, magic words in the title hint it… <em>you need visual feedback!</em> </p> <p>Developers tend to remove it, but one precious attribute in CSS, the <em>outline</em>, is all you need to give your user visual feedback. </p> <p>The outline is very similar to a border, but doesn’t occupy any space, and you should use it to let users know what they’re focusing on.</p> <div data-oembed-url="https://youtu.be/cuTBWIDruFs"> <div style="left: 0; width: 100%; height: 0; position: relative; padding-bottom: 56.25%;"><iframe allow="encrypted-media; accelerometer; clipboard-write; gyroscope; picture-in-picture" allowfullscreen="" scrolling="no" src="https://www.youtube.com/embed/cuTBWIDruFs?rel=0" style="border: 0; top: 0; left: 0; width: 100%; height: 100%; position: absolute;" tabindex="-1"></iframe></div> </div> <p>Usually you’d add it on CSS like this:</p> <pre> <code class="language-css">:focus {    outline: 2px solid magenta;    outline-offset: 1px; }</code></pre> <p>But I noticed that it responds to clicking as well. In this case, it makes sense to have the outline <strong><em>only by keyboard tabbing</em></strong>. There is a pseudo element called <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible">focus-visible</a> that does exactly this (out of the box!), but is not functional in IOS Safari yet. I ended up installing <a href="https://github.com/WICG/focus-visible">a very cool library called focus-visible</a> that allows you to define your outline to only affect elements focused by tabbing like this:</p> <pre> <code class="language-css">/*  This will hide the focus indicator if the element receives focus via the mouse,  but it will still show up on keyboard focus. */ .js-focus-visible :focus:not(.focus-visible) {    outline: none; } /*  Optionally: Define a strong focus indicator for keyboard focus.  If you choose to skip this step then the browser's default focus  indicator will be displayed instead. */ .js-focus-visible .focus-visible {    outline: 2px solid magenta;    outline-offset: 1px; }</code></pre> <p> </p> <blockquote> <p><strong><em>TIp</em></strong>: Make sure that the focused element stands out. A good option is to use a color with high contrast to the rest of the pallet in your site and make the outline really thick.</p> </blockquote> <h3>Sequential keyboard navigation</h3> <p>Do you know someone called “float: left”? Well, one careless implementation with that bad boy was my first encounter with a non-sequential keyboard navigation. I didn’t understand the importance of this until I tried keyboard-navigating a site that used lots and lots of floats to order HTML elements.</p> <p>Here’s a very good example of what not to do (try following the focused element).</p> <div data-oembed-url="https://youtu.be/26nwWgA-LfM"> <div style="left: 0; width: 100%; height: 0; position: relative; padding-bottom: 56.25%;"><iframe allow="encrypted-media; accelerometer; clipboard-write; gyroscope; picture-in-picture" allowfullscreen="" scrolling="no" src="https://www.youtube.com/embed/26nwWgA-LfM?rel=0" style="border: 0; top: 0; left: 0; width: 100%; height: 100%; position: absolute;" tabindex="-1"></iframe></div> </div> <p><em>I find this to be a very good example of how to confuse your users.</em></p> <p><strong>Keyboard navigation must follow a logical order</strong>, or else it will confuse your users. Make sure you follow a reasonable path that visits all your links in an easy-to-understand order.</p> <p> </p> <p>I think that’s enough for today. Stay tuned, we still have a lot to talk about!</p>

Related blog posts

You get a11y, you get a11y, everyone gets a11y!

Get accessibility tips on how to handle color on your website to better reach your user.