For many web designers, accessibility conjures up images of blind users with screenreaders, and the difficulties in making sites accessible to this particular audience. Of course, accessibility covers a wide range of situations that go beyond the extreme example of screenreader users. And while it’s true that making a complex site accessible can often be a daunting prospect, there are also many small things that don’t take anything more than a bit of judicious planning, are very easy to test (without having to buy expensive assistive technology), and can make all the difference to certain user groups.
In this short article we’ll focus on keyboard accessibility and how careless use of CSS can potentially make your sites completely unusable.
Keyboard Access
Users who for whatever reason can’t use a mouse will employ a keyboard (or keyboard-like custom interface) to navigate around web pages. By default, they will use TAB and SHIFT + TAB to move from one focusable element (links, form controls and area) of a page to the next.
Note: in OS X, you’ll first need to turn on full keyboard access under System Preferences > Keyboard and Mouse > Keyboard Shortcuts. Safari under Windows needs to have the option Press Tab to highlight each item on a webpage in Preferences > Advanced enabled. Opera is the odd one out, as it has a variety of keyboard navigation options – the most relevant here being spatial navigation via Shift+Down, Shift+Up, Shift+Left, and Shift+Right).
But I Don’t Like Your Dotted Lines…
To show users where they are within a page, browsers place an outline around the element that currently has focus. The “problem” with these default outlines is that some browsers (Internet Explorer and Firefox) also display them when a user clicks on a focusable element with the mouse. Particularly on sites that make extensive use of image replacement on links with “off left” techniques this can create very unsightly outlines that stretch from the replaced element all the way to the left edge of the browser.
Outline bleeding off to the left (image-replacement example from carsonified.com)
There is a trivial workaround to prevent outlines from “spilling over” by adding a simple overflow:hidden, which keeps the outline in check around the clickable portion of the image-replaced element itself.
Outline tamed with overflow:hidden
But for many designers, even this is not enough. As a final solution, many actively suppress outlines altogether in their stylesheets. Controversially, even Eric Meyer’s popular reset.css – an otherwise excellent set of styles that levels the playing field of varying browser defaults – suppresses outlines.
html, body, div, span, applet, object, iframe ... {...outline: 0;...}/* remember to define focus styles! */:focus {outline: 0;}
Yes, in his explanation (and in the CSS itself) Eric does remind designers to define relevant styles for :focus… but judging by the number of sites that seem to ignore this (and often remove the related comment from the stylesheet altogether), the message doesn’t seem to have sunk in.
Anyway… hurrah! No more unsightly dotted lines on our lovely design. But what about keyboard users? Although technically they can still TAB from one element to the next, they now get no default cue as to where they are within the page (one notable exception here is Opera, where the outline is displayed regardless of stylesheets)… and if they’re Safari users, they won’t even get an indication of a link’s target in the status bar, like they would if they hovered over it with the mouse.
Only Suppress outline For Mouse Users
Is there a way to allow users navigating with the keyboard to retain the standard outline behaviour they’ve come to expect from their browser, while also ensuring that it doesn’t show display for mouse users?
Testing some convoluted style combinations
After playing with various approaches (see Better CSS outline suppression for more details), the most elegant solution also seemed to be the simplest: don’t remove the outline on :focus, do it on :active instead – after all, :active is the dynamic pseudo-class that deals explicitly with the styles that should be applied when a focusable element is clicked or otherwise activated.
a:active { outline: none; }
The only minor issues with this method: if a user activates a link and then uses the browser’s back button, the outline becomes visible. Oh, and old versions of Internet Explorer notoriously get confused by the exact meaning of :focus, :hover and :active, so this method fails in IE6 and below. Personally, I can live with both of these.
Note: at the last minute before submitting this article, I discovered a fatal flaw in my test. It appears that outline still manages to appear in the time between activating a link and the link target loading (which in hindsight is logical – after activation, the link does indeed receive focus). As my test page only used in-page links, this issue never came up before. The slightly less elegant solution is to also suppress the outline on :hover.
a:hover, a:active { outline: none; }
In Conclusion
Of course, many web designers may argue that they know what’s best, even for their keyboard-using audience. Maybe they’ve removed the default outline and are instead providing some carefully designed :focus styles. If they know for sure that these custom styles are indeed a reliable alternative for their users, more power to them… but, at the risk of sounding like Jakob “blue underlined links” Nielsen, I’d still argue that sometimes the default browser behaviours are best left alone. Complemented, yes (and if you’re already defining some fancy styles for :hover, by all means feel free to also make them display on :focus)… but not suppressed.



Comments
Got something to add? You can just leave a comment.
09/12/2009
This is one of the small things that really makes a difference the problem as mentioned in the article is that designers/developers add in the CSS reset without even thinking about what it does. Eric Meyers reset is great but all too often it is added but as it is not understood, will not be touched or modified.
That is why I think focus outlines should not be reset and I hope that he changes it. It then forces the designer or developer to actively suppress the outline and that is a concious decision rather than one of ignorance.
09/12/2009
I’m glad too see this article here, too, Patrick. It’s amazing the number of sites who don’t set :focus styles (especially those powered by Eric Meyer’s reset style sheet).
I admit I’ve done it in the past purely for aesthetic reasons but back then I knew nil about accessibility (not that I know a lot now, though).
09/12/2009
One thing that surprised me is the number of times I see people using sites with their keyboard in everyday life – so its something that applies to everyone, not just people that navigate by keyboard out of necessity. It is a vital piece of a stylesheet, and the lack of :focus style often annoys me on sites (when I have a sandwich in my mouse hand!)
09/12/2009
It was great reading this article. I don’t have to use a keyboard out of necessity, but I often choose to. Turning on Firefox’s “start searching when you start typing” makes keyboard navigation in websites a breeze. Type what you see, hit enter, boom. It frustrates me when people turn off the :focus because of aesthetics, because I too often use the tab and shift+tab in addition to the above technique to surf a page.
09/12/2009
Oh, it’s worth mentioning that the title was nicked from a conversation ages ago with the lovely Veeliam … cheers fella.
09/12/2009
Nice article!
Did you manage to remove the inner outline in buttons with Firefox? I just tried *:active::-moz-focus-inner { border: 0; } but it seems like buttons keep focus after clicked and thus i didn’t manage to detect whether it’s a tab or click focus.
It would be great if we could achieve the same result with those pesky buttons.
09/12/2009
Definitely cool trick. I never in the past considered this like a usability problem who need to be resolved. Now I have the awareness and I will implement this in my CSS Projects.
Thank you.
09/12/2009
Great article, Patrick. This is one of the details that most web developers don’t pay attention to, even though it’s a big usability win.
The “Outline suppressed, reintroduced on :focus, suppressed on :active” example looks very interesting in case you want to reduce the outlines to a minimum for users that don’t need it, while maintaining its functionality for others.
09/12/2009
Matt is absolutely right. More and more users are using keyboard navigation, often to avoid RSI with a mouse. Also, users with non-touch mobile devices or web tv often tab through links to get around.
09/12/2009
Just a quick tip: `outline: none;` can be shortened to `outline: 0;`.
09/12/2009
Good article. I recently gave myself a kick up the rear to tighten up my accessibility-minded process on projects – and :focus was one of the issues I addressed.
The other was how my site looked and functioned with all images disabled – another consideration that often slips the net.
09/12/2009
a:hover, a:active { outline: none; }
Firmly added to the company reset.css
09/12/2009
Good reminder, Pat. I think you hit upon the easiest solution in your final sentence: “if you’re already defining some fancy styles for :hover, by all means feel free to also make them display on :focus)”.
At Clearleft we do tend to turn off outline for focus states, however we also always include styles for hover states, so our rule is: wherever you have a:hover also include a:focus.
09/12/2009
Thanks, Patrick, a great reminder :-)
I am defining my :focus but you’ve made me think again, will need to reconsider how exactly I do this. So thanks ;)
09/12/2009
Great article. I actually have never thought about this before. I mean, personally, i’ve never navigated a website with the keyboard before. Always nice to read stuff like that.
09/12/2009
I’m glad someone actually wrote an article on my favourite CSS pet peeve.
I would go further and say I actually like to have an outline on :focus even for when I’m using a mouse, and I’m particularly happy that the outline becomes visible when using the Back button (because then is when I really need/want it).
09/12/2009
I use this to keep :focus outlines from being too distracting for mouse users:
function hideOutlines() {$(“a”).click(function(e){this.blur();});}
09/12/2009
Great article. Its something that I’ve seen discussed a few times and definitely needs a solution. After attempting to implement this on a dev site I have to say your proposed method for suppressing it works amazingly, except when dealing with clicks that initiate Javascript actions on a specific page. As you are not leaving, and you do hover off the focus outline is returned.
The best thing you might have said though, that for some reason had never occurred to me is to design specific focus styles or use your hover styles which may end up being the best method.
09/12/2009
great, a nice clear article! exactly what i need, i was just diving into making the outline work as i wanted. this is one of those little things that make a website complete
09/12/2009
Good point. I hadn’t thought of using existing :hover styles as :focus styles.
25/02/2010
(A little late, I know, but just found and bookmarked this)
Often, esp with image replacement, I’ll remove the outline, and then importantly (!!!) make hover and focus styles the same. Also, focus outline is only removed selectively, rather than on all anchors or whatever.
Whatever I’m using to give visual feedback to the mouser, the keyboarder gets it too. If I’m changing colour and underlining something, focus does that too. If I’m using Gilder-Levin image replacement, or similarly funky setups where there’s real text under an image, I still have text-related styles (either change colour or add/remove underline or whatever) and again, it’s for both focus and hover. Active tends to end up in my stylesheets more for IE6 than for actual :active states.
So, really, the point is visual feedback. If you have strong visual feedback going on for :hover and it’s a focusable element, you should be able to safely remove outline so long as :focus sits in the same declaration as :hover. Less Ugly, same feedback.
17/12/2010
Brilliant article, Patrick – many thanks!
05/01/2011
Just wanted to point out that, thanks to some recent bug fixes in Opera, I’ve updated my experiments to find a Better CSS outline suppression
Commenting is closed for this article.