 This definitely says designing, and for some of you who know me, I do not describe myself in any way, shape, or form as a designer. In fact, very much not a visual designer, and it's not what people signed up for. So I've been lying to you, but I think really the thing is we need to find out what is designing. So is this designing? This is kind of what we expect, where all of our minds go when we start talking about design. We do all of our work in Photoshop, spit out a static picture, and throw that over the wall. So is this designing? This is every human factors engineer's favorite example of poor, poor design. Once you have painted yourself into this corner though, your next design solution is to make that little push sign as big as you possibly can. So I would call that some form of designing, bad designing maybe. Is this designing? Yeah, I'd say so. Traffic calming is an effective method of reducing injuries and fatalities on roads. This is called a snet down. What happens when it snows is you can tell everywhere the cars have been, and so this tells us what areas of the road we don't actually need to have as road, which can be reclaimed for pedestrians or general traffic calming. So it gives us a lot of insight into safety. Now another thing that might be curiously called designing is sound design. We've got somebody in the back. I would like to thank all of our wonderful tech people pandering to the crowd. So the way something sounds inside any one of these setups, any one of these shows is we need to make sure that it actually comes through and is communicated to you. So yes, all of this is designing. Good designing like good engineering is done to solve problems. If you're not solving a problem, why are you doing it? So why is it we never seem to design for accessibility? My name is Nathan Hammond, and just like every one of you in this room, I design and consume interfaces for humans, and you can reach me at any one of those places. And see, the thing is, every single one of us humans is different, but that doesn't mean that somebody isn't going to try and put us in a nice little box. And what constitutes good design for one person isn't necessarily good design for another person. And sometimes what separates good design from great design is actually achieving universal design. And so this is the Stokey trip-trap. It's a really, really, really cool, interesting chair. So universal, you say, pfft, not possible. What the hell are you talking about, Nathan? Sounds like compromises. What about all of the edge cases? What about all of the things that make me a unique and special snowflake? In order to be a great designer, you need to design for that, too. And so I keep using this word design. Design is this process that we have to go through to actually solve problems. So if we're designing for accessibility, then we need to just make sure that we address accessibility as part of the design process. And that's not something you randomly do. It's not something that magically happens after a whole archive of PSDs gets thrown over a wall. And then magically somehow happens between that point and it appearing on a server because you just ran SCP. And it's not something that can be captured as a line item in some generic spreadsheet and then address for the first time three quarters of the way through the project. This is real, y'all. I have been on projects that have exactly like that. In fact, how many of you have? Yep. So it comes about three quarters of the way through the project. The project manager comes in and says, great. I'm really excited about this. What are we going to do to make it accessible? Well, at that point, honestly, you're not. You've kind of gone too far. And you're going to bolt on a whole bunch of things and just hope and pray that it works out exactly as you would expect. And you can ask Dr. Frankenstein how that worked out for her monster. So in order to actually achieve accessibility, you need both cheesy stock photography. And you need to address all of the design constraints as early in the process as you feasibly can. Now, that's not something that you can just throw your hands up in the air and say, the process is broken. It's not my problem anymore. It's not that simple. We need to actually solve the problems. That's what we are paid to do. And so, well, most of us. So human problems are difficult to solve. Budget problems are difficult to solve. This is the House Financial Committee. And I can't imagine what their life is like. And I'm really glad it's not mine. But I can talk politics with you guys later if you want. So how many of your companies actually have a budget set aside for accessible experiences? I count four hands, five hands, five out of all of you. That's a very, very small number. So what are we going to do about that? We've got budget problems. We've got human problems. But when it comes to computers, it's exactly, exactly what we tell them to do. And no more. And that's where we know that the human side of the process is broken. We, Emberanios, in particular, we should aim to make our tool set accessible by default. Horizon Tide lifts all boats and Ember's Convention over configuration gives us the leverage we need to make that happen. And so it's my privilege now to introduce my good friend and colleague, Jenison Asuncion, who is going to actually walk through a demo of a very simplistic application to actually give you a sense of what things are going to sound like. And so I'm going to set that up now. And here's microphone. Hi. Hi. Step back. Really, I'm not faking. OK, is that on? OK. Hey, everyone. Well, Nathan's setting up. I'm really excited to be here. I've been using screen readers for probably longer than some of you have been around. So, but I'm going to be, as I'm doing the demonstration, I'm going to be playing the role of the average Joe or Joanne out in, oh, South Sandwich or somewhere like that, who doesn't know from single-page apps. They don't know from, they just want to go online and use any website that any of you folks would want to use. So we're going to do a couple of demos. There's a way to shut all of those things up. Just really quickly, for any of you folks who are going to start playing with this after. OK, for any of you folks who are going to be playing with this on your own later after you get inspired by wanting to check out accessibility, you can turn on on your Macs, because you're all Mac users, I know. Command F5 turns voiceover on. Command F5 turns voiceover off. And please, whatever you do, if you're going to be doing any testing or experimenting, do it with Safari, because there's a little bit of different experiences if you're going to use voiceover with Chrome. And the lion's share, I would say 99% of any blind user using a Mac is going to be using voiceover with Safari. So if you want to be doing some real testing, we'll do that. So which one do you have up here? The good one? Static one. OK. So we're going to go around, like I said, pretending I'm Joe. I'm going to look around this page. OK, so I'm going to start moving around the screen. Again, let's pretend that this is the first time I'm coming here. So I'm going to want to look around to see what's there. The one thing you need to understand is, as you folks look at the screen and can I, here's the links and stuff, I'm doing the same thing with my cursor keys. I'm able to explore without firing links or anything unless I want to. So I'm just going to start looking around. OK, so there's a home link. Messages. OK, I'm going to stop there for a second just to demonstrate that I was just going around like link by links. But if I want to, right now I've just pulled up a list of links like this. So I can move around on the screen by links, by headings. OK, by links and headings. Another cool thing I can do if I wanted to is I can, I think I just went out of my, can you get me back in? OK, so let me, let me just fire one of these links and let you folks can see what the expected behavior is. Here we go, I'll go to messages. OK, so I'm going to activate this by hitting the space bar and holding down my voice over keys. So what it's doing right now is it's loading, it's loaded into the, into voice over what the screen looks like. But notice as soon as I click the link, it actually started speaking. And so I knew that I'd done something. So that's, that was the expected behavior. Nathan, did you want to bring up the other site? So, Don't try this at home. OK, here we go. So again, picture me, Joe, I'm at home. I just loaded this web page. OK, so I want to check my news feed. I thought I just did that. Let me do that again. Kind of confusing. I clicked the link and I expected it to start talking. Kind of frustrating. Maybe did I do this wrong? Let me try this. Oh, OK. Let me try a different link, maybe. So at this point, I'd be ready to just dump out of the site and maybe grab a drink or something. Because as you noticed, it just, it didn't do anything like it did last time. So Nathan is going to walk you through how to make that better. But I just want to hammer home the point that for the average blind person, going to a site, there's a set of expected behaviors. And so, obviously, you saw I activated the feed link. I tried doing that. Nothing happened. Just imagine if you clicked with the mouse and you just, nothing, the screen just stayed exactly the same. OK? That's, you know, as someone who's been using a screen reader a long time, I know to basically expect not every website's going to work anyway. So I know to look around at things. But the average person would dump out of this website totally. So if this was a commerce site, you just lost some business. OK? So that's a plain vanilla EmberJS application. If none of you have done anything with your applications focusing on accessibility, that's what your app sounds like right now. So I'm going to turn off voiceover. And let's go ahead and get back into keynote. And what? There. All right, so now, again, you can magically not see what I'm talking about. So clearly not perfect. We've got a lot of things we can learn from that. So first off, screen readers start reading from the top of the page on each load. And dynamically updating the DOM without providing any information about what's going on results in nothing, literally nothing. Now, your markup's still important. You saw that as we were moving through, we actually hit links, and those links were there. And that's a strong virtue of Ember relying on real HTML. So it's not all bad news. We've done a lot of things right that give us the ability to go back and actually fix some of our underlying problems. And other things like ARIA are still important. So we've seen what it's like when we've built an inaccessible Ember application. That's clearly not good enough. And so what we really need to do is we need to figure out how to be accessible by default. We need to provide hooks and constructs that make it more difficult to be inaccessible than it is for us to be accessible. That follows with Ember's convention over configuration and with making it easier to do things the right way than it is to do things the wrong way. So let's dive in on a case study called page loading that impacts literally every single Ember application. So we've identified a problem. And so we expect as a user of screen readers that we have this certain set of behavior. So let's come up with a solution. We've got all of these goals for an end user of a screen reader. This includes making sure it reads from the top. We need to make sure that it follows the patterns of respect. We need to make it clear to the user that the application state has changed. Then we've got all of these goals as a Ember author as well. And we have to work with current idiomatic Ember code. We want to make it backwards compatible so that we don't have to land this in Ember 3.0. We should be accessible by default. The API needs to not suck. And we need to make sure that it's extensible because I'm not perfect. You're not perfect. We're not perfect. And we're going to miss some edge cases. So if we actually follow things very similar to the extensible web manifesto, we don't end up with application cache. And so if you're intimidated, don't be. It's really not that difficult. So what we're going to do is we're going to start going through the process of how we can solve this problem. So we'll take an inventory of our Ember tool set. We've got all of these primitives available to us. We've got routers. We've got transitions. We've got routes, templates, outlets, HTML bars, which is a beautiful gift. And all of a sudden, we go, hm, you know what? I've got it. Enlightenment. We could focus on an outlet the moment it has shown up on the page. And it'll work, right? Well, maybe. You don't really know yet. So how many of you are on the Ember Core team and know Ember's internals like the back of your hand and no screen readers like the back of your hand? Empty set. So yeah, me either. But I had this idea of what I wanted to accomplish. So now it's time to check to see if it's actually feasible. So what do I know about screen readers? Well, first off, it's exactly like the browser wars. You remember how you had to make a change in Netscape to make it work in IE, and then you had this random weird behavior style sheet to make IE play nicely with, oh gosh, yes, all of those things. How many of you grew up in the 2000s and did that? So you actually have a ton of latent skills in this space. So really glad to have you. And so little other facts about screen readers. And also, here's some trivia about Ember. Bonus points if you know why any of these decisions were made. And then you will be made a core team member and expected to commit and change to a computer. So now that we know all of these things about screen readers in Ember, and you can go back and read that later, we want to actually design a solution that we think will cover our use case. We can start to explore the area. So we need to start thinking about API design. It's the primary use case. If you ever have seen Tom Dale's tweet, a transcluded, restricted, irrestricted, transcluded directive is basically a component. And having a language or having a very common interface for how you do something is a feature that is very present in Ember across the entire stack. And so the sign of a great feature is that we don't have to use it to still be able to benefit from it. All right, so in this case, after we've managed to avoid the feedback, we have a default implementation of something that maybe is like a focus hook. We have a hook that we add to a route that says this is what you do when I focus this route. It seems like a legit place to start. So what do you do? You dive into app.js. App.js is this app thing that gets generated by Ember CLI and none of us ever touch it, right? Seems mostly normal. But what if we use that to actually start overriding Ember core functionality? So here's a really, really simplistic function. It basically does nothing more than grab an element and set its focus. Okay, cool. Now, I just need some way to actually trigger that. I have no idea. So time to open up your debugger and trace through Ember code because none of us are Ember experts except for the 12 or 13 of you. All right, I'm looking at you, Stefan. So if we don't call it, it was just your name. So I don't have to call it except for in a situation where the route changes. Okay, so let's go when we enter a route. Seems legit. All right, so we've got a transition available to us when we enter a route. And so we're gonna override how all of that works. You don't need to read any of this code. But there is one weird situation where if I'm going from messages slash one to messages slash index, I don't wanna set it to messages dot index is content because realistically, you navigated to dot messages. You didn't magically try and go all the way to the index, though you may have. So you really wanna focus up a level. So fortunately, that's available and exposed to us as a pivot handler because of Mahdi's work. Machiner, Alex Machiner, I know people buy their handles. So great, now we've got promises. We need some way to call it. We've got this transition that's been wired up and that, oh dear, how do you do this? So this is what we do. After transition completes, we want to, after it's rendered, we want to focus the route. So we actually call the focus hook, blah, blah, blah. We've got a transition. We've got all of this little cleanup. And then basically after we've received our transition and we've done our focusing, then we want to actually begin our focus hook. So it's actually not unintentional that these get smaller and smaller because these become more and more about implementation details. Then we need to actually integrate this. So sometimes the changes that you make will actually require diving into Ember core so that you can actually call back out. And so that looks like this. And you might have seven or eight, maybe 10 lines that need to change so that you have some hooks or you need to pass something forward that was previously unavailable and you find out where that might need to live. And then you say, okay, I've got something. This looks really cool. I think it might work. I've done some tests. Jenison has told me this is only marginally less terrible. I pulled it up in JAWS. I pulled it up in NVDA. I pulled it up in voiceover. It seems to work. I've focused through a lot of it. It seems like it's a legitimate solution. All right, now it's time to contribute back to Ember. So you've created this feature. It all works and you're proud of it. Then you say, I want to make this a core part of Ember so that we can all be accessible by default. You write an RFC. And so that's up right now. This has a bit of conversation about a focus hook, but there are probably eight other different solutions, but I've created a reference implementation that we can use as straw man to move forward. I believe personally, very firmly, that this should be a part of core and we need some sort of way that we can actually be accessible by default. So you can use this today. You can go grab the code that we've done here as part of LinkedIn's efforts to actually pull into your application right now and have outlet focusing. It should work with all of your apps, except there's a couple of minor things that you need to be aware of. You have templates. Each of those templates must be wrapped in a grouping element. Otherwise it doesn't know what to start reading. So that can be a div, that can be an article, that can be a section. And you can't use automatically rendered templates anymore because you have to wrap them in a div. There are other sorts of weird edge cases that you'll discover, but it's a much, much, much better situation. So I'm gonna bring Jenison back up here. And we're going to do a simplistic demo of the same application, except this time I'm going to uncomment one line. While he's doing that, I'm really, when Nathan told me about all the stuff he's doing in Ember and when he came to work with us, I think it's really exciting that we have an opportunity to make this available. And if any of you have questions and stuff, you can find me on Twitter at Jenison. And I'd be happy to take a look at your stuff and give you folks' comments. And now we're gonna refresh and turn on VoiceOver. VoiceOver on Safari, Ember on the D111 window. LinkedIn, Long Page, Group, S-T-Board, Focus. The sport of Jenison's knowledge. Oh, okay. All righty. Okay, good. Yeah, I'll turn it on the tracker, on purpose. Oh, never mind. I'll get that. All right. The shoes is in my own press control option for the stage analysis. One password, exact knowledge. I'm in the thing, can you give me out of this? I'm losing my shit, I'm not a Canadian. I really am not. Okay, I'm Canadian, though. Okay, here we go. So what I wanna do is, I'm demonstrating the fact that blind folks also have the option of using the trackpad as well, similar to on the iPhone, so I'm just moving around here. So, okay, so let's try this out. Okay, again, no one's in the room. I'm Joe again. Do-do-do. There's a homelink. Messages link. Feed. Okay, so I wanna go to my messages. Okay, I'm gonna hit the space bar. Messages, forward, conversation with Jack, link, forward, conversation with John. Look at that. Forward, conversation with Jack, link. That's absolutely a lot better, right? So there you go. So with that work, and I know in the beginning it might look like a lot of stuff, but just imagine the impact you're having by taking that extra time up front. So that's the demo. Did you want me to do another one? Or did you think, okay. So if your clients aren't talking to you about accessibility and they're not bringing it up as a requirement to you to do, why don't you introduce it to them, okay? And again, like if you have any questions, at Jenison you can find me there and I'd be happy to chat further with you about that. Thanks a lot. Whoops, hold on. When we're doing this, it's a very, very different experience from a static site. We have programmatic control over the way you set your focus in the application. Now this has additional consequences in terms of things like scrolling behavior, visual layout, all sorts of other things that still need to be solved. These are open questions, open things that we need to address as a community as to how we want to handle it. But this is just the start. As designers of web-based applications, we have largely abdicated our responsibility of participating in the discussions and the design of the experience for users of assistive technology. That's something that needs to stop. We've spent two decades allowing others to actually make those decisions for us. This consistent behavior makes for a great baseline. We've been doing this for so long simply because design patterns actually make sense. But we can't change those overnight and we have an opportunity now to do better than we ever have in the past. So we will, we will do better. And we can start by actually taking a seat at the table and making sure that the experiences for assistive tech users are actually what we want them to be. And maybe a decade from now, we'll have something that we can all be proud of, something that we can look at and say, yes, we did that. And now the web is that much more accessible. So I'm Nathan, I moved across the country to work at LinkedIn because LinkedIn is doing incredible things. Thank you so much. All right. I think we got time for two questions. All right, so you added a focus hook. I'm not understanding exactly what you're doing in the focus hook. Is there a default action for that focus hook or did you do something to, all right. All right, so hopping off of mute. So yes, I want us as an Ember community to ship a default focus hook that has a normal behavior that all of us can expect. But you can override it in your own individual routes. That's my personal opinion. I haven't spoken to anybody on the core team about this. Sorry. But the goal is for me that we have a default focus hook available. And that way, everybody gets this out of the box. And so that default focus hook, as provided in my little demo here, actually was what you saw on the screen. And it just grabs the first element of that render node and sets focus to that. RFC 66, it's off. Any other questions? What should we be using for testing accessibility? Like is Safari with voiceover the gold standard now? Or is there a suite of things that we should be trying? I'm going to actually defer this one to Jenison, so we need a microphone. So on the Mac, definitely voiceover with Safari. Now, I would say, though, that the line share of screen reader users are still on Windows. So Firefox with a software called NVDA, it's just actually free. So NVDA, you can download that. And if you have a virtual box or a Windows machine somewhere. But you're definitely going to want to test an at least voiceover in Safari with voiceover in Safari, and then at least one Windows screen reader. So Firefox and NVDA is the other one I would suggest. And that's only for screen readers. I mean, we've been talking about this, but keep in mind, accessibility is more than just blind folks. All right, thank you guys very, very much.