 Hi, I'm Emma Torsky and today I'm going to share eight actionable steps to build more accessibly with Angular. Let's get started. Accessibility is a vital part of web development, ensuring that users can perceive, understand, navigate, and interact with apps. In fact, one in four US adults have a disability that impacts their major life activities. On wide, about 15% of the world's population, more than one billion people, have some form of disability, with about two to four percent experiencing significant difficulties. In this course, Ally is shorthand for accessibility. Notice that the A is followed by 11 characters and a Y. Today, we'll use best practices and built-in techniques to address common web accessibility issues in a demo dumpling shop Angular app. By the end, our app will meet Accessibility Guidelines, WCAG 2.0, and ARIA 1.2, and pass Acts and Lighthouse Accessibility Audits. Everything you need for this project is linked in the code lab in the description box below. All of the getting started code is already in your GitHub repository. To begin, clone the code and open it in your favorite dev environment. Once we clone, install and ng serve, and you'll see your starting point is a basic restaurant app designed for this code lab. The code has been simplified to show the concepts in this code lab, but it's pretty non-functional. For example, let's see, if I click purchase, obviously I'm not going to actually let you make a purchase. How do we know what we want to fix? We're going to start each example by recognizing the accessibility issue using a mixture of manual and automated testing. In the currency of the web, manual testing accessibility is mandatory. You have tools that can identify accessibility issues, but no tool can certify that an app is fully accessible. Manual testing ensures that you test for a breadth of ally concepts that include logical content order and feature parity. To manually test applications for accessibility in this course, we'll be turning on the computer's built-in screen reader and navigating through the app with keyboard navigation. For more information, you can see semantics and screen readers, or if you go in the code lab, there's some good resources on how to look for all of this stuff here. So I'll go ahead and turn on my voiceover. And you can see that I can navigate through and insert into this. So for the course, I will be exiting that just because I don't want to fight with a voiceover, but as you can see, that's what you'll be doing. You can also use the Mac built-in voiceover, which is what I was just doing by clicking enable voiceover in the accessibility settings of your system preferences. Or what I'll do is press touch ID three times, and that's the short key for turning the service on and off. We're also going to be using Lighthouse to run accessibility tests. So if I enter Lighthouse within my console and I choose just accessibility for desktop, I can generate a report, and I can see my starting place of everything that I need to fix. Let's see. I might need to stop and restart it because of how many things I'm sharing. And while that's going, let's go ahead and look over at our last thing, which is if I go into my code, you can also use Angular's ESLint rules to link your code for common accessibility issues and automatable attributes that we can check for. So if I go to all of my code and I enter into my ESLint RC JSON, this is going to be all of the ESLint tests that I am checking for. And in my rules, you can see that the code already comes with these, I believe 10, I don't know, I'm not going to count, but 10 accessibility issues or rules. And I'm choosing to say 2, so this value can be 0, 1, 2, with 0 being nothing, 1 being a warning and 2 being an error, and that's choosing how when I run my Lint rules, these issues are tested for. So you can go to the ESLint repository to see more of these, but these are the 10 that we recommend, and you can find these all again in the code lab to add. So that's a great really quick lift if you just want to automate a little bit of accessibility. And if I go back to my terminal, I can actually do MPM run, and while I'm waiting for my Lint team, I can see that I'm using 2 new of a version, but it'll still run, and we can see that we have one error being caught by one of those rules. So the rule for click events have key events. Can see that there's something in my app that's not working correctly because there's not a key up or key event associated with something in one of my templates. So we'll fix that in a little bit. And if I go back to my application, I can see that I get an 87 for my Lighthouse accessibility score, which isn't bad, but we definitely want to get up to the green area of both 90, and we can do better and get almost to 100. So we see we have a bunch of different itemized things here, and those are going to be some things we fix. So now that we have a starting place, I want to get started by fixing our first issue of the eight identified issues that I've picked out again by manual testing with voiceover, by running this Lint check here, and by doing this Lighthouse accessibility test to see what's going on there. The first issue that we're going to fix is defining a unique page title. Providing unique, concise page titles helps users using Ally services quickly understand a page titles content and purpose. Page titles are critical to users with visual difficulties because they are the first page element announced by screen reader software. Angular is a single page application framework. And as a result, a majority of the transitions, such as moving to a new page, do not involve a page reload. Until recently, this meant that each page had an identical page title and provided no value for understanding the page's context or purpose. So if you can see that here, let's identify that issue and then talk about how we're going to fix it. So as you can see right now up at the top, we're looking really small here, but it says Ally and Angular. And if I open up a new tab of this and go to maybe a different page, let's go to our story. You can see that this is like the about page of our website, and it's still at the top just says Ally and Angular. And if I open one more just to really prove my point, let's say I go to the last page, so find us. So this is like a map if I had location services that said like where I'm located in San Francisco. And we can see that all of these have the exact same page titles. So there's not a lot of information. So if you can think about this in like, let's say a Google search website, let's say you had like 30 tabs of Google search open, and all of them just said Google search at the top. But you had 30 different searches and you were trying to find that one tab. It's really hard because you have to click into each one. So both from like a UX standpoint, it's just a terrible experience to have to go into each tab to figure out what's there. But also from an accessibility standpoint, that's the first thing your screen reader is going to read to your users. So you want to convey what's on the page in that page title. So in Angular V14, the router added a built-in method to define unique page titles out of the box. This provides a streamlined approach to ensure developers follow page title best practices. To fix this, we're going to use that built-in tool. So if we go to define page titles, we're going to go into our app routing module. And we're going to add this title property. So this is the new thing that was added in version 14 when you update. So I'm going to take this and I'm going to go into app routing and go into my code. The other way you can check any of this is since we're on step four of the code lab, you can search to do step four and quickly jump to where you want to go. And what we're going to do is again, add that title property. So like here is a title. And then if I save, I should be able to go back. Let's go to this running. It recompiled and see, here we go. Here's the title. So that title was automatically applied. So this is super easy. If you're familiar with former versions of Angular, it's much more difficult. And just for the sake of time, I'm going to copy and paste this code to define my new routes and replace it here. And then this can be deleted. We no longer need that to do. And if we look at the best practice here, what I like to do is convey like what that page is. So this is the shop page where you could buy things. So our shop dash and then the overall website. You can see common patterns of this. If you go to other websites, again, like Google search, we'll say like what the search term is and then Google search. So conveying the most important or most specific thing about the page and then the more general context. So specific then general is just like a best practice that I like to follow. But if we save that and go back, then if I open up those tabs I just had, you can see that now I have our story, Angular, find us, Ally and Angular, and our shop, Ally and Angular. And so we are seeing the difference without even needing to go. So if I'm here and I want to go to that like find page, I don't need to go into each one. That's super cool. And again, I'm just really excited because again previously you would have had to add and manually manage these page titles and apply that in your app component. So this is a super easy way where I'm adding like, I mean literally no lines of code were added, just like a few characters on a few lines. So super cool, super quick, super easy. Now that we've done that, we've verified our change and we're one step closer. So let's keep going. Your design might seem cool, but it's not cool if people with visual impairments like color blindness can't read your content. The web content accessibility guidelines or WCAG 2.0 define a series of color contrast ratios that ensure that your content is accessible. In Angular and on the web, you can define color palettes that ensure your components meet these standards and are visible for users with low vision and color blindness. So for this, we're going to identify the issue by inspecting the page with the little Chrome DevTools inspector. And the thing that's really standing out to me on this page is this matte icon. And if I click on it and hover it, I can see that that accessibility contrast is not good. So again, if I hover, you can see that that contrast value in accessibility is quite low. So significantly below the WCAG guidelines. If I go down to that value in the actual Chrome DevTools, by going up, I can hover it. And I can see that that contrast ratio is quite low and I can actually try and fix it to either 3.0 or 4.5 and see that it needs to be much darker for the recommended value. So super cool that Chrome has that built in. But now let's go change that in the code. So to do this, we are going to go back into our code and look at the palettes we've defined. And we can see that I have this value. I'm using this pink palette, right? I'm really enjoying this pink, red, quite bright vibe. But this text value is 500, which if you're familiar with Angular, you know that the material color palettes that we're defining are using values from 100 to 900 with 100 being the lightest and 900 being the darkest. And so for the 100 to 500 contrast is quite low, right? We're only like two color steps off of one another. So I'm going to go ahead and change that to 900 and go the furthest away that I can and go back and see how that changes it. And if I reload, we can see that anywhere that that really light color was is swapped to a really dark color. And I can also hover it and see that, again, that color contrast is now above four, which is meeting the guidelines that I need. So I've met that color contrast ratio. I can also go this is something that, again, that lighthouse audit is going to do a really good job of checking. So this is the contrast here because again, this is super automated, right? We can test and see if colors need it. And here it was pointing out that those icons were not doing very well. So now if I rerun my audit, I can see my percentage should go up. Yeah, so we got two more points there and that contrast is no longer there. So we verified both manually by hovering and by running the audit again that I fixed the automated thing and my palette is now fixed. And the benefit of doing it in a palette is that anywhere that you're going to use icons or things that are using material in this application that are using that text color are now going to use that accessible color with the highest contrast. So super great to do it in a more generic place like your styles versus individually overriding like that that color is darker. The broader you go, the more accessible it's going to be. We fixed two things. We've gotten our score up two points. Let's keep going. And our next one is going to be another thing in our templates, which is using semantic HTML. We're now on step six and let's talk about native HTML. So if we go to our application, we're actually going to be on our our story page here and native HTML elements capture a number of standard interaction patterns that are important accessibility. While a paragraph can be styled as a span or a div can be styled as a button, semantic HTML elements ensure that screen readers and keyboard navigation understand the interactions and control your HTML. When you're authoring Angular components, you should always try to reuse these native elements directly when possible rather than re-implementing well-supported behaviors. This ensures that the page has good content structure and natural content flow and that the tab is in a logical order to assist users navigating the web with effective use of the keyboard. So here we have two things that we're going to fix and the first we can actually see again in that lighthouse score if I go back but we can see that it's getting mad that the heading elements are not sequential. And if I actually go to this other tab and run another lighthouse test on this, it's going to get even more mad at me because it's going to notice that each of these HTML elements are headers in the wrong order. So these heading elements don't make sense and are not sequential. Otherwise, this page is looking pretty good. So to fix this, we're going to go back into our code and we're going to go to that. We're going to go to do six and we're going to notice that in the about component I can even look at this and say, okay, I start with an H3, a header three. I go to a header two, which is supposed to be higher than an H3, right? This should go one, two, three, four, five, six. Then I go to a five and a six but then I go back to a five. Then I go to five, then I go right. So this number order doesn't make sense if I'm trying to go sequential. I'm not doing a very good job at that. So we're going to go and I provided the code snippet in the code lab but we're going to take this and we're just going to reorder these things so that they have headers and it's going to be the same text but instead of using headers to decide the styling, I'm going to use headers as what they are which is semantic HTML element that our voice over would understand as the header of a section and then anything within that section I'm going to mark as a paragraph because it's essentially just like a line of text. It's not a header. It's not like this section information and then I'm going to use styling and specifically angular materials built in styling classes to apply some styling to make sure that I get this same style that I really like without having to use semantic HTML to sort of hack it. So if I save this and I save this and I go back we should see that. Yeah. So that reloaded and we now have what is clearly two headers with some text in the middle that still has fun styling but isn't all a header. Right. In general, text and all the headers and if I rerun that white house I should see a fix there which is exactly what we're trying to do. And yeah. So this page is now at a hundred which is a little premature but quite exciting because again we fix that semantic HTML thing. Now if we go back here we're going to fix the other semantic HTML thing which if we inspect we're going to see that this purchase button right it clearly like in theory the idea of this website is like here's my dumpling preview. This is like a super cool nuanced dumpling shop where like you can order hot pink dumplings of different quantities of different filling types. So let's say we're going like chicken and tofu and I want to click purchase this purchase button should be how you purchase those dumplings right but I can notice that it's actually just a div that's styled to sort of look like a button and even in the HTML it's called button it just is a div which is really not what we want here because again we want to use the semantic HTML for this we want to use the native button attribute because when we turn on something like voiceover and we navigate we can get to that control and voiceover will know what to do with that known interaction. So to do this we're going to go to do number six the other one and we're going to see here and see that even within our code editor we know that there's an issue here right so this is what was being thrown by that lint error earlier is it knew that this div has this click attribute that like it really shouldn't and so we're getting an in browser error because I made that ng lint error. So if we copy and paste the code that I provided we're changing this to a button with angular material flat styling just coloring it a little bit and then putting the exact same class on it putting the same click event on it and just giving it the exact same text. So again, the before and after is very similar. We're just making this a button and by doing that we get rid of the in code editor error and if we go back to linting we can run that lint test again and see that that should also be fixed and while that's going we can also go back to our shop and we can see that there's now like even the UX of this is great, right? So if I zoom in so you can really see if I like click there's like a click interaction, right? It's a visible the UX is great, right? So we think about accessibility as just fixing things for people using accessibility services but a lot of what we've already fixed today right like this color contrast just makes it easier for everyone or this like clicker interaction like the fact that it now has hover and you can see that the like cursor changes and there's like known interactions there in animation is like a really great benefit where fixing things for accessibility is not just for people who we typically think of as needing accessibility services it's really a better user experience for everyone. So if I rerun that accessibility report on this and I go back and look I can see that all of my linting has passed so we're already much closer and we're up to the green space here. So we're up to a 91 because again we fixed this button issue and we fixed this page all with just using semantic built in HTML. So a lot of great things happening already and we're only about halfway. The next thing we're going to do is use selectable controls with angular material. So here you can see that one of the complicated interaction patterns for accessibility services is nested controls in this demo we're using all of these checkboxes right and we have nested controls where you can get like chicken but not impossible meat and you can get tofu but not bok choy right these are nested controls where there's vegan there's meat but there's also nested options. But how do you indicate to a user that you selected a subgroup or navigated to the parent item? So let's think like when you're going through this interaction with a voiceover how do you indicate that bok choy is a sub child of vegan or that meat is a parent of chicken and impossible meat? That's a really hard pattern to try and work with. In angular simplified menus and controls create a much more navigatable experience and so what we want to do is simplify those controls as much as possible and use the angular material list box to build out this interaction pattern. So I'm not going to turn on voiceover just because running a screen share while also doing voiceover on this step is like quite difficult but as you can see it's that same interaction pattern that we had right where like you really can't convey these nested controls very well and it's just a really poor experience for everyone involved. To fix this let's simplify this a little bit so we're going to go to step seven uh scroll up and we're going to be replacing the check boxes with material check boxes. So first if we go to our code I'm going to swap here and we go to to do item seven. We can see that to create selectable controls we have a ton of stuff here of all of our selectable controls in our shop component and what we want to do is just simplify this. So we're going to define our options a little bit differently. Here so our filling option instead of being a set of Booleans is going to be a list of strings and I made them a little bit fancier. So now we have a list of fillings. We have our selected fillings which is again a nice little ArrayList and then we're just going to in our faux purchase correct that the way we make a faux purchase is a little different because of that ArrayList of strings just strings there you go strict taping that's really getting the best of me here. So now we have just an Array here of our fillings that we're excited about. I like made them a little bit fancier because why not again an ArrayList of our selected ones and then if we go down here into our selected fillings when we make a purchase we're just going to go through create a list of each of the selected fillings that we have and then just print that and that's going to be the flavor of dumplings that we're buying. So now that we fixed that part we're going to go into the actual controls and just replace this like really complicated whole UL list or unordered list with this provided here which is significantly shorter and what it is is again a matte selection list of list options where each of the fillings that I just provided is going to be one of the options that I give. So I'm using the ngModel to make sure that I know that all of the selected fillings are going to be my selected controls and just again give that selection list and here notice that I'm giving an ArrayLabel so I'm providing context for what that list is for ArrayList or screen readers so that when it's read as a list it's read as the dumpling filling list so just something to indicate there and then just each of my flavors is going to be one of those so quite easy and then I believe we can also just get rid of some styling just to make sure we clean up some things so within that shop component that last to do is just a quick little cleanup and if I save all of that and I go back we can see that yep without doing very much we already have a bok choy and chili crunch a tofu and mushroom a chicken and ginger and impossible meat and they're all within fillings and you can see that the styling changed quite a bit so I now have those click interactions it's not that unordered list but I've also removed the nested controls so if I went in with voiceover I would very clearly hear that this is a list of my fillings I would get to pick each one and I wouldn't get confused about whether or not I was ordering like the parent of what flavor or whatever and you can see that I believe if I run the lighthouse again I would also get a slight bump just because I'm not using sort of like a less supported pattern there so quite exciting if we move on the next thing is going to be very closely related which is step eight is talking about aria in that template that I was just in I showed that I was using this aria label right and so you see this a lot where aria labels are going to provide context for what that control or what that HML element is doing and how to be read to a screen reader so that's not just a button it's a purchase button or it's not just a list of controls it's the dumpling filling list so it's providing that context for the screen reader or accessibility service so the next thing we're going to do is we're going to add a label to something that's missing the label so this was caught if we go in we can see that here the first issue we have is form element does not have associated label so again you can think of aria as a lot of those labeling technologies and if we look we see that the input didn't have a label here so that was that filling and we already added that right so that one was fixed we ran it and the next one is aria input field does not have a label so this slider that's deciding how many dumplings I want I always want more than bakers doesn't doesn't have a label as well so if I go into to do eight I'm looking to see what aria label is missing and what I'm noticing is this mat slider is an accessibility it's a material component slider so it already has a lot of built-in accessibility just because it's the material component version it's a known interaction of a slider but I'm not seeing any aria label so I'm not providing context so here I'm going to go back to my code lab just to make sure I get the code right and all I have to do is add this aria label value so all I'm doing is adding just that aria label and that's solving it so then if I went in with a screen reader or I ran that lighthouse command again I would see that instead of just being an unknown slider it would be read as dumpling order quantity slider so again you can think of this as providing context to what that interaction is and I actually would probably go back and remove the word slider since the role would be read in a different place so this is the context not the interaction and then the slider would actually read that and a cool thing is if you hover as you saw there I could actually open the aria reference which is what I accidentally just did if you want more information on that so I'm going to go ahead and I'm going to run one more accessibility report just to see that and I fixed two things with aria now so I should see that fix and again this is like pretty intuitive yep we're at a hundred percent more than halfway through already at a hundred percent we're still going to do a little bit more which is why I said that manual testing is super important but from the chance of automatable fixes we have fixed everything that was automatically checked so that's a super cool goal I'm going to go ahead and give myself a little bit of a pat on the back hopefully you can too and I'm going to exit out of lighthouse just so that we're not too distracted by that but if you think about that it makes a lot of sense right like let's say you're on a screen reader and you get to the point of selecting the quantity and you get to like you know you change it up to like 13 there's no context for like what the 13 is of so we want to make sure that anytime you're making a slider selection there you're being told that it's you know 13 dumplings that you're about to order that the order quantity of dumplings is 13 that way you don't get to the end and click purchase and say like well I don't know I like got 13 maybe that's like 13 fillings or 13 boxes versus 13 dumplings right I think I would be incredibly sad if I made this one because I thought that it was like one box of dumplings and then a single dumpling arrived at my house that would be very sad we've gotten to the point of doing everything that we can without really digging into some of the nuances of angular and we've done a lot to be clear we've done page titles uniquely just by using that built-in router property we've changed the color palette to have color contrast and we've really looked at the semantic HTML and controls as well as changing that pattern of this checkbox to be a little bit more intuitive and digging into the aria attributes of our templates to make sure that they're the most accessible possible so now we're going to move on to part nine which is where we add the power of the angular CDK accessibility package to fix common additional accessibility issues the thing about this is the CDK's accessibility module helps solve more complicated angular specific issues and by the end of the section we're going to add the module so that we can continue and do more of this you can read more about what the CDK Ally package does on our docs website but you can really think of it as providing a set of tools just like anything in the CDK or component development kit it's going to provide you a bunch of tools so that you can build components that are more accessible it's going to give you ways to hook into things like focus live announcement, contrast all kinds of more nuanced interaction patterns that are common on the web that we want to give you a direct way to hook into those APIs and control so to do this we're going to go to do step nine and it's going to be really easy all we're doing is adding this module so we want to import the accessibility module just like anything in a module we're importing it and then it's getting mad because we didn't use it but that's okay because we can add it to the top and then it's imported and we can save it and close out some files and go let's see it should have recompiled we might want to restart when we import a new module I always like to just re-serve my application just in case to make sure I'm getting that import but yeah super simple so we're getting that Ally module again the shorthand for accessibility from the import in the CDK and really that's about it and I'm realizing I put this little low I actually want it to be up here with all of my packages and cool so we did that super easy probably the easiest step so far because there's no visual change right we just imported a new module let's keep going and look at three ways to use this module the first thing we're going to look at is focus trap if we open I previewed this earlier but if I open my color here I can select a new color so let's say like right now my dumplings are gold let's say I want to make them light green so I could apply that color they change color and in theory they would arrive and be a different color or let's say like I went into dark mode let's say I'm really digging this like plum color for spring it's like very seasonal and so I can apply that color so when I open this dialogue what I'm doing is I should be opening this dialogue and redirecting the focus of like a screen reader to know that it's inside of a dialogue so if I had voice over open I would want to contain the focus within this dialogue because while this is open I want you to make a selection here before exiting out right you can click out but you haven't made any change there so I want to make sure that you know if you select this color attribute that I'm sending you to a dialogue and I'm letting you make a change here before applying the color and going back right and I want to make sure that the user knows that they entered a dialogue what they're doing in that dialogue and then when they exit I want to make sure they know what happened in that dialogue so really common accessibility pitfall is that you'll open this dialogue and somehow the screen reader will be able to continue to edit things outside the dialogue while it's open right that I could like change the quantity of dumplings while within that dialogue so I want to make sure I'm trapping focus and this is something that we call focus trap the angular CDK trap focus directive traps tab key focus within an element and this is intended to be used to create accessible experiences for components like modal dialogues where focus needs to be constrained in order to do this we're going to go to you gust it to do stop 10 and we're going to actually go in and add just this CDK focus initial and all that's doing is letting the user know where to put the focus so CDK focus trap if we open to the documentation is going to have a lot of stuff there angular angular material and if I go into the components in the CDK I can see that within the accessibility package I'm looking at focus trap so this is things where I want to trap focus and there's a bunch of options here so there's trapping focus there's changing the focus region and there's indicating initial focus so for the use of this codelab all I'm going to be doing is making sure that the initial focus is where I want it which means that it's on the selection list so if I go to to do step 10 I'm going to see that initially if I were to use a screen reader and I go to this dialogue the initial focus would be on the entire or would be on apply color right it would be on like exiting the dialogue and so I want to actually move the focus to the entire window so that you go through each of the colors before doing that so that you know about that so here I'm going to make one change which is just adding this CDK focus initial which is saying this is where I want the initial focus to be on that list of colors and it says easy that stop and then if I see it and I go back it's recompiled and again accessibility short cuts you can hear that I turned my voice over on oops accessibility short cuts and if I turn voice over on and I move it over so you can see what is being said and I go here and I enter you can see that initially that color okay so you can see that when I selected that color and I opened the dialogue I'm now focused on white the first color in that and if I scroll through I can select a color so I'm selecting color and then I can exit by going to apply color and I'm going to exit out of this so that I'm not fighting with voice over but what you saw there to recap since I was fighting with voice over is that I selected this color and now my focus was on white the first color there versus one of these controls to exit right so I was put directly into the colors and I was told what I was selecting the dumpling color and then I was able to apply the color and exit so that was done again using the CDK focus initial but there's also really great stuff that I would highly recommend if you're using dialogues on other things like chopping focus again I didn't need to chop focus within that dialogue because I am using the math selection list which automatically knows when I open this mat dialogue with a mat dialogue action to control and trap focus I was just making sure that the focus was where I wanted so we've done that we've verified and that's step 10 off the list so we verified it our color picker now has cracked focus trapping and we're super close to the end our next thing is going to be super super simple are similar to what we just did which is again looking at that color indication and this is announcing changes so when I go and make a change let's say I change the color right to green yellow this like weird neon when I exit I want to make sure the user knows what just happened so I want to announce to the screen hey you just changed the color so you know like there's been a change to the screen you exited that dialogue and something happened another common thing is if you make a purchase I want to announce that that purchase was made let's say this is like hooked up to some sort of payment platform and you've exited and you've made a payment I want to make sure that this payment or this purchase that I'm just console printing for now is announced to the user so that they know what they're purchasing or going into another window to purchase so to do this we're going to use something else from our accessibility CDK package which is called live announcer and so live announcer is going to allow you to notify when something on the screen has changed you can imagine if you're attempting to submit a form or complete a purchase and not knowing that an error has popped up right error handling is super frustrating let's say you go to submit your address because you're making a really big purchase and the zip code is off or something and so you're just sent back to that form and visually there's an error on one of those form attributes but to somebody who is non-cited you're not being notified of what the error is and you're having to go through the entire form again to figure it out I know it's really frustrating for me when like I don't know what the error is and I'm being sent back to a form so error controls are a great place to use live announcer which announces messages for screen readers to use using the aria live region to ensure screen readers are notified about those notifications and live page changes so to do this we're going to add the live announcer so we're going to go to do 11 and we're going to go into this component and add the live announcer attribute if I go to do 11 we did that we're going to first go into the component let's see yes so first we go into the component we import the live announcer then we go into the actual class and we want to just add the live announcer to the constructor here and I'm just copying and pasting it so that you know what is happening but in this constructor here I'm just going to replace the constructor with this other constructor which includes that live announcer added so let's see it looks like I am missing something here change color and here the last thing I'm going to do is in my change color I'm going to change how I change color so here in this change color method providing a color and then I'm reemitting the new color and what I want to add here is this live announcer attribute right so I want to change the color but I also want to announce before changing that that color has changed so here in this to do I'm going to add this dot live announcer and I'm going to announce sensible thing that the new color is been selected so before I close and I'm going to do that anytime the dialogue is closed just to notify and then the other thing I'm going to do is I'm going to go into this component and I'm going to do the same thing again for that purchase that I was making right so the other to do is to do the exact same thing and add that live announcer but in my other place which is to import it to my shop component and do the exact same thing which is import live announcer from the CDK Ally I'm going to go into my constructor I'm going to make sure I have a reference to that live announcer just a private live announcer instance and then I'm just going to again use that super simple thing we're on my purchase my faux purchase I'm going to say this live announcer so of my instance I want to make an announcement and I want to announce the exact same thing I'm console logging which is what that purchase is so that in theory you would notify again this is sort of more of like a demo of what I would do with this but error handling is a really great instance and so here I'm going to go back make sure it recompiled it did and I'm going to turn on services and before I do so what you're listening for is when I click this button I want to hear or you'll be able to visually read that what is being read to the screen or what is being read with voiceover includes that announcement so if I turn on my services again accessibility shortcuts check and I show you what's being read application now in our shop purchase button group main you are currently a button to look at this button press control this slide is getting inside purchase purchase 11 buttons in the color bowl comment result purchase 11 buttons in the color bowl change dumpling wrapper call like green selected change dumpling wrapper color button group main select color like green you are currently a button group to voiceover yeah and so there you saw with a little bit of hacking of voiceover given the screen record happening that when I clicked purchase I was announcing again that I had made a purchase of this gold color and then I went and changed the color to light green and you saw that it announced that a new color had been selected so again these are instances of using this instance of live announced to make sure that the user knew and now drumroll please we have one last thing which is maybe like the coolest but a little bit more niche thing and that's something that we're going to call high contrast mode so Microsoft window supports an accessibility feature called high contrast mode and this mode changes the appearance of all applications including web apps to dramatically increase contrast in Angular we want to respect the user's preferences for this app and so we want to use the high contrast mode detector which again is going to be another attribute within this accessibility package to make sure yes targeting high contrast mode to make sure that we are respecting the user's preference there so Internet Explorer Microsoft Edge and Firefox support this mode and Google Chrome currently does not support window high contrast mode but there are changes being made to CSS all of the time to better respect again different forms of high contrast different color palettes prefers reduced motion there's a lot of CSS things we can do for accessibility and so this is one that we specifically want to look at for styling so here since I'm currently in Chrome I'm going to just mock what this would look like so that you can understand a little bit of the difference and so we're specifically going to be looking at this purchase button here and if I go into to do 12 I can see that in high contrast mode I would want to change the difference between these two colors to be essentially like white and black right it's it's almost white and black and how high the contrast is you can think of a CAG as using a 4.0 color contrast ratio that's what we changed initially where these colors are quite different think about if this background was white and this was black like the highest contrast you can get is what we're looking for so to support high contrast mode we're going to go into our style CSS and we're going to use the CDK high contrast mixing that's provided with accessibility so we're going to import this in again to do 12 our last one and so we're going to import that and then we're going to go down a little bit and we're going to use this include in purchase button so we're going to go to our purchase button we're going to add the include and so this is include like the SAS thing and then in high contrast mode so when the service or when this application is being served or used in a high contrast mode setting with that user setting turned on we're going to add a really thick outline and we could even like do more right like let's go big here and then we're just going to change the color to like the lightest possible version of again this pink palette that we're in just to go as light as physically possible and so if you want to see what that would look like since again we're not in high contrast mode I'm just going to go ahead and change it here so that you can see again what we're doing there and so here my computer is mad at me let's not this back why let's try use nope try use no tilde can't find style sheet to import let's try always fun okay well as we debug this and regenerate what I'm trying to show here is that if we go to again these two things we're using this mix in to ensure that when we're in this high contrast mode which is provided again by the accessibility service that we're adding the context of trying to make the purchase button as dark as possible again just to show that difference and it is really unhappy with that import there's something about strict importing that is not working with my compilation okay let's ignore that for now so if I go back can you compile please if I go to the instances of this if I just mock what's being happened here or what's happening here I want to show the difference and so if that import is correct which it will be in the code lab you'd see that if I was a user that had this setting on that I would then see this very differently styled purchase button that really emphasizes what's happening there has a much higher contrast color the outline is much significantly larger so it's really showing that control and it has the exact same behavior but again it's just emphasizing that styling so this is for maybe a more low-visioned user or somebody who has these controls on this is a really common setting for people who sometimes have chronic migraines who need to see really high contrast to not have to like focus really hard and discern the difference with like small nuances and so if I was styling my entire app with high contrast mode in mind I would go through and each of these controls I would make sure had the highest contrast had the largest outlines I would change the style even of maybe these dumplings that I'm showing to have a much thicker line to make sure they have maybe like a white background so really restyling your application again with this high contrast mix in being included to make sure that you can do that and again I have changed this import so you would just want to make sure this import is pointing to the correct thing it's possible it's index don't worry too much about this oh okay well we're going to keep moving on but in theory oops hello okay let's make sure we compile so a little bit of an anticlimactic end but let's move this back to not a ridiculous high contrast to the other one and we can see that visually not a lot has changed from our application but we've done a lot to change the different controls we have almost wrapped up and I just want to do a quick recap of the eight steps we did so you can think about the changes you made and how they might apply to applications you are currently working on that aren't a dumpling shop because this is fun but you know there's a lot of other cool things out there that are using accessibility and it's important that all of them think about accessibility and make these changes so the first and probably the coolest is if you update your application to version 14 you can automatically change that page title and again this is like super cool super built-in it's very new but if I look for that routes definition I can see that all I had to do was add that title and now I'm seeing these unique page titles up at the top so that was step one step two we changed this color here of this icon to make sure that it had the highest possible contrast ratio and met WCAG guidelines in step three we changed the semantic HTML of our purchase button and our story to make sure that they're using semantic HTML in the next one we made sure that we had selectable controls by again using aria to apply an aria value to this slider to make sure that we were giving the user context with aria labels to ensure that we were notifying them what they were doing on the screen and then we went over to our other control and simplified our controls of our checklist here of all of our fillings so that instead of using nested controls and a complicated pattern with low accessibility we could simplify the controls with a similar result to ensure that we have higher accessibility of our control system and that was everything we did without any angular package then we went and we added the angular CDK accessibility package or ally package and we went in and we changed three things there we added the focus trap to control focus of this color dialog we also announced changes when we exit the color dialog as well as when we make a purchase let's go in dark mode for this using the live announcer to announce those changes and finally we looked at high contrast mode to ensure that users with a selection for a specific change on their screen or a visual indication of preference are being respected by our application using the built-in high contrast mixing that we provide and so we did all of that and we fixed eight super quick super easy things for how to fix accessibility in this app congratulations you addressed common web accessibility issues in your angular app what was your favorite step my personal favorite is angular v14's new streamlined page title options directly in the router it's a game changer for out of the box accessibility to see all of the solutions check out the main branch in the get hub repository you now know the key steps required to resolving eight common ally pitfalls in your angular application thank you so much for joining me don't forget to follow angular on Twitter and YouTube and I'll see you next time