RACHEL SHEARER: Hi. My name is Rachel Shearer. I'm a software engineer on
the Google Accessibility Engineering Team. And I'm here to talk about
making your web apps accessible using HTML5
and ChromeVox. So I'm actually going
to start this thing right off with a demo. I'm guessing that some of you
have seen this page before. This is Sergey's Google+
profile page. There's a UI control in the
upper right called the Add to Circles widget that you can use
if you want to add Sergey to one of your Google+
circles. You just hover over it with your
mouse and you can see the drop-down menu open
up underneath. You can interact with this menu
by checking checkboxes. You can create a new circle
at the bottom. And I'm guessing that most
of you out there probably interact with the control the
same way, hovering over it with your mouse. And so this is an interaction
that looks really good, and it performs really well for you. But now, I want you to
try something for me. Imagine that you can't
see the screen. And you can close your
eyes if that helps. So you can't see the screen and
you want to add Sergey to your circles. But if you can't see
the screen, then you can't use a mouse. So maybe you'll be using
a keyboard instead. But how do you hover over the
Add to Circles widget if you're just using a keyboard? The answer is you can't. It's impossible. So this is an example of a UI
interaction that looks really good and performs really well,
but it only performs really well for a certain
kind of user. And that's the kind of user
who can use a mouse. But as web developers, it's
really important for us to take into account that there's
lots of different kinds of users, and not all of them
can use a mouse. And we really need to make sure
that we're doing a good job for those users. And that's what accessibility is
all about, making your web apps usable by everyone. It includes people who can't
use the mouse, and it also includes people who use
assistive technology. Assistive technology is
basically software or hardware that makes it easier for someone
with a disability to use the internet. So there are lots of different
types of disabilities and special needs that
users might have. But for the purposes of this
tutorial, I'm going to focus on solutions for three groups
of users, blind users, users with low vision, and
motor-impaired users. And the reason for that is that
we know something very powerful about these users. We actually have a lot of
information about how they're going to be accessing
our apps. Blind users will generally use a
screen reader that describes the page using speech
or Braille output. And I actually have a
picture of a Braille display right here. This is a close-up of
a Braille display. And most blind users who use a
screen reader, whether or not it has speech output or Braille
output, will use standard keyboard for input. Low vision users will generally
use large fonts or something called a
screen magnifier. And I'll show you what a
screen magnifier looks like on this tab. So this is an example of
a screen magnifier. I'm selecting part of the page,
and you can see that it's expanding at the top,
making it really big, so that someone who has low vision
will be able to see it. And so that's the second
type of user. Motor-impaired users, who can't
use a mouse, might use some kind of special keyboard
or even a voice control interface to interact
with your app. So because we know a lot about
the assistive technology these users are going to be using, we
can do a lot to make sure that our web apps perform
well for them. I also want to note that these
three groups of users have something big in common. And I've actually already
talked about it. These three groups of users
can't use the mouse. So when you're testing your
apps, it's really important to make sure that you test it with
the keyword and that you can use it without
using a mouse. So now that we know a little bit
about the different kinds of users who might be accessing
our app I want to talk a little bit more
about testing. I already mentioned that we
should be testing our apps using just the keyboard. But I want to introduce a tool
that I'm going to be using during this talk. This is ChromeVox. ChromeVox is a screen reader
for Chrome that my team at Google built. ChromeVox will help me
demonstrate better how an assistive technology user might
experience a web app. It's really easy to use,
because it's a Chrome extension, and it was designed
completely for the web. You control it using keyboard
shortcuts, and it speaks the contents of pages using
the Chrome TTS API. There's a lot of other kinds of
screen readers, but we feel that ChromeVox particularly
shines as a testing tool. It interprets pages pretty much
the same way that other screen readers do. But because it's a Chrome
extension it's really easy for developers to set up and use. So how does ChromeVox work? Well, it works the same way as
any other screen reader. Let me demonstrate. It's actually been running in
the background this entire time, but I'm going to turn it
on now to let you hear what it sounds like. CHROMEVOX: Screen readers
and magnifier-- RACHEL SHEARER: So I'm going
to walk through this slide using keyboard shortcuts that
control ChromeVox so you can hear what it has to say. And it actually already started speaking this slide already. CHROMEVOX: Heading
[? group ?]. Screen Reader Introduction. Heading two. Screen readers and magnifiers
allow the user to explore both static text and interactive
elements. RACHEL SHEARER: All I'm doing is
using the keyboard to drive ChromeVox around the page. CHROMEVOX: Here's an example
web form to demonstrate. Enter your name. Edit text. Choose your favorite
color, red. List box 1 of 10. Submit button. Having trouble? Click here for help. Link. RACHEL SHEARER: So you saw that
ChromeVox WAS not only speaking the static text, but
it was also giving you sound indicators of what kind of
UI element that you were interacting with at
any given time. And that's basically how all
screen readers work. So someone who can't see the
screen is going to get the full experience of what's
on the screen. So now that we know more about
the different kinds of assistive technology and how
we can test our apps using only the keyboard and screen
reader like ChromeVox, let's talk about how we get there, how
we get to building a more accessible app. First, I'm going to talk about
the building blocks, the essential things that you need
to know when you're just starting out. And then I'm going to introduce
an approach that we've been trying out here
at Google, a systematic step-by-step approach to testing
and building for accessibility. After that, I'm going to go
a little deeper and talk a little bit more about custom
interactive controls, some of the more complex interactions
that you see, like the Add to Circles widget. And then, at the end, I'm going
to list some tools and resources that you can
use to help you. So let's start from scratch,
at the DOM. We can look at the DOM of a page
by opening it up in the Developer Tools, which I'm
going to do right now. So this right here in the
left-hand pane is the DOM. You can see all of the
slide elements. Inside this slide you
see the hgroup element and the article. And you see the slide that I'm
looking at right now, and this is the DOM structure,
article tags, headings, and the hierarchy. So the interesting thing about
the DOM is visually impaired users using assistive technology
like a screen reader see only the DOM. It doesn't matter what
your page looks like. They see only the building
blocks of the page. And keyboard-only
users navigate the page in DOM order. So they go basically top to
bottom in the DOM, moving focus around to navigate
the page. So you really have to adjust
your thinking here. The DOM is the users' mental
image of the page. They can't see what the page
looks like, and they're only seeing the DOM. So the way you build your app,
the app skeleton, that's the way these users are going
to interact with it. So knowing this, we can think
of some best practices that will help these users. The first is that we want to
create logical sections of the document, to group interface
elements that are related together. And you can use HTML5 semantic
elements like nav and header to make this easier, NAV to
group all your navigation elements together, and
header to group all your header content. And there's other HTML5
semantic elements too. Even some old school ones, like
h1, h2, and h3 will help users better understand the
structure of your app. You also want to make sure that
parTS of controls are grouped together in the DOM. So I see this a lot, where
you'll have a drop-down menu button somewhere in the DOM, but
drop-down menu itself is all the way at the
end of the DOM. And you can use CSS to make this
make sense visually, but if someone sees only the DOM,
they're not going to know where that menu is, because
it's all the way at the end of the DOM. So you can make things easier
by grouping things that are supposed to be together
together in the DOM. And then this last point is
pretty basic, but I'm going to say it again. You really want to make sure
that you're using CSS for layout instead of
using tables. For these users, tables
mean structured data. They can't see what the page
looks like, so using tables to lay out your page is
going to be very confusing for these users. So this slide is an example
of the things I was talking about. This is a quote that looks like
it makes a certain amount of sense visually. "The rain in Spain stays mainly
in the plain." So let's see how ChromeVox reads it. And remember that ChromeVox,
because of the screen reader, is reading only the DOM. So let's see what ChromeVox
does as I move it through the page. CHROMEVOX: Here's a quote. article. "The plain in rain stays
mainly in the Spain." RACHEL SHEARER: So that didn't
make a whole lot of sense. And even though this sentence
makes total sense visually, ChromeVox was jumping
all over the place. And that's because if I open up
the Developer Inspector and inspect these elements, you'll
see that the DOM for the page actually looks like this. The DOM underneath the
page has these words all over the place. "Plain in rain stays mainly in
the Spain." And we've used CSS to position it in a way that
looks like it makes sense. But ChromeVox is reading
the DOM. The layout of these words in
the DOM is exactly what ChromeVox is going to read. It doesn't know what the page
looks like visually. It's only reading the DOM. So it's really important to make
sure that your DOM make sense when you're building
a web app. The next thing I want to talk
about is interactive controls. And this, I swear, is one of the
easiest things you can do to improve the accessibility
of your site. Instead of using generic divs
and spans for buttons and links and stuff like that, use
the native HTML tag that's most appropriate. I use the terms div soup and
span salad to describe apps that are built like this. Don't use div soup. Don't use span salad. It just creates a really
confusing DOM, and it confuses these users. And there's two reasons why. First, screen readers can't
identify generic divs or spans as controls. They just see a div or a span
in the DOM, and they don't know what that's
supposed to be. They don't know that your span
with an onclick handler is supposed to be a link. They can't crawl through the
JavaScript to try and figure out exactly what the
developer meant. So they're just not going
to speak it as interactive at all. And a user can completely skip
over things that you want them to interact with because you've
identified them only as spans and divs. Also, spans and divs aren't
focusable by default. They won't receive
keyboard events. And this is even worse. A user who can see the screen
and who is trying to interact with something that you styled
as a button, if that's not focusable, they're never going
to be able to send the keyboard events do it. So no div soup and
no span salad. Use native HTML tags
wherever you can. I also want to note that there's
no reason not to use them for modern browsers. You can style them however you
want, and you can make them look like anything. And they give you focus
management and keyword support for free. Screen readers know exactly
how to identify them, and users know how to use them. And that's really one of the
most important parts. So this slide is a quick example
of how this works. On this slide there's
a button. And you can see that created
it using a div and an onclick handler. So let's see what
ChromeVox says. I'm going to turn ChromeVox
on again. CHROMEVOX: Spain heading
group custom button. Live coding example,
heading two. RACHEL SHEARER: So I'm just
going to move ChromeVox through this slide and we'll
see what it does. CHROMEVOX: Click
on this button. Article. Send. Clickable. RACHEL SHEARER: So you'll see it
said the word send, and it said clickable. But there's no indication
that it's a button. ChromeVox knows to
say clickable. It's smart enough to say
clickable when it encounters something that has an onclick
handler to let the user know that this button is somehow
interactive. But as a keyboard-only user,
if I try to press Enter in order to interact with
this button-- I'm pressing Enter
like crazy now-- nothing happens. That keyboard event isn't
getting sent to that button, and nothing is happening
on the page. But the good thing is, the fix
for this is really easy. You want to change this
div into a button. It's just one simple change,
and I'll make it right now. I'm going to turn ChromeVox
off first. CHROMEVOX: ChromeVox
is now inactive. RACHEL SHEARER: So I'm just
going to change this div tag into a button. And you'll see that nothing
visually on the page changed. The CSS is doing everything
right. So now let's try this out
with ChromeVox again. CHROMEVOX: Refresh button. RACHEL SHEARER: OK. Let's move on to the Send button
and see what happens. CHROMEVOX: Send button. RACHEL SHEARER: Right. This is great. ChromeVox said, send button. And it used an audio indicator
to indicate that this is a button. And if I press Enter, the alert
opens, just like the onclick handler is supposed
to do in the code. CHROMEVOX: Send button. RACHEL SHEARER: So this was a
really simple change, and this is something that is really
simple to do. But it can really save you a lot
of time later on, so you don't have to reimplement all
of this stuff later on your div soup and span salad. The next thing I want to
talk about is labeling. Labeling is also something that
is really important, now that we're talking
about controls. You want to make sure
that you're labeling your form elements. And the label element is really
perfect for this task. Another thing that you want to
make sure you're doing is labelling your images with
the alt attribute. And this is really
important too. All images need to have the alt
attribute, not just some of them, all of your images. And the reason why is that if
there is no alt attribute on an image, a screen reader is
just going to try and speak that image anyway. It's going to try and identify
that image to the user. But it's just going to speak
the file name of the image. And for really complex web apps,
that can get horrible. The final names for some of the
images that I see every day are really, really long
strings of characters. And that gives users a really
terrible experience. And I just want to say, if the
experience is that bad, these users will just leave. A page full of unlabeled form
fields and unlabeled images is a terrible experience
for users. And so there's two kinds
of alt texts that you need to have. Every image needs to have it,
but important images need to have descriptive alt texts. This is alt text that actually
describes what the image is. For images that are decorative,
you can give them blank alt text. So this is alt text that tells
the screen reader that it can skip this image entirely. Blank alt text tells the screen
reader not to try to read the file name, just skip
the image entirely. It's not necessary. And so you can see on this slide
I've got an image that's essentially a bullet point,
and I'm giving it blank alt text. We don't need a screen reader
going through a page, reading all of the bullet points. It's just not necessary. So this next slide is another
live example. This is a form that looks
like a lot of forms that I see every day. You've got these labels
underneath these text fields, username and PIN. And they're positioned visually
underneath the form. But you can see in the code
underneath that they're not actually explicitly associated
with the form the DOM. And we also have an image,
just for fun, that's unlabelled. So let's see what ChromeVox
does with this page. CHROMEVOX: Password edit
text, edit text. RACHEL SHEARER: So you'll see
it's saying, edit text and password edit text. It's saying password edit text
because we gave that input field the type password. So that's a little bit
better than just saying blank edit text. But for both of these fields,
there's actually no indication what the user is supposed
to put in there. There's no label. A user would have no idea what
they're supposed to do. Let's try out the image. CHROMEVOX: Password edit text,
nine zero one P three N nine four T three image. CHROMEVOX: So this is
an example of what I was talking about. It can't figure out that image
is supposed to be, so it just reads the file name. And it's totally inexplicable
what this image is supposed to be if you can't see
the screen. So, you can clearly see that
navigating around a page that is full of unlabeled field and
images will get really tedious for a user. And again, this is another
really easy fix. If you change these spans that
have username and PIN, you change it into labels using
the label tag, you can fix this problem really easily. So let's do that right now. CHROMEVOX: ChromeVox
is now inactive. RACHEL SHEARER: I'm changing
this span to be a label tag. And I'm changing the second
span to be a label. I'm going to actually explicitly
associate it with the username field in the DOM. And this second one is going
to explicitly be associated with the password field. And you'll see, again, visually
that nothing changed. CSS is still styling
things correctly. And then I'm also going to give
this poor image an alt tag, Golden Gate Photo. All right. So I've made these changes. Let's try it again
with ChromeVox and see what happens. CHROMEVOX: Article username
edit text. RACHEL SHEARER: So you see, it's
actually saying, username edit text, whereas before it
was just saying edit text. CHROMEVOX: P-I-N password
edit text. RACHEL SHEARER: And this
is really great. It's also saying P-I-N edit
text instead of password. You can see how that distinction
on this page might be really important. So it's important to make
sure this password field is labeled correctly. Let's see how that
image sounds. CHROMEVOX: Golden Gate Photo. RACHEL SHEARER: So you can see,
right away, making these simple changes enabled ChromeVox
to interpret this page correctly to the user. The user gets better information
about what these form fields are supposed
to be. And it's low-hanging fruit
like this that is really easy to fix. The thing is, it's easier to
build this stuff in from the beginning rather than having to
go back later and find all of your form fields that aren't
labeled and all of your images that are missing
alt text. So this next topic is about
managing focus. And we're going to get a little
bit more advanced here. Basically, you want
to make sure that you're managing focus. And the reason for
this the simple. Users who are not using the
mouse, keyboard-only users, are navigating through
your page by moving focus through the DOM. You can think of focus
as like their cursor. So you can really help these
users out by making sure that you know where focus is and by
managing it appropriately. I'm going to give you a quick
demo of what someone navigating through page using
focus looks like. I'm going to use the
google.com/accessibility site. I'm just going to press Tab. And you can see that this little
blue box is moving around the page as
I press Tab. Pressing Tab in a browser
moves focus throughout the page. It's just moving it linearly
down the DOM. And you can see it move
throughout this page. So someone that is navigating
without using a mouse, someone who is navigating using the
keyboard, can press Tab to move linearly up and down
the DOM, or Shift-Tab to move back up. So why is this important? Well, you can place focus
by using element.focus. And if you pay attention to what
the user is doing, you can really make things easier
for them by putting focus into appropriate places as the user
is performing a task. And when the user is done with a
certain task, you can return focus to where it was before. And if you do these things,
you're really going to help them out. A lot of times, I see apps
where focus might just be dropped on the floor. And that actually means that
focus is being reset back to the top of the page. And that can be really
frustrating. If you're in the middle of
editing something, and the focus is dropped on the floor,
and you're sent all the way back to the top of the DOM,
that's frustrating. And it's something that is
really common for users to experience. I'm just going to quickly show
you what that is like. And again, this is something
that I see all the time. It's a pop-up dialog button. And you can see that
if you click on it, it opens the dialog. And you can press OK, and
the dialog disappears. And if you look at the code
below, you might be able to notice that there's
a red flag here. The dialog in the DOM,
this thing, is actually before the button. And you can remember from
earlier that I said that you want to make sure that
things in your DOM are grouped logically. So the fact that this dialog
is before the button, that doesn't look super good. But let's see what
ChromeVox does. Turning ChromeVox on. CHROMEVOX: Adding group pop-up
dialog, live coding example, heading two. RACHEL SHEARER: So we're
on the heading. Let's tab to the button. CHROMEVOX: Heading group
article, buy more printer ink button. RACHEL SHEARER: I'm going to
press Enter, and hopefully the dialog will open. Great. The dialog opened, but the weird
thing is that the little orange outlined, the purple and
orange online, shows you where focus is. And focus didn't move. Focus is still on the button. This dialog is open, but
ChromeVox didn't speak anything, and focus is
still on the button. So a user who can't see the
screen has no idea that something happened. They have no idea that the
dialog even opened. And that's a really
bad experience. And if the user did somehow try
and get into the dialog, like maybe they're a
keyboard-only user who can see the screen, they'll have to
tab all the way around the page before they can get
back to that dialog. And that's something that users
might not be able to figure out. You'll notice that if I open
the dialog, and somehow get inside of it, and I close the
dialog, focus just gets dropped on the floor. The previously focused element--
you can see a little orange square-- that's gone. It's not in the DOM anymore. And nothing happened. ChromeVox didn't
speak anything. And I don't know where
I am on the page. And you actually have
to tab backwards-- CHROMEVOX: Exiting dialog. RACHEL SHEARER: --to get
back to the button. So that's a poor experience
as well. But the fix for this, again,
is actually pretty easy. You might be noticing a pattern
here, that all these fixes are actually
pretty easy. And the good thing is there's a
number of different ways you can improve this experience. One of the ways is actually
putting focus on the button as soon as the dialog opens. So you can see here in
the code, I'm inside this method, confirm. And this is when the
dialog opens. So I'm just going to set focus
on the OK button in the dialog as part of the dialog opening,
using .focus. Then I'm also going to be a nice
person, and I'm going to set focus back on the button
when the dialog closes. So this button is
called Confirm. I'm going to set focus back
on that button there. Just double checking,
confirm, OK good. So now that I've added .focus
to the confirm and close dialog methods, let's see if
we've improved this experience at all for our users. I'm going to turn ChromeVox
back on. CHROMEVOX: Article
refresh button. RACHEL SHEARER: Move back
up to the button. CHROMEVOX: Buy more printer
ink button. RACHEL SHEARER: And
open the dialog. CHROMEVOX: Entering dialog. RACHEL SHEARER: So you'll
see right away that this is much better. ChromeVox announced that we
entered the dialog, and focus is thrown right back
onto the OK button. And even better, a user who can
see the screen and is may be only using the keyboard
starts right off in that dialog and they can interact
with it right away. A ChromeVox user or any screen
reader user would be able to navigate around the dialog and
figure out what they're supposed to be doing. So let's try closing
the dialog. I'm going to hit Enter
on the OK button. CHROMEVOX: Exiting dialog. RACHEL SHEARER: And you'll
see that ChromeVox said, exiting dialog. And focus is thrown right
back onto the Buy More Printer Ink button. So the user is right back where
they started, and you've helped them out a lot when
they're going through this dialog workflow. So the last thing I want to talk
about, while I'm talking about building blocks, is
keyboard shortcuts. And keyboard shortcuts can be
really helpful to help users navigate through your
app efficiently. And they're also really good
for power users, who maybe aren't using assistive
technology and who maybe can see the screen. But for power users, who use
your app a lot, keyboard shortcuts can be really great. There's two different kinds. Navigation shortcuts
jump between major interactive areas. You can think of these like
the J and K shortcuts in Google+ that move between
posts in the Stream. And I'll show those off
to you right now. I'm on the Google+ page. I'm going to go into
my Stream. And you can see that I can use
J and K keyboard shortcuts to move between posts. These are navigation
shortcuts. They're great because they
help break your UI into different units. They prevent users from having
to do a bunch of tabbing in order to get to the next post
in their Google+ Stream. The second type of
keyboard shortcut is an action shortcut. Action shortcuts basically just simplify a user's workflow. So in Google+ the equivalent of
this would be pressing R to reply to a post. So you'll see, you just press
that one keyboard shortcut-- I just pressed R-- and it opens up a
new reply field. And you can start composing
right away, instead of having to find the Reply button, and
press it, and open it back up. It's really simple, and it
enables a complex action. The important thing to remember
about shortcuts, though, is that they
really need to be documented somewhere. And even if they are documented,
not all users are going to know about them. So keyboard shortcuts are
great, but they're not a Band-Aid for an inaccessible
page. You might have all the keyboard
shortcuts in the world, but if you don't label
your form fields, and you don't have alt attributes, a
user is still going to have a bad experience. So keyboard shortcuts are great,
but they don't solve all problems. So now that I've given you the
building blocks, let's move on and talk about a systematic
approach to building accessible web apps. First, you want to take care
of the most basic errors. You want to clean up the
low-hanging fruit. Look at your DOM order and
make sure that related controls are grouped together. You can create logical groups
with semantic tags like nav, header, h1, and the landmark
ARIA roles. I'll be talking about ARIA
in a couple of slides, so hold on for that. The next thing you want to do
is use native HTML5 controls wherever possible, and try to
avoid div soup and span salad. Finally, you want to label
your controls and images. And the great thing about these
basic errors is that they're easier to catch and
fix early in the process. But once you catch them, the
fixes are really easy. Next, you want to think about
keyboard navigation. Try your app out with just the
keyboard, and make sure that you can reach all interactive
controls by tabbing. Make sure you can use
enter and space to interact with UI controls. And manage focus to make sure
that users can perform tasks with the keyboard efficiently. Keyboard navigation is so, so
important to take care of early in the development
process. When you get keyboard navigation
working, you ensure that screen reader users will
be able to navigate through your UI controls individually. You also ensure that screen
reader users will be able to activate those controls. By taking care of DOM structure
and keyboard navigation, you'll have
done 90% of the work that you have to do. So now that we've discussed
the building blocks of accessible web applications,
let's talk about the other 10%. In this part of the talk, I'm
going to give more detailed information about custom
interactive controls. And I'm going to use Add to
Circles widget from Google+ as an example throughout
this section. So native tags are
really great. Native links and buttons
are awesome. But if you want to enable
complex interactions like the Add to Circles widget, in many
cases, you're going to end up with div soup. But it's not the end
of the world. What you need to do is
reimplement the semantics of a native control on the
custom control. And I actually already talked
to you about how to do this. You want to think about focus
management for your custom control, and it's also important
to think about keyboard support. Reimplementing both of those
things is going to give your users a really good
experience. You also need to do additional
work for screen readers. And that's adding something
called ARIA attributes. I said before that it's
impossible for screen readers to identify what a bunch
of divs in the DOM are supposed to be. So adding ARIA attributes gives
screen readers a hint as to what your custom controls
are supposed to be, so they can do a better job interpreting
them to the user. So it helps you work around the
downsides of div soup for screen readers. So coming back to the Add to
Circles widget, it's pretty much the definition
of div soup. And this is the simplified
version of the Add to Circles widget. The actual code for it would
not even fit on this page. And it's mostly divs
and spans. The Add to Circles widget,
implemented just like you see here, is impossible for a screen
reader to understand. And it would be really difficult
for a keyboard-only user to use it. So I'm actually going
to walk you through how we improved it. It's still div soup, but we've
got extra information in there to make it a lot easier for
keyboard-only users and screen reader users to use. I'll walk you through the code,
because I'll be talking about this later. The first div that you see here
is the Add to Circles widget itself. And the second div
is the drop-down. You can see it's got a bunch
of divs for checkboxes. And it's actually appended
at the end of the DOM for CSS reasons. So that's one of the things
that we needed to fix. So the first thing we have
to do is manage focus. Remember when I said
that divs and spans aren't keyboard focusable? Well, you can make them keyboard
focusable by adding an attribute called tabindex. There's a bunch of different
ways to add tabindex, and they're listed on this slide. But essentially, if you add
tabindex equals zero to a div, it adds that div into
the tab order. So if you have a user who is
navigating around the page by pressing Tab, that user will be
able to focus on that div and send it keyboard events. So to tabindex is really,
really important. You can add keyboard handling,
and you can add labels, and all that stuff I talked about
earlier, but if your divs aren't focusable, a user won't
be able to interact with them. And so that's why it's
so important. After that, you want to make
sure that you're placing focus wherever necessary with
element.focus. Remember, we can proactively
place focus that way to create an efficient workflow
for users. So with custom controls, you
also want to make sure that you show the keyboard
some love. You want to add key handlers so
that a user can use Enter and Space and arrows
and Escape to interact with your control. And one of the best ways I've
found to do this is to pick a native control and then
try and mimic it. This can be a native control
as simple as a button or a select box, or it can be
something as complicated as something that you'd find on a
native operating system, like a tab panel or something
like that. But these kinds of native
controls usually handle keys like Enter or the arrow
keys really well. And users know how to interact
with these kinds of widget. They know to press the arrow
keys to move up and down in a select box. So if you mimic that native
control, a user is automatically going to know a
lot about what they have to do in order to interact
with your control. And these W3C actually has a
really good guide to common keyboard patterns
that you see. I'm going to open it up here so
you can actually see what this looks like. Here, under the Design
Patterns section. So, if you look at this guide,
you can actually get a good idea for what users might expect
when they encounter your control. So this code is just an example
of what a keyboard handler might look like
underneath here, with return on reply key down and checking
for key codes and stuff like that. So back to the Add to
Circles widget. What you're going to be doing is
picking native elements and then trying to mimic them,
just like I said before. The Add to Circles widget, to
a keyboard-only user or a screen reader user, is probably is most like a button. To a sighted user, you
hover over it. But then again, a keyboard-only user can't hover. So let's make it
like a button. And so making it like a button,
the first thing we're going to do add tabindex
equals zero to make it keyboard focusable. That's probably always the first
thing you're going to do you on a custom UI control. And then, after we do that,
we're going to add keyboard events like Enter and Space. We're going to listen for those
so that we can activate the button and show
the drop-down. Remember, a keyboard-only user
can't do hover, so Enter and Space mimic the behavior of a
regular button, and a user is going to be expect to
be able to do that. As for the menu itself,
it's a drop-down menu. And it's actually kind of
like a modal dialog. If you think about it, when you
hover over the button-- and I'll show you what that
looks like again. So if you go back to the Google+
Add to Circles button, you hover over it,
you have this modal dialog that appears. And you can interact with it,
you can check buttons, you can do whatever. But once you move the mouse away
from it, that drop-down disappears. And that's pretty much the same
way a modal dialog works. You can't interact with the rest
of the page until a modal dialog disappears. So we decided that we should
implement dialog behavior for this drop-down menu. The way dialogs work, as we saw
in that earlier example, is that you want to focus on the
first focusable element, like we did on the OK button
in the dialog example. So that's what we want to do
for the drop-down menu. We ask for the first focusable
element and we put focus on it. The next thing that you
want to do is trap focus inside the dialog. You don't want the person to
accidentally fall out and not know where they are
on the page. We also added Escape as a
keyboard shortcut, because that's something
that's commonly found in native dialogs. Then another important thing to
remember, when the dialog closes we want it to set focus
back onto the Add to Circles widget, instead of dropping
it on the floor. So I'll show you an example
of how this works. I'm just going to use the
keyboard instead of ChromeVox. So let's go back to Sundar's
profile, and I'm going to get keyboard focus on the Add to
Circles button, and I'm going to press Enter. And you can see, right away,
the dialog opened. There's a little blue outline
around that checkbox that shows that we have focus
on that checkbox. And I can use Tab to kind
of move through the rest of this dialog. So if I decided that I'm done,
and I'm going to be following Sundar, I press Escape. And you can see, page focus
goes right back to that button, which is great. That's exactly what we
want to see from this Add to Circles button. So next, I want to talk about
screen reader accessibility and the Add to Circles widget. And I mentioned ARIA before. So our Add to Circles widget
is a pile of divs. And as I pointed out earlier,
screen readers have real difficulty identifying
what a pile of divs is supposed to be. So ARIA is essentially a set
of HTML5 attributes that actually provide that
information to screen readers. The information that a sighted
user gets visually you can provide to a screen reader user
by noting with ARIA, this div is a button, or this
div is a menu. It's important to note that you
have to do everything else that I talked about earlier
in addition to ARIA. Just adding an ARIA attribute
doesn't actually give a widget keyboard handling. Or focus management. Or anything like that. You still need to
add that stuff. ARIA is just a layer on top that
specifically helps screen readers identify what
things are. So let's talk about
ARIA roles. There are two categories of ARIA
attributes, ARIA roles and ARIA states and
properties. The role attribute is static. It indicates that this generic
tag is behaving a certain way. So in this example, this div
here is going to be behaving like a button. It's taking on the
role of a button. So the ARIA attribute on this
div of is role equals button. You can also use ARIA attributes
to indicate composite controls. So those complex interactive
controls I mentioned before that don't really have a native
HTML equivalent, you can use ARIA there too. We can explicitly state that
this next div is playing the role of menu item
using the role equals menu item attribute. And there's a lot of different
roles that you can pick and choose from to add to your
generic controls. Another type of role that
I mentioned earlier is a landmark role. And that's a role that can be
used to organize the DOM in the same way that I
mentioned before. You can use a landmark role to
actually identify separate areas of your app to
screen reader. You can use them together with
the new HTML5 semantic tags to create a really rich
user experience. So in this example, I used to
the section semantic tag, but also gave it the
role of search. This indicates to a screen
reader that this section of the site is the search
section. A second category of ARIA
attribute contains ARIA states and properties. These are both dynamic. ARIA states add dynamic
information about the current state of an element. And you can use them in addition
to roles to identify what an element is
currently doing. For example, this div this
acting like a checkbox, so it has role equals checkbox. It also has the ARIA attribute
ARIA checked equals true. And as this checkbox gets
checked and unchecked, we can actually update this ARIA
state in our JavaScript. And this tells a screen reader
to tell the user this div is actually a checkbox, and
it's currently checked. There's a bunch of different
states associated with the different roles that you can use
to add richer information about the current state
of a dynamic control. One type of ARIA property is
the aria-live property. And this is a little bit more
complicated, so I'm not going to go into a ton of
detail right now. But essentially, you can use
it to identify dynamic content on a page. So if you add the aria-live
attribute, you're adding it to elements that are going
to get updated. And you can use the attribute
to describe the types of updates that this element is
going to be receiving. And if you want more
information, here's a link to the W3C guide to live regions,
which I'll open up. So you can see, there's a whole
section here in this document on live region
properties and how to use them. And this document can be really
valuable if you're trying to learn about
how to do this. Aria-live regions are something
that can be really useful if you have a very
complex page that is receiving updates all at once that might
not be in the same area where the user has focus. If you remember that keyboard
focus is like a cursor, and if you have a lot of stuff that is
happening outside of where that cursor is, things get
confusing really fast. So the aria-live property is
super useful and can really help you out there. So let's go back to the
Add to Circles widget. Now we know about ARIA, and
we have this pile of divs. So we want to make sure that
we add some ARIA to ensure that a screen reader user can
understand what the Add to Circles widget is supposed
to be doing. So the first thing that we're
going to specify is that this element is a button. So we're going to add role
equals button to this widget. And you'll notice that we have
tabindex equals zero in there, which is really, really
important for ARIA. Again, adding a tabindex
attribute spans to your generic elements really
should be the first thing that you do. We also want to specify that the
Add to Circles drop-down dialog is, in fact, a dialog,
like we decided earlier. So we're going to add
role equals dialog. And we did, unfortunately, also
use divs for checkboxes here, so we also want to specify
that those divs are indeed checkboxes. So we give them role equals
checkbox and update ARIA checked in the JavaScript as the
person checks or unchecks the checkbox. So now that we've added all of
this ARIA for screen reader users, let's try out the Add to Circles widget with ChromeVox. So here we are on Sundar's
profile. And you can see the Add
to Circles widget right at the top. Let's try and interact with
that Add to Circles widget using ChromeVox to see if we can
add Sundar to our circles. So I'm going to use ChromeVox
to navigate to the Add to Circles widget. CHROMEVOX: Navigation, Add
to Circles button. RACHEL SHEARER: So
that's great. You can see that ChromeVox said,
Add to Circles button. There's no indication that this
is actually some kind of strange widget that has a hover
target and you need to hover over it. A user who can't see the
screen doesn't care about any of that. We say that it's a button, and
they know how to interact with the button. So let's press Enter and
see what happens. CHROMEVOX: Entering dialog. RACHEL SHEARER: So
this is great. You can see that focus moved
to that checkbox, and ChromeVox said, entering
dialog. You can move around with Tab to
the other checkboxes, and ChromeVox-- Well, let's see what
ChromeVox says. CHROMEVOX: Zero family. Checkbox not checked. Zero acquaintances. Checkbox not checked. Five following. Checkbox not checked. RACHEL SHEARER: So
this is great. You can use tab to move around
this drop-down dialog. And ChromeVox is speaking it
just like you'd expect. Let's press Spacebar. CHROMEVOX: Checked
six following. Checkbox checked. RACHEL SHEARER: And you can see
that ChromeVox updates as the checkbox is checked. It's actually listening for
those ARIA changes, and it's letting you know that this
checkbox is checked. Let's press Escape to
close the dialog. CHROMEVOX: Exiting dialog. RACHEL SHEARER: So
this is awesome. The dialog went away, and
ChromeVox announced that you're exiting the dialog. There's no indication that this
is a drop-down and not really technically a dialog,
and you might have had to hover over it. Someone who can't see
a screen, this interaction is perfect. It's composed of UI elements
that they know how to interact with, buttons and dialogs. Because people have interacted
with this stuff before, they know how to do it. So it makes things a lot
easier for these users. The Add to Circles widget seems
really complicated. You've got to hover, it's not
a standard UI control. But you can see with the
combination of managing focus, keeping track of keyboard, and
adding ARIA, we can turn it into something that makes a
lot of sense for different kinds of users. Let's go over how we got here. First, you want to make sure
that you're structuring your DOM in a sensible way. It's true for all web apps. And it's also true for custom
controls themselves. You also want to make sure that
you're using native HTML tags wherever possible to save
yourself extra work later. You also want to make
sure your controls and images are labeled. You want to make sure you have
intuitive focus management, that you're guiding the user
around the page by moving focus proactively. You also want to make sure
that your app can be used entirely with the keyboard. Because, remember,
not all users are able to use the mouse. You have to have keyboard
handling and focus management so you can unplug your mouse,
use your app, and have everything work just like
you expect it to. And additionally, include ARIA
for screen reader users, to help screen reader users
in the midst of div soup and span salad. So now I'm going to list some
tools and resources that can help you get your app to being
a more accessible experience. The first one is ChromeVox,
which I was using to demonstrate. It's actually built in on Chrome
OS, and it's available as an extension for Chrome
on other platforms. It's something that any
developer can install on Chrome and use right away. And the great thing about
ChromeVox is that it's also open source. So you can access the source
code at this google-axs-chrom e.code.google.com link
on the slide. There's other no-cost screen
readers out there, VoiceOver and NVDA are examples of them. As a developer, it's super
important to test your app using just the keyboard, but
it's also good to take a test drive with a screen reader. Some other libraries with
accessibility support include Dojo Toolkit, GWT,
and jQuery UI. So if you're trying to build
your web app using components that already exist, these
libraries are good to look at, because they can take care of
a lot of this accessibility stuff for you. So whether you're building a
web app from scratch, or you're working on refining a
complex UI control like the Add to Circles widget, it's
definitely possible to deliver a dynamic, accessible experience
that looks really good to sighted users, but
performs really well for all kinds of users. The first step in this process
is really easy, just close your eyes or unplug your mouse
and try to use your app. Once you try that, you can
probably figure out some things to fix that can make the
experience a lot better. And finally, following HTML5
standards, especially ARIA, are going to get you the rest
of the way there, to an app that works well for everybody. So thank you very much
for tuning into this developer tutorial. I hope you had a lot of fun
watching it, or at least learned something. You can talk to me on Google+
using this goo.gl shortlink that's on this slide. And on Twitter, my handle
is rachelshe. So I look forward to
hearing from you. And that's it.