Build more accessible apps in Angular
Aug 15, 2023
Build more accessible apps in Angular
To watch this keynote interpreted in American Sign Language (ASL), please click here → https://goo.gle/3KYkHqF Learn how to improve accessibility within an existing Angular app. Explore Angular v14’s latest features to add dynamic page titles, check theming color contrast, and explore the CDK’s a11y package for more advanced accessibility controls. Discover how to identify and develop for eight common accessibility use cases to apply to your own web applications. Speaker: Emma Twersky Watch more: All Google I/O 2022 Sessions → https://goo.gle/IO22_AllSessions Web at I/O 2022 playlist → https://goo.gle/IO22_Web All Google I/O 2022 workshops → https://goo.gle/IO22_Workshops Codelab → https://goo.gle/3FC2IFr Subscribe to Google Chrome Developers → https://goo.gle/ChromeDevs #GoogleIO
Content
0 -> [Music]
5.12 -> hi
5.839 -> i'm emma torski and today i'm going to
8 -> share eight actionable steps to build
10.4 -> more accessibly with angular
12.639 -> let's get started
15.04 -> accessibility is a vital part of web
17.359 -> development ensuring that users can
19.52 -> perceive
20.72 -> understand navigate and interact with
24.08 -> apps in fact one in four us adults have
27.92 -> a disability that impacts their major
29.92 -> life activities
31.679 -> worldwide about fifteen percent of the
34.32 -> world's population more than one billion
36.96 -> people have some form of disability
40 -> with about two to four percent
41.92 -> experiencing significant difficulties
45.68 -> in this course
47.12 -> ally is shorthand for accessibility
50.16 -> notice that the a is followed by 11
52.8 -> characters and a y
57.039 -> today we'll use best practices and
59.44 -> built-in techniques to address common
61.6 -> web accessibility issues in a demo
64.08 -> dumpling shop angular app
66.64 -> by the end our app will meet
68.56 -> accessibility guidelines wikag 2.0 and
72.32 -> aria 1.2
74.08 -> and pass axe and lighthouse
75.92 -> accessibility audits
78.56 -> everything you need for this project is
80.64 -> linked in the code lab in the
82.159 -> description box below
84.56 -> all of the getting started code is
86.32 -> already in your github repository
90 -> to begin clone the code and open it in
92.799 -> your favorite dev environment
105.6 -> once we clone install an ng serve and
108.72 -> you'll see your starting point is a
110.399 -> basic restaurant app designed for this
112.479 -> code lab
123.92 -> the code has been simplified to show the
125.759 -> concepts in this codelab but it's pretty
128 -> non-functional
129.84 -> for example let's see
132.879 -> if i click purchase obviously i'm not
135.12 -> going to actually let you make a
136.239 -> purchase
137.36 -> how do we know what we want to fix
139.599 -> we're going to start
140.8 -> each example by recognizing the
142.64 -> accessibility issue using a mixture of
144.959 -> manual and automated testing
147.92 -> in the current state of the web manual
149.84 -> testing accessibility is mandatory you
152.959 -> have tools that can identify
154.239 -> accessibility issues but no tool can
157.04 -> certify that an app is fully accessible
160.4 -> manual testing ensures that you test for
162.64 -> a breadth of ally concepts that include
165.2 -> logical content order and feature parity
169.68 -> to manually test applications for
172 -> accessibility in this course we'll be
173.76 -> turning on this computer's built-in
175.68 -> screen reader and navigating through the
177.599 -> app with keyboard navigation
179.84 -> for more information you can see
181.519 -> semantics
182.879 -> and screen readers uh or if you go in
185.28 -> the code lab there's some good
188.159 -> resources on how to look for all of this
191.28 -> stuff here
192.48 -> so i'll go ahead and turn on my voice
195.28 -> over
197.2 -> accessibility shortcuts
202.239 -> you can see
206.239 -> that i can navigate through
215.28 -> um so
217.04 -> for the course i will be exiting that
219.519 -> just because i don't want to fight with
221.2 -> a voice over but as you can see that's
222.64 -> what you'll be doing
224.48 -> uh you can also use the mac built-in
227.84 -> voiceover which is what i was just doing
229.76 -> by clicking enable voiceover in the
231.84 -> accessibility settings of your system
234.08 -> preferences or what i'll do is press
237.28 -> touch id three times and that's the
239.28 -> short key for turning the service on and
241.84 -> off
243.2 -> we're also going to be using lighthouse
245.439 -> to run accessibility tests so if i enter
248.879 -> lighthouse within my console
251.12 -> and i choose just accessibility for
253.92 -> desktop i can generate a report and i
256.799 -> can see my starting place of everything
259.12 -> that i need to fix
261.359 -> let's see i might need to stop and
263.6 -> restart it because
266.16 -> of how many things i'm sharing
270.72 -> and while that's going let's go ahead
273.04 -> and look over at our last thing which is
274.96 -> if i go into my code you can also use
277.84 -> angular's eslimp rules to link your code
280.479 -> for common accessibility issues and
282.88 -> automatable attributes that we can check
284.88 -> for
285.68 -> so if i go to all of my code and i enter
289.12 -> into my eslint rc json this is going to
293.28 -> be all of the eslint
295.36 -> tests
296.4 -> that i am checking for and in my rules
299.199 -> you can see that the code already comes
301.759 -> with these i believe 10
305.28 -> uh
306.16 -> i don't know i'm not going to count but
307.6 -> 10
308.479 -> accessibility issues uh or rules and i'm
312.32 -> choosing to say two so this value can be
315.52 -> zero one
316.96 -> two
317.84 -> uh with zero being nothing one being a
320.72 -> warning and two being an error and
322.4 -> that's choosing how when i run my lint
324.479 -> rules
325.68 -> these issues are tested for
328.4 -> so you can go to the eslint repository
330.24 -> to see more of these but these are the
331.759 -> 10 that we recommend and you can find
333.6 -> these all again
335.44 -> in the code lab to add so that's a great
338.4 -> really quick lift if you just want to
340.24 -> automate a little bit of accessibility
342.88 -> and if i go back to my terminal
345.199 -> i can actually
347.6 -> uh do
350.479 -> npm run and
354.88 -> oops
359.84 -> and while i'm waiting for my linting i
362.72 -> can see
363.759 -> oops
364.72 -> that i'm using
367.199 -> too new of a version but it'll still run
370.88 -> and we can see that we have one error
373.039 -> being caught by one of those rules so
375.12 -> the rule for click events uh
377.6 -> have key events can see that there's
379.84 -> something in my app that's not working
381.36 -> correctly because there's not a key up
383.36 -> or key event associated with
385.759 -> something in one of my templates so
387.52 -> we'll fix that in a little bit
389.44 -> and if i go back to my application
392.639 -> i can see that i get an 87 for my
394.96 -> lighthouse accessibility score which
396.96 -> isn't bad uh but we definitely want to
398.88 -> get up to the green area of above 90 and
401.84 -> we can do better and get almost to a
403.36 -> hundred
404.4 -> um so we see we have a bunch of
407.12 -> different itemized things here and those
408.639 -> are going to be some things we fix
410.96 -> so now that we have a starting place i
412.88 -> want to get started by fixing our first
415.44 -> issue
417.199 -> of the eight identified issues that i've
419.28 -> picked out again by manual testing with
421.599 -> voiceover by running this lint check
424.96 -> here
426 -> and by doing this lighthouse
427.52 -> accessibility test to see what's going
430.24 -> on there
432.16 -> the first issue that we're going to fix
434.16 -> is defining a unique page title
436.88 -> providing unique concise page titles
439.199 -> helps users using ally services quickly
442.24 -> understand a page title's content and
444.96 -> purpose
446 -> page titles are critical to users with
448.16 -> visual difficulties because they are the
450.24 -> first page element announced by screen
452.319 -> reader software
453.84 -> angular is a single page application
456.08 -> framework and as a result a majority of
458.96 -> the transitions such as moving to a new
461.28 -> page do not involve a page reload until
464.639 -> recently this meant that each page had
466.8 -> an identical page title and provided no
469.599 -> value for understanding the page's
471.44 -> context or purpose so if you can see
474 -> that here let's identify that issue
476.8 -> and then talk about how we're going to
477.919 -> fix it
479.039 -> so as you can see right now up at the
481.28 -> top uh we're looking really small here
483.12 -> but it says ally in angular and if i
485.759 -> open up a new tab of this
488.8 -> and go to maybe a different page let's
490.4 -> go to our story uh you can see that this
493.44 -> is like the about page of our website
495.039 -> and it's still at the top just says ally
497.44 -> in the angular
498.72 -> and if i open one more just to really
500.72 -> prove my point let's say i go to the
502.8 -> last page so find us so this is like a
505.199 -> map um if i had location services that
508.4 -> said like where i'm located um
511.36 -> in san francisco and we can see that all
513.599 -> of these have the exact same page title
515.599 -> so there's not a lot of information
517.68 -> so if you can think about this in like
519.599 -> let's say a google search website let's
522.24 -> say you had like 30 tabs of google
524.56 -> search open
525.76 -> and all of them just said google search
527.68 -> at the top but you had 30 different
529.839 -> searches and you were trying to find
531.279 -> that one tab it's really hard because
533.279 -> you have to click into each one so both
535.76 -> from like a ux standpoint it's just a
538.24 -> terrible experience to have to go into
539.92 -> each tab to figure out what's there
542.16 -> but also from an accessibility
543.76 -> standpoint that's the first thing your
545.92 -> page uh or your screen reader is going
548.399 -> to read to your users so you want to
550.959 -> convey what's on the page in that page
553.36 -> title
554.88 -> so in angular v14 the router added a
557.92 -> built-in method to define unique page
560.399 -> titles out of the box this provides a
562.88 -> streamlined approach to ensure
564.64 -> developers follow page title best
566.48 -> practices
568.64 -> to fix this we're going to use that
570.72 -> built-in tool so if we go to define page
573.519 -> titles
575.36 -> we're going to go into our app routing
577.6 -> module and we're going to add this title
580.24 -> property so this is the new thing that
582.16 -> was added in version 14 when you update
584.72 -> so i'm going to take this and i'm going
586.32 -> to go into app routing
588.399 -> and go into my code the other way you
590.399 -> can check any of this is since we're on
592.32 -> step four of the code lab you can search
594.24 -> to do step four
595.92 -> and quickly jump to where you wanna go
598.32 -> and what we're gonna do is again add
599.92 -> that title property
602.08 -> so like
603.44 -> here is a title
606 -> and then if i save
609.44 -> i should be able to go back
611.92 -> let's go to this running
614.079 -> it recompiled and see here we go here's
616.88 -> the title so that title was
618.24 -> automatically applied so this is super
620.64 -> easy if you're familiar with former
622.16 -> versions of angular it's much more
623.6 -> difficult and just for the sake of time
625.839 -> i'm going to copy and paste this code
628.16 -> to define my new routes
631.519 -> and replace it here and then this can be
634.56 -> deleted we no longer
636.24 -> need that to do
637.92 -> um
638.88 -> and if we look at the best practice here
640.64 -> what i like to do is convey like
643.6 -> what that page is so this is the shop
645.68 -> page where you could buy things so our
647.68 -> shop dash and then the overall website
650.64 -> you can see common patterns of this if
652.32 -> you go to other websites again like
653.68 -> google search will say like what the
655.2 -> search term is and then google search um
657.76 -> so conveying the most important or most
659.76 -> specific thing about the page and then
661.519 -> the more general context
663.76 -> so specific
665.2 -> than general
666.56 -> is just like a best practice that i like
668.32 -> to follow but if we save that and go
670.56 -> back
671.839 -> then if i open up those tabs i just had
674.88 -> you can see that now i have our story
677.6 -> angular find us
679.68 -> ally angular and our shop ally in
682.64 -> angular and so we are seeing the
684.48 -> difference without even needing to go so
686.56 -> if i'm here and i want to go to that
687.92 -> like find page i don't need to go into
689.839 -> each one
691.44 -> that's super cool um
693.68 -> and again i'm just really excited
695.12 -> because again previously you would have
697.04 -> had to add and manually manage these
699.2 -> page titles and apply that in your app
701.36 -> component so this is a super easy way
703.68 -> where i'm adding like
705.68 -> i mean literally no lines of code were
707.44 -> added just like a few characters on a
709.76 -> few lines so
711.2 -> super cool super quick super easy
714.399 -> now that we've done that we've verified
716.16 -> our change and we're one step closer so
718.88 -> let's keep going
720.64 -> your design might seem cool but it's not
723.04 -> cool if people with visual impairments
725.36 -> like colorblindness can't read your
727.04 -> content
728.72 -> the web content accessibility guidelines
731.12 -> or what cag 2.0 define a series of color
734 -> contrast ratios that ensure that your
736.24 -> content is accessible
738.399 -> in angular and on the web you can define
740.959 -> color palettes that ensure your
742.56 -> components meet these standards and are
744.56 -> visible for users with low vision and
746.959 -> color blindness
748.88 -> so for this we're going to identify the
751.2 -> issue by inspecting the page with the
753.44 -> little chrome devtools inspector
755.6 -> and the thing that's really standing out
756.959 -> to me on this page is this matte icon
760.48 -> and if i click on it and hover it i can
762.48 -> see
763.68 -> that that accessibility contrast is not
766.16 -> good so again if i hover you can see
768.399 -> that that contrast value in
770.079 -> accessibility is quite low so
773.68 -> significantly below the wacag guidelines
776.399 -> if i go down to that value in
780.399 -> the actual chrome dev tools by going up
783.44 -> i can hover it
785.92 -> and i can see that that contrast ratio
788.8 -> is quite low and i can actually try and
790.959 -> fix it to either 3.0
793.279 -> or 4.5 and see that it needs to be much
796.88 -> darker for the recommended value so
799.36 -> super cool that chrome has that built in
802 -> but now let's go change that in the code
804.48 -> so
805.76 -> to do this
807.519 -> um we are going to go back into our code
810.88 -> and look at the palettes we've defined
813.04 -> and we can see
815.279 -> that i have this value
817.36 -> i'm using this pink palette right i'm
819.12 -> like really enjoying this pink red quite
821.36 -> bright vibe
822.72 -> but this text value is 500 um which if
825.839 -> you're familiar with angular
827.92 -> you know that the material color
830 -> palettes that we're defining are using
832.16 -> values from 100 to 900 with 100 b being
836.24 -> the lightest and 900 being the darkest
841.44 -> and so for the 100 to 500 uh contrast is
845.92 -> quite low right we're only like two
847.6 -> color steps off of one another so i'm
850.079 -> going to go ahead and change that to 900
852.8 -> and go the furthest away that i can
855.519 -> and go back and see how that changes it
858.48 -> and if i reload
861.76 -> we can see that anywhere that that
863.44 -> really light color was is swapped to a
866 -> really dark color um and i can also
869.12 -> hover it and see that again
871.76 -> that color contrast is now uh above four
875.76 -> which is meeting the guidelines that i
878 -> need so i've met that color contrast
880.639 -> ratio i can also go this is something
882.8 -> that again that lighthouse audit is
884.48 -> going to do a really good job of
885.68 -> checking
886.639 -> so this is the contrast here because
888.56 -> again this is super automated right we
890.399 -> can test and see if colors
892.399 -> meet it and here it was pointing out
894.24 -> that those icons were not doing very
896.32 -> well so now if i rerun my audit
900.48 -> i can see
902.639 -> my percentage should go up yeah so we
905.44 -> got two more points there and that
907.6 -> contrast is no longer there so we
909.279 -> verified both manually by hovering
911.839 -> and by running the audit again that i
913.76 -> fixed the automated thing and my palette
916.079 -> is now fixed and the benefit of doing it
918.48 -> in a palette
920.079 -> is that anywhere that you're gonna use
922 -> icons or things that are using material
925.519 -> in this application that are using that
927.92 -> text color
929.279 -> are now going to use that accessible
932.32 -> color with the highest contrast
935.12 -> so super great to do it in a more
937.199 -> generic place like your styles versus
939.44 -> individually overriding like that that
941.92 -> color is darker the broader you go the
944.32 -> more accessible it's gonna be we've
946.24 -> fixed two things we've gotten our score
947.92 -> up two points let's keep going
951.279 -> and our next one is going to be another
953.44 -> thing in our templates which is using
955.6 -> semantic html
958.079 -> we're now on step six
962.639 -> and let's talk about native html so if
965.519 -> we go to our application we're actually
967.36 -> going to be on our r story page here and
970.16 -> native html elements capture a number of
972.959 -> standard interaction patterns that are
974.88 -> important accessibility
976.88 -> while a paragraph can be styled as a
979.04 -> span or a div can be styled as a button
983.44 -> semantic html elements ensure that
985.839 -> screen readers and keyboard navigation
987.92 -> understand the interactions and control
990.24 -> your html
992.32 -> when you're authoring angular components
994.48 -> you should always try to reuse these
996.48 -> native elements directly when possible
999.199 -> rather than re-implementing
1000.8 -> well-supported behaviors
1003.04 -> this ensures that the page has good
1005.12 -> content structure and natural content
1007.44 -> flow and that the tab is in a logical
1009.839 -> order
1011.199 -> to assist users navigating the web with
1013.759 -> effective use of the keyboard so here we
1016.639 -> have two things that we're going to fix
1018.8 -> and the first we can actually see again
1021.12 -> in that lighthouse score if i go back
1023.839 -> but we can see that it's getting mad
1026.319 -> that the heading elements are not
1028.48 -> sequential um and if i actually go to
1031.039 -> this other tab and run another
1032.559 -> lighthouse
1034.079 -> uh test on this it's gonna get even more
1036.88 -> mad at me
1038.4 -> um
1039.919 -> because it's gonna notice that each of
1041.919 -> these html elements uh are headers in
1044.799 -> the wrong order so these heading
1046.24 -> elements don't make sense or not and are
1048.48 -> not sequential otherwise this page is
1050.64 -> looking pretty good
1052.48 -> um
1053.6 -> so to fix this we're gonna go back into
1055.76 -> our code and we're gonna go to we did
1058.559 -> that
1059.52 -> we're gonna go to to do six
1061.76 -> and we're gonna notice that in the about
1063.919 -> component
1066 -> i can even look at this and say okay i
1067.919 -> start with an h3 a header three i go to
1070.559 -> a header two which is supposed to be
1074.32 -> higher than an h3 right this should go
1076.799 -> one two three four five six
1078.88 -> um then i go to a five and a six but
1081.12 -> then i go back to a five
1083.039 -> then i go to five then i go right so
1084.64 -> this this number order doesn't make
1086.08 -> sense if i'm trying to go sequential i'm
1088.32 -> not doing a very good job at that
1090.559 -> so we're gonna go and i provided the
1092.96 -> code snippet in the code lab
1095.679 -> but we're going to take this
1098.4 -> and we're just going to reorder these
1100.16 -> things so that they have headers
1105.2 -> and it's going to be the same text but
1106.96 -> instead of using headers to decide the
1109.12 -> styling i'm going to use headers as what
1111.44 -> they are which is
1113.36 -> semantic html elements that are voice
1116.08 -> over would understand as the header of a
1118.559 -> section and then anything within that
1120.72 -> section i'm going to mark as a paragraph
1122.72 -> because it's essentially just like a
1124.24 -> line of text it's not a header it's not
1127.2 -> like the section information
1129.52 -> and then i'm going to use styling uh and
1131.919 -> specifically angular materials built-in
1134.48 -> styling classes to apply some stylings
1138.16 -> to make sure that i get this same style
1141.36 -> that i really like without having
1143.84 -> to use semantic html to sort of hack it
1147.52 -> so
1148.4 -> if i save this
1151.919 -> and i save this
1154.64 -> um
1157.36 -> and
1158.24 -> i go back
1160.64 -> we should see that yeah so that reloaded
1163.44 -> and we now have what is clearly two
1165.679 -> headers
1167.36 -> with some text in the middle that still
1169.6 -> has fun styling but isn't all a header
1171.84 -> right in general text and all the
1173.52 -> headers and if i rerun that lighthouse
1177.52 -> i should see
1179.12 -> a fix there
1180.559 -> which is exactly what we're trying to do
1184.72 -> and yeah so this page is now at 100
1186.96 -> which is a little premature but quite
1188.96 -> exciting um because again we fixed that
1191.36 -> semantic html thing
1194.08 -> now if we go back here we're going to
1195.84 -> fix the other semantic html thing which
1198.48 -> if we inspect
1200.08 -> we're going to see that this purchase
1202.24 -> button right it clearly like in theory
1205.039 -> the idea of this website is like here's
1206.96 -> my dumpling preview
1208.72 -> um this is like a super cool nuanced
1211.039 -> dumpling shop where like you can order
1213.039 -> hot pink dumplings
1214.799 -> um of different quantities
1217.6 -> uh of different filling types so let's
1219.84 -> say we're going like
1221.36 -> chicken and tofu
1224.24 -> um and i want to click purchase this
1226.88 -> purchase bun should be how you purchase
1229.12 -> those dumplings right
1231.039 -> um but i can notice that it's actually
1233.28 -> just a div that's styled to sort of look
1235.76 -> like a button and even in the html it's
1238.48 -> called button it just is a div which is
1241.52 -> really not what we want here because
1243.6 -> again
1244.559 -> we want to use this
1245.84 -> semantic html for this we want to use
1248 -> the native button attribute because when
1250.159 -> we turn on something like voiceover and
1252.24 -> we navigate we can get to that control
1254.48 -> and voiceover will know what to do with
1257.2 -> that known interaction
1259.44 -> so to do this we're going to go to to do
1261.6 -> number six
1263.52 -> the other one and we're going to see
1266 -> here and see that even within our um
1269.44 -> code editor we know that there's an
1271.52 -> issue here right so this is what was
1273.76 -> being thrown by that lint error earlier
1276.4 -> um is it knew that this div has this
1278.72 -> click attribute that like it really
1280.559 -> shouldn't and so we're getting an in
1282.08 -> browser error because i made it that
1284.72 -> nglint error
1286.4 -> so if we copy and paste the code that i
1288.48 -> provided we're changing this to a button
1291.28 -> with angular material flat styling
1294.88 -> just coloring it a little bit and then
1296.88 -> putting the exact same class on it
1298.72 -> putting the same click event on it and
1300.88 -> just giving it the exact same text so
1302.88 -> again the before and after is very
1304.48 -> similar we're just making this a button
1307.36 -> and by doing that we get rid of the in
1309.6 -> code editor error
1311.84 -> um
1313.44 -> and if we go back to linting we can run
1316.159 -> that lint
1317.679 -> test again and see that that should also
1320.48 -> be fixed
1321.84 -> and while that's going we can also go
1324 -> back to our shop
1325.52 -> and we can see that there's now like
1327.919 -> even the ux of this is great right so if
1329.84 -> i zoom in so you can really see
1332.64 -> um if i like click there's like a click
1335.44 -> interaction right it's visible the ux is
1338 -> great right so we think about
1339.679 -> accessibility as just fixing things for
1342.799 -> people using accessibility services
1345.44 -> but a lot of what we've already fixed
1346.88 -> today right like this color contrast
1348.799 -> just makes it easier for everyone
1351.2 -> um or this like clicker interaction like
1352.96 -> the fact that it now has hover and you
1355.039 -> can see that the like cursor changes and
1357.2 -> there's like known interactions there in
1360.24 -> animation
1361.44 -> is like a really great benefit where
1363.28 -> fixing things for accessibility is not
1366.24 -> just for people who we typically think
1368.72 -> of as needing accessibility services
1371.12 -> it's really a better user experience for
1373.12 -> everyone
1374.64 -> so if i rerun that accessibility report
1376.799 -> on this
1378.559 -> and i go back and look i can see that
1380.48 -> all of my lending has passed so we're
1383.36 -> already much closer and we're up to the
1385.84 -> green space here so we're up to a 91
1387.84 -> because again we fixed this button issue
1390.799 -> and we fixed this page all with just
1394.159 -> using semantic built-in html so
1397.28 -> a lot of great things happening already
1399.2 -> and we're only about halfway the next
1402.4 -> thing we're going to do is use
1404 -> selectable controls with angular
1406.4 -> material
1407.6 -> so here you can see that one of the
1409.2 -> complicated interaction patterns for
1411.2 -> accessibility services is nested
1413.36 -> controls in this demo we're using um
1416.96 -> all of these check boxes right and we
1418.48 -> have nested controls where you can get
1420.64 -> like chicken but not impossible meat and
1422.48 -> you can get tofu but not bok choy right
1424.559 -> these are nested controls where there's
1426.4 -> vegan there's meat but there's also
1428.32 -> nested options
1430.4 -> but how do you indicate to a user that
1432.48 -> you selected a subgroup or navigated to
1435.28 -> the parent item so let's think like when
1437.679 -> you're going through this interaction
1439.6 -> with uh
1440.96 -> voiceover how do you indicate that bok
1443.36 -> choy is a sub child of vegan or that
1446.4 -> meat is a parent of chicken and
1448.24 -> impossible meat that's a really hard
1450 -> pattern to try and work with
1452.32 -> in angular simplified menus and controls
1455.679 -> uh create a much more navigatable
1457.919 -> experience and so what we want to do is
1460.32 -> simplify those controls as much as
1462 -> possible and use the angular material
1464.48 -> list box to build out this interaction
1467.44 -> pattern
1469.2 -> so i'm not going to turn on voiceover
1471.279 -> just because uh
1473.52 -> running a screen share while also doing
1476.159 -> voiceover on this step is like quite
1477.6 -> difficult but as you can see it's that
1479.679 -> same interaction pattern that we had
1481.279 -> right where like you really can't convey
1483.84 -> these nested controls very well and it's
1485.679 -> just a really poor experience for
1487.12 -> everyone involved
1489.279 -> to fix this
1490.64 -> let's simplify this a little bit so
1492.4 -> we're going to go to step 7
1495.84 -> scroll up
1497.36 -> and we're going to be replacing the
1499.76 -> check boxes with material checkboxes so
1502.08 -> first if we go to our code i'm going to
1504.72 -> swap here
1506.799 -> um
1507.84 -> and we go to to do item 7
1511.12 -> we can see
1512.4 -> that to create selectable controls we
1515.279 -> have a ton of stuff here
1518 -> of all of our selectable controls in our
1520.08 -> shop component and what we want to do
1523.279 -> is just simplify this so we're going to
1525.2 -> define our uh
1527.44 -> options a little bit differently
1530.24 -> um
1530.86 -> [Music]
1532.08 -> here so our filling
1534.08 -> option instead of being a set of
1535.6 -> booleans is going to be
1537.76 -> um a
1539.039 -> list of strings
1540.64 -> um and i made them a little bit fancier
1543.36 -> so now we have a list of fillings we
1545.919 -> have our selected fillings which is
1547.919 -> again a nice little array list
1551.2 -> and then we're just going to in our faux
1554.4 -> purchase
1556.559 -> correct that
1558 -> the way we make a faux purchase is a
1559.919 -> little different because of that array
1561.279 -> list of strings
1564.83 -> [Music]
1568.84 -> fix
1570.48 -> just strings
1574.64 -> oops
1576.24 -> there you go
1580.96 -> cool
1585.36 -> sorry my strict taping that's really
1587.6 -> getting the best of me here so now we
1590.08 -> have um just an array here of our
1592.64 -> fillings that we're excited about i like
1594.799 -> made them a little bit fancier because
1596.32 -> why not
1597.6 -> again an arraylist of our selected ones
1599.84 -> and then if we go down here into our
1601.36 -> selected fillings when we make a
1602.799 -> purchase we're just going to go through
1605.36 -> create a list of each of the selected
1607.44 -> fillings that we have
1609.039 -> um and then just print that and that's
1611.2 -> going to be the flavor of dumplings that
1612.88 -> we're buying
1614.32 -> so now that we've fixed that part
1616.64 -> we're going to go into the actual
1618.48 -> controls and just replace this like
1620.48 -> really complicated whole ul list
1623.279 -> uh or unordered list
1625.84 -> with
1627.679 -> this provided here which is
1630 -> significantly shorter and what it is is
1632.159 -> again a matte selection list
1635.679 -> of
1636.799 -> list options where each of the fillings
1639.36 -> that i just provided is going to be one
1641.44 -> of the options that i give
1643.36 -> so i'm using the ng model um to make
1647.12 -> sure that i know that all of the
1648.4 -> selected fillings are going to be my
1649.84 -> selected controls and just again give
1652.4 -> that selection list um and here notice
1655.44 -> that i'm giving an aria label so i'm
1657.36 -> providing context for what that list is
1660.48 -> for aria or screen readers um so that
1663.52 -> when it's read as a list it's read as
1665.52 -> the dumpling filling list
1667.6 -> so just something to indicate there and
1669.44 -> then just each of my flavors is going to
1671.279 -> be
1672.24 -> one of those so
1674 -> quite easy and then i believe we can
1676.08 -> also just get rid of some styling um
1678.159 -> just to make sure we clean up some
1679.919 -> things so within that shop component
1681.76 -> that last to do is just a quick little
1683.44 -> cleanup
1684.72 -> and if i save all of that and i go back
1687.919 -> we can see that yep
1690.24 -> without doing very much we already have
1693.52 -> a bok choy and chili crunch a tofu and
1695.52 -> mushroom a chicken ginger and impossible
1697.36 -> meat and they're all within fillings and
1699.36 -> you can see that the styling changed
1701.12 -> quite a bit
1702.24 -> so i now have those click interactions
1704.32 -> it's not that unordered list but i've
1706.399 -> also removed the nested controls so if i
1708.72 -> went in with voiceover i would very
1710.559 -> clearly hear that this is a list of my
1712.88 -> fillings i would get to pick each one
1715.039 -> and i wouldn't get confused about
1716.96 -> whether or not i was ordering like the
1718.399 -> parent of what flavor or whatever
1721.279 -> and you can see that i believe if i run
1723.279 -> lighthouse again i would also get a
1725.44 -> slight bump just because um
1728.32 -> i'm not using sort of like a
1730.88 -> less supported pattern there so
1733.279 -> quite exciting
1734.799 -> if we move on the next thing is going to
1736.88 -> be very closely related which is step 8
1740.48 -> is talking about arya
1742.48 -> in that template
1744.32 -> that i was just in
1746.32 -> i showed that i was using this aria
1748.32 -> label right and so you see this a lot
1750.399 -> where aria labels are going to provide
1753.6 -> context
1754.799 -> for what
1756.24 -> uh that control or what that html
1758.88 -> element is doing and how to be read to a
1761.6 -> screen reader so that it's not just a
1763.279 -> button it's
1764.96 -> a purchase button or it's not just a
1768.24 -> list of controls it's the dumpling
1770.88 -> filling list so it's providing that
1772.559 -> context for the screen reader or
1774.399 -> accessibility service
1776.399 -> so the next thing we're going to do is
1778.08 -> we're going to add a label to something
1780.799 -> that's missing a label so this was
1782.72 -> caught
1783.679 -> if we go in
1785.36 -> we can see that
1786.88 -> here the first issue we have is form
1789.2 -> element does not have associated label
1791.6 -> so again you can think of arya as a lot
1793.44 -> of those labeling technologies and if we
1795.919 -> look we see that the input
1798.24 -> didn't have a label here so that was
1800.24 -> that filling
1801.52 -> um and we already added that right
1804.48 -> um so that one was fixed
1806.799 -> if we re-ran it and the next one is our
1809.12 -> input field does not have a label so
1810.72 -> this slider
1812.32 -> that's deciding how many dumplings i
1814 -> want i always want more than weaker
1815.919 -> stuffing
1817.039 -> um doesn't have a label as well so if i
1819.36 -> go into to do eight
1821.679 -> i'm looking to see what aria label is
1824.32 -> missing and what i'm noticing is this
1826.24 -> matte slider is an accessibility it's a
1828.72 -> material component slider
1831.12 -> so it already has a lot of built-in
1832.48 -> accessibility just because it's the
1834.159 -> material component version it's a known
1836.08 -> interaction of a slider
1837.919 -> but i'm not seeing any aria label so i'm
1840.32 -> not providing context
1842.32 -> so here i'm going to go back to my code
1844.96 -> lab just make sure i get the code right
1848.159 -> and all i have to do is add this aria
1850.159 -> label value
1852.159 -> so all i'm doing is adding just that
1854.559 -> aria label and that's solving it so then
1857.12 -> if i went in with a screen reader or i
1859.039 -> ran that lighthouse command again i
1861.039 -> would see that instead of just being an
1862.72 -> unknown slider it would be red as
1864.72 -> dumpling order quantity slider
1867.44 -> so again you can think of this as
1868.96 -> providing context to what that
1871.44 -> interaction is and i actually would
1873.36 -> probably uh go back and remove the word
1876.64 -> slider since the
1878.399 -> uh roll would be read in a different
1880.559 -> place so this is the context not the
1883.76 -> interaction and then the slider would
1885.52 -> actually oops
1886.88 -> read that
1888.08 -> and a cool thing is if you hover
1890.159 -> as you saw there
1891.679 -> i could actually open the aria reference
1894.32 -> which is what i accidentally just did
1897.44 -> uh if you want more information on that
1899.36 -> so i'm gonna go ahead and i'm gonna run
1901.039 -> one more uh accessibility report just to
1903.679 -> see that and i fixed two things with
1905.44 -> arya now so i should see that fixed and
1908.32 -> again this is like pretty intuitive yep
1910.48 -> we're at a hundred percent
1912.72 -> uh more than halfway through already at
1914.24 -> 100 we're still gonna do a little bit
1916.48 -> more which is why i said that manual
1918.799 -> testing is super important
1921.2 -> um
1922.24 -> but from the chance of automatable fixes
1926.399 -> we have fixed everything that was
1928 -> automatically checked so that's a super
1930.72 -> cool goal i'm gonna go ahead and
1933.039 -> give myself a little bit of a pat on the
1934.72 -> back hopefully you can too and i'm gonna
1936.96 -> exit out of lighthouse just so that uh
1939.279 -> we're not too distracted by that
1941.919 -> uh but if you think about that it makes
1943.519 -> a lot of sense right like let's say
1945.36 -> you're on a screen reader and you get to
1946.799 -> the point of just selecting the quantity
1950.08 -> um and you get to like
1952.559 -> you know you change it up to like 13
1954.559 -> there's no context for like what the 13
1956.88 -> is of so we want to make sure that
1958.72 -> anytime you're making a slider selection
1961.44 -> there um you're being told that it's you
1964 -> know 13 dumplings that you're about to
1966.159 -> order that the order quantity of
1967.919 -> dumplings is 13. that way you don't get
1970.399 -> to the end and click purchase and say
1972.24 -> like well i don't know i like got 13
1974.24 -> maybe that's like 13 fillings
1977.44 -> or 13 boxes uh versus 13 dumplings right
1981.919 -> i think i would be incredibly sad if i
1984 -> made this one because i thought that it
1985.519 -> was like one box of dumplings
1988.08 -> um
1989.039 -> and then a single dumpling arrived at my
1991.279 -> house that would be very sad
1993.6 -> we've gotten to the point of doing
1995.279 -> everything that we can without really
1997.84 -> digging into some of the nuances of
2000 -> angular
2001.6 -> and
2002.399 -> uh we've done a lot to be clear we've
2004.64 -> done page titles uniquely um
2008.32 -> just by using that built-in router
2009.919 -> property we've changed the color palette
2012.48 -> to have color contrast and we've really
2014.559 -> looked at the semantic html and controls
2017.84 -> as well as changing that pattern of this
2020.399 -> uh checkbox to be a little bit more
2022.559 -> intuitive
2024.24 -> and digging into the aria attributes of
2027.12 -> our templates to make sure that they're
2028.799 -> the most accessible possible
2031.44 -> so now we're going to move on to part
2033.679 -> nine which is where we add the power of
2036.399 -> the angular cbk accessibility package to
2040.48 -> fix common additional accessibility
2042.64 -> issues
2043.84 -> the thing about this is the cdk's
2046.64 -> accessibility module helps solve more
2049.839 -> complicated angular specific issues and
2052.8 -> by the end of this section we're going
2054.079 -> to add the module so that we can
2055.52 -> continue and do more of this
2058 -> you can read more about what the cdk
2060.399 -> ally uh package does on our docs website
2064.96 -> but you can really think of it as
2066.399 -> providing a set of tools just like
2068.879 -> anything in the cdk or component
2071.04 -> development kit
2072.399 -> um it's going to provide you a bunch of
2074 -> tools so that you can build components
2076.079 -> that are more accessible it's going to
2078 -> give you ways to hook into things like
2080 -> focus um live announcement contrast
2084 -> uh all kinds of more nuanced interaction
2086.56 -> patterns that are common on the web that
2088.24 -> we want to give you a direct way to hook
2090.159 -> into those apis and control
2092.639 -> so to do this
2094.159 -> we're going to go to
2095.919 -> uh to do step 9
2098 -> and it's going to be really easy
2101.44 -> uh all we're doing is adding this module
2103.92 -> so we want to import the accessibility
2106.16 -> module
2107.28 -> um just like anything in a module
2110 -> we're importing it
2111.76 -> and then it's getting mad because we
2113.359 -> didn't use it but that's okay because we
2117.2 -> can add it
2119.44 -> to the top
2120.88 -> and then
2122 -> it's imported and we can save it
2125.28 -> and
2126.16 -> close out some files
2128.079 -> and go
2130.079 -> let's see
2131.599 -> it should have recompiled
2133.839 -> we might want to restart
2136 -> when we import a new module i always
2138.72 -> like to just reserve my application just
2141.599 -> in case to make sure i'm getting that
2143.44 -> import
2145.119 -> but yeah super simple so we're getting
2147.04 -> that ally module again
2149.359 -> uh the shorthand for accessibility from
2151.68 -> the import in the cdk
2154.4 -> um and really that's about it uh and i'm
2157.44 -> realizing i put this
2159.44 -> a little low i actually want it to be up
2161.76 -> here with all of my packages
2164.56 -> um and cool
2166.32 -> so we did that super easy probably the
2168.72 -> easiest step so far because there's no
2170.4 -> visual change right we just imported a
2172.16 -> new module let's keep going and look at
2174.48 -> three ways to use this module
2176.88 -> the first thing we're going to look at
2178.48 -> is focus trap if we open i previewed
2181.92 -> this earlier but if i open my color here
2185.119 -> i can select a new color so let's say
2187.119 -> like right now my dumplings are gold uh
2190.4 -> let's say i want to make them light
2191.599 -> green so i could apply that color they
2193.76 -> change color and in theory they would
2195.839 -> arrive and be a different color
2198 -> um or let's say like i went into dark
2201.04 -> mode let's say i'm really digging this
2202.64 -> like plum color for spring it's like
2205.2 -> very um
2207.2 -> seasonal
2209.119 -> um and so i can apply that color so when
2212 -> i open this uh dialogue what i'm doing
2215.92 -> is
2216.64 -> i should be opening this dialog and
2218.72 -> redirecting the focus of like a screen
2220.88 -> reader to know that it's inside of a
2222.8 -> dialog so if i had voice over open i
2224.8 -> would want to contain the focus within
2227.28 -> this dialogue because while this is open
2229.839 -> i want you to make a selection here
2231.68 -> before exiting out right you can click
2233.92 -> out
2234.88 -> but you haven't made any change there so
2236.96 -> i want to make sure that you know if you
2238.72 -> select this color
2240.8 -> attribute that i'm sending you to a
2242.4 -> dialog and i'm letting you make a change
2244.48 -> here before applying the color and going
2246.88 -> back right and i want to
2248.96 -> make sure that the user knows that
2250.48 -> they've entered a dialogue what they're
2252.48 -> doing in that dialogue and then when
2254.56 -> they exit i want to make sure they know
2256.56 -> what happened in that dialogue
2258.88 -> so a really common accessibility pitfall
2262.16 -> is that you'll open this dialog and
2264.079 -> somehow the screen reader will be able
2265.76 -> to continue to edit things outside the
2267.92 -> dialog while it's open
2269.599 -> right that i could like change the
2271.68 -> quantity of dumplings while within that
2273.839 -> dialogue
2275.28 -> um so i want to make sure i'm trapping
2277.28 -> focus and this is something that we call
2278.88 -> focus trap
2280.24 -> the angular cdk trap focus directive
2283.52 -> traps tab key focus within an element
2286.4 -> and this is intended to be used to
2288.079 -> create accessible experiences for
2290.4 -> components like modal dialogues where
2293.2 -> focus needs to be constrained
2295.839 -> in order to do this we're going to go to
2298.72 -> you guessed it to do step 10
2302.079 -> and we're going to uh actually go in and
2304.88 -> add just this cdk focus initial and all
2308 -> that's doing is letting the user know
2310.64 -> where to put the focus
2312.48 -> so cdk focus trap um if we opened the
2315.68 -> documentation
2317.76 -> um
2319.76 -> is going to have a lot of stuff there
2321.68 -> angular
2324 -> thank you
2325.359 -> let's material
2331.52 -> oh that must be cut out
2334 -> and if i go into the components in the
2335.599 -> cdk i can see that within the
2337.359 -> accessibility package i'm looking at
2339.839 -> focus drop so this is things where i
2341.92 -> want to track focus and there's a bunch
2343.92 -> of options here so there's trapping
2345.599 -> focus there's changing the focus region
2348.32 -> and there's indicating initial focus so
2350.96 -> for the use of this code lab all i'm
2353.68 -> going to be doing is making sure that
2355.04 -> the initial focus is where i want it
2357.599 -> which means that it's on the selection
2359.44 -> list so if i go to to do step 10
2363.599 -> i'm going to see that
2365.839 -> initially
2367.2 -> if i were to use a screen reader
2370 -> um
2371.2 -> and i go to this dialog
2373.28 -> the initial focus would be on the entire
2377.28 -> uh or would be on apply color right it
2379.28 -> would be on like exiting the dialogue
2381.04 -> and so i want to actually move the focus
2382.8 -> to the entire window so that you go
2384.8 -> through each of the colors before doing
2386.48 -> that so that you know about that
2388.8 -> so here i'm going to make uh one change
2391.68 -> which is just adding the cdk focus
2393.68 -> initial which is saying this is where i
2395.839 -> want the initial focus to be
2398 -> on that list of colors
2400.16 -> um and it says easy that stop
2402.64 -> and then if i save it and i go back it's
2405.119 -> recompiled and again
2408 -> accessibility shortcuts you can hear
2410.8 -> that i turn my voiceover on
2413.68 -> um
2416.16 -> accessibility shortcuts and if i turn
2418.64 -> voiceover on
2421.839 -> and i move it over so you can see what
2423.68 -> is being said
2428.88 -> we're gonna go here
2430.48 -> and i enter you can see that initially
2432.56 -> that color
2433.68 -> selected one and eleven
2435.44 -> you are currently on element inside the
2437.359 -> response
2438.96 -> okay so you can see that when i selected
2440.8 -> that color and i opened the dialog i'm
2443.44 -> now focused on white the first color in
2446 -> that and if i scroll through
2448.64 -> i can select a color so i'm selecting
2451.44 -> color
2454.64 -> and then i can exit by going to apply
2456.64 -> color
2460.319 -> and i'm going to exit out of this so
2461.52 -> that i'm not fighting with voiceover but
2464 -> what you saw there to recap since i was
2466.16 -> fighting the voiceover is that i
2467.839 -> selected this color
2469.68 -> and now my focus was on white the first
2472.16 -> color there versus one of these controls
2474.16 -> to exit right so i was put directly into
2476.96 -> the colors and i was told what i was
2478.8 -> selecting the dumpling color
2480.96 -> and then i was able to apply the color
2482.72 -> and exit
2484 -> so
2484.8 -> that was done again using the cbk focus
2487.119 -> initial but there's also really great
2488.72 -> stuff that i would highly recommend if
2490.4 -> you're using dialogues on other things
2492.24 -> like chopping focus again i didn't need
2494.88 -> to chop focus within that dialogue
2496.96 -> because
2498.48 -> i am using the matte selection list
2500.48 -> which automatically knows
2502.8 -> when i open this matte dialog with a
2505.28 -> matte dialog action to control and trap
2508.24 -> focus i was just making sure that
2510.88 -> um
2513.28 -> the focus was where i wanted so
2515.68 -> we've done that we've verified and
2518 -> that's step 10 off the list so we
2520.56 -> verified it our color picker now has
2522.88 -> correct focus trapping and we're super
2525.359 -> close to the end
2527.04 -> our next thing is going to be super
2528.8 -> super simple uh similar to what we just
2531.599 -> did which is again looking at that color
2533.68 -> indication and this is announcing
2536.079 -> changes so when i go and make a change
2538.64 -> let's say i change the color right to
2540.64 -> green yellow this like weird neon
2544.079 -> when i exit i want to make sure the user
2546.24 -> knows what just happened so i want to
2547.92 -> announce to the screen
2549.599 -> hey you just changed the color so you
2551.359 -> know like there's been a change to the
2552.88 -> screen you exited that dialogue and
2554.96 -> something happened
2556.24 -> another common thing is if you make a
2558.88 -> purchase i want to announce that that
2560.64 -> purchase was made let's say this is like
2562.64 -> hooked up to some sort of payment
2565.04 -> platform and you've exited and you've
2567.04 -> made a payment i want to make sure that
2569.44 -> this payment or this purchase that i'm
2572.319 -> just console printing for now is
2574.48 -> announced to the user so that they know
2576.24 -> what they're purchasing or going into
2577.92 -> another window to purchase
2579.839 -> so to do this we're going to use
2581.76 -> something else from our accessibility
2584.079 -> cvk package which is called
2586.96 -> live announcer
2589.119 -> and so
2590.16 -> live announcer is going to allow you to
2592.72 -> notify when something on the screen has
2595.2 -> changed
2596.319 -> you can imagine if you're attempting to
2597.839 -> submit a form or complete a purchase and
2599.839 -> not knowing that an error has popped up
2601.76 -> right error handling is super
2603.2 -> frustrating let's say you go to submit
2605.52 -> your address because you're making a
2607.119 -> really big purchase and
2608.96 -> um the zip code is off or something and
2611.68 -> so you're just sent back to that form
2613.28 -> and visually there's an error on one of
2615.76 -> those form attributes but to somebody
2618.24 -> who is non-sighted you're not being
2620.4 -> notified of what the error is and you're
2622.24 -> having to go through the entire form
2624 -> again to figure it out i know it's
2626 -> really frustrating for me when like i
2627.76 -> don't know what the error is and i'm
2629.68 -> being sent back to a form so
2632 -> air controls are a great place to use
2634 -> live announcer which announces messages
2636.56 -> for screen readers to use using the aria
2640 -> live region to ensure screen readers are
2642.24 -> notified notified
2644.24 -> about those notifications and live
2646.8 -> page changes
2649.119 -> so to do this
2651.119 -> um
2652.64 -> we're going to add the live announcer
2655.52 -> uh so we're going to go to
2658.24 -> to do 11 and we're going to go into this
2661.04 -> component and add the live announcer
2663.119 -> attribute so if i go to to do 11 we did
2666.8 -> that
2669.359 -> um
2670.48 -> we're going to
2671.92 -> first go into the component
2674.72 -> let's see yes so first we go into the
2677.28 -> component we import the live announcer
2680.96 -> to do
2681.53 -> [Music]
2683.76 -> then
2684.72 -> we go into the actual class and we want
2687.44 -> to just add the live announcer to the
2692 -> constructor here and i'm just copying
2693.839 -> and pasting it so that you
2697.359 -> know what is happening but in this
2699.359 -> constructor here i'm just going to
2700.96 -> replace the constructor with this other
2703.52 -> constructor
2704.8 -> which includes
2707.28 -> that live announcer
2709.44 -> um added so
2712.64 -> uh let's see
2716.4 -> oh it looks like i'm missing
2722.72 -> something here oh change color oh
2725.52 -> um and here
2727.2 -> the last thing i'm gonna do is in my
2729.359 -> change color
2730.88 -> um i'm going to change how i change
2732.96 -> color so here in this change color
2735.68 -> method i'm providing a color and then
2738.16 -> i'm re-emitting the new color and what i
2740.56 -> want to add here is this live announcer
2742.96 -> attribute right so
2745.04 -> i want to change the color
2747.68 -> but i also want to announce
2750.24 -> um before changing
2752.24 -> that that color has changed so here in
2754.319 -> this to do i'm going to add this dot
2756.24 -> live announcer
2758.4 -> um and i'm going to announce uh sensible
2761.839 -> thing that the new color has been
2764.56 -> selected so before i close
2767.359 -> um and i'm going to do that anytime the
2769.04 -> dialog is closed just to notify
2771.44 -> and then the other thing i'm going to do
2773.04 -> is i'm going to go into this component
2776.48 -> and i'm going to do the same thing again
2777.92 -> for that purchase that i was
2780 -> making right so the other to do is to do
2783.04 -> the exact same thing
2786.16 -> and add that live announcer but in my
2788.24 -> other place which is to import it to my
2791.119 -> shop component um
2794.319 -> and do the exact same thing which is
2795.839 -> import
2796.8 -> uh live and answer from the cdk ally
2799.92 -> i'm gonna go into my constructor i'm
2801.68 -> gonna make sure i have a reference to
2803.839 -> that live announcer just a private live
2806.24 -> announcer instance
2807.92 -> and then i'm just gonna again use that
2810 -> super simple thing where on my purchase
2813.04 -> my faux purchase
2814.8 -> i'm going to say this live announcer so
2817.44 -> of my instance i want to make an
2819.2 -> announcement and i want to announce the
2820.8 -> exact same thing i'm console logging
2823.119 -> which is what that purchases so that in
2825.52 -> theory you would notify again this is
2828 -> sort of more of like a demo of what i
2829.599 -> would do with this um but error handling
2832.079 -> is a really great instance and so here
2834.48 -> i'm gonna go back make sure it
2836.24 -> recompiled it did
2838.4 -> i'm gonna turn on services and before i
2840.64 -> do so what you're listening for is when
2842.72 -> i click this button i want to hear
2845.28 -> uh or you'll be able to visually read
2847.44 -> that what is being read to the screen
2849.52 -> or what is being read with voiceover
2851.92 -> includes that announcement
2854.319 -> so if i turn on my services again
2857.319 -> accessibility shortcuts
2859.68 -> check
2862.24 -> and i show you what's being read
2864.96 -> application now in our
2866.72 -> purchase button group name
2868.88 -> your current button to click on press
2871.44 -> control this slide is hidden in
2872.72 -> slideshows purchase purchase 11
2874.48 -> ducklings in the color gold common
2875.92 -> result purchase 11 ducklings in the
2877.599 -> color gold
2879.359 -> change dumpling wrapper color light
2880.88 -> green selected unlock change dumpling
2882.72 -> average color button group main select
2884.72 -> color light green you are currently in
2887.04 -> rotten group two voice over off
2889.599 -> yeah and so there you saw with a little
2891.839 -> bit of hacking a voiceover given
2894.24 -> uh
2895.52 -> the screen record happening that when i
2897.599 -> clicked purchase i was announcing again
2900.319 -> that i had made a purchase of this gold
2902.16 -> color and then i went and changed the
2903.839 -> color to light green and you saw that it
2905.839 -> announced that a new color had been
2907.359 -> selected
2908.8 -> so again these are instances of using
2910.8 -> this instance of live announce to make
2912.559 -> sure that the user knew
2914.72 -> and now
2915.839 -> drum roll please we have one last thing
2918.88 -> which is maybe like the coolest but a
2922.079 -> little bit more niche thing and that's
2923.68 -> something that we're going to call high
2925.2 -> contrast mode
2926.88 -> so microsoft window supports an
2929.2 -> accessibility feature called high
2930.96 -> contrast mode and this mode changes the
2933.359 -> appearance of all applications including
2936.24 -> web apps to dramatically increase
2938.16 -> contrast
2939.52 -> in angular we want to respect the user's
2942 -> preferences for this app and so we want
2944.48 -> to use the high contrast mode detector
2946.8 -> which again is going to be another
2948.64 -> attribute
2949.839 -> within this accessibility package to
2952.88 -> make sure
2955.359 -> yes targeting high contrast mode
2957.76 -> um
2958.559 -> to make sure that we are respecting the
2960.72 -> user's preference there
2962.96 -> so internet explorer microsoft edge and
2965.52 -> firefox support this mode and google
2967.839 -> chrome currently does not support window
2970.24 -> high contrast mode
2971.839 -> but um
2973.76 -> there are changes being made to css all
2976.319 -> of the time to uh better respect again
2979.68 -> different forms of high contrast
2981.28 -> different color palettes
2983.04 -> prefers reduced motion there's a lot of
2985.04 -> css things we can do for accessibility
2987.599 -> and so this is one that we specifically
2989.359 -> want to look at for styling so here
2992.48 -> since i'm currently in chrome i'm going
2994.559 -> to just mock what this would look like
2997.599 -> so that you can understand a little bit
2999.44 -> of the difference and so we're
3000.72 -> specifically going to be looking at this
3002.24 -> purchase button here and if i go into to
3004.88 -> do a
3005.92 -> 12
3008.079 -> um i can see that in high contrast mode
3010.88 -> i would want to change
3012.64 -> uh the difference between these two
3015.599 -> colors to be essentially like white and
3017.52 -> black right it's it's almost white and
3019.2 -> black and how high the contrast is you
3021.599 -> can think of cag as using a 4.0 color
3024.72 -> contrast ratio that's what we changed
3027.119 -> initially where these colors are quite
3028.72 -> different think about if this background
3030.88 -> was white and this was black like the
3032.4 -> highest contrast you can get is what
3034.16 -> we're looking for
3035.92 -> so to support high contrast mode we're
3038.4 -> going to go into our style css and we're
3040.319 -> going to use the cdk high contrast
3042.8 -> mix-in that's provided with
3044.72 -> accessibility um so we're going to
3047.2 -> import this
3049.119 -> in again to do 12.
3052.4 -> our last one um and so we're going to
3055.28 -> import that
3058.4 -> and then we're going to go down a little
3060.24 -> bit and we're going to use this include
3063.04 -> um in purchase button so we're going to
3065.359 -> go to our purchase button
3067.04 -> we're gonna add the include and so this
3069.119 -> is include um like the sas thing
3073.04 -> uh and then in high contrast mode so
3075.599 -> when the
3077.28 -> uh service or when this application is
3079.28 -> being served or used in a high contrast
3081.92 -> mode setting um with that user setting
3084.16 -> turned on we're going to add a really
3086.559 -> thick outline and we could even like do
3088.319 -> more right like let's go big here
3091.2 -> uh and then we're just going to change
3092.559 -> the color to like the lightest possible
3094.64 -> version of again this pink palette that
3096.48 -> we're in
3097.52 -> um
3098.72 -> just to go as light as physically
3100.64 -> possible
3102.64 -> and so if you want to see what that
3104.079 -> would look like um since again we're not
3106.72 -> in high contrast mode i'm just going to
3108.319 -> go ahead and change it here so that you
3110.319 -> can see again what we're doing there
3112.8 -> and so here oops
3116.079 -> my computer is mad at me
3118.8 -> just got this back
3123.599 -> why
3125.68 -> hm
3131.28 -> let's try and use
3135.92 -> nope
3137.599 -> try use no tilde
3143.68 -> can't find style sheet to import
3146.88 -> let's try
3155.119 -> always fun
3156.88 -> um
3157.67 -> [Music]
3161.839 -> okay well as we debug this and
3163.44 -> regenerate what i'm trying to show here
3166 -> is that if we go to again these two
3167.839 -> things we're using this mix-in
3170.319 -> to ensure that when we're in this high
3172.96 -> contrast mode which is provided again by
3175.52 -> the accessibility service that we're
3177.52 -> adding the context of trying to make the
3179.839 -> purchase button as dark as possible
3182.24 -> again just to show that difference um
3187.28 -> it's really unhappy with that import
3190.4 -> there's something about strict importing
3192 -> that it's not uh
3195.359 -> working with my compilation okay
3198.72 -> let's ignore that for now
3200.96 -> um
3203.52 -> so if i go back can you compile
3206.72 -> these
3213.119 -> hi contrast
3216.24 -> okay
3218.319 -> so if i go to the instances of this if i
3220.8 -> just mock what's being happened here or
3222.88 -> what's happening here i want to show the
3225.04 -> difference and so if that import is
3227.359 -> correct which it will be in the code lab
3229.28 -> you'd see that if i was a user that had
3231.28 -> this setting on that i would then see
3233.92 -> this very
3235.28 -> uh differently styled purchase button
3237.68 -> that really emphasizes what's happening
3239.92 -> there it has a much higher contrast
3241.839 -> color
3242.88 -> um the outline is much significantly
3245.76 -> larger so it's really showing that
3247.2 -> control and it has the exact same
3248.96 -> behavior but again it's just emphasizing
3251.359 -> that styling so this is for maybe a more
3253.839 -> low vision user or somebody who has
3256.079 -> these controls on
3257.68 -> this is a really common setting for
3259.76 -> people who sometimes have chronic
3261.359 -> migraines
3262.72 -> who need to see really high contrast to
3264.96 -> not have to like focus really hard and
3266.88 -> discern the difference of like small
3268.48 -> nuances and so if i was styling my
3271.04 -> entire app with high contrast mode in
3273.119 -> mind i would go through in each of these
3274.96 -> controls i would make sure had the
3276.8 -> highest contrast
3278.559 -> had the largest outlines i would change
3280.64 -> the style even of maybe these dumplings
3282.96 -> that i'm um showing to have a much
3285.44 -> thicker line to make sure they have
3287.04 -> maybe like a white background um so
3289.52 -> really restyling your application again
3292.24 -> with this high contrast mix-in
3295.04 -> being included to make sure that you can
3297.52 -> do that and again um
3300.88 -> i have
3302.96 -> changed this import
3305.04 -> so you would just want to make sure this
3306.319 -> import is pointing to the correct
3308.4 -> thing it's possible it's
3310.4 -> syntax don't worry too much about this
3315.92 -> nope okay
3317.28 -> well we're gonna keep moving on but in
3320.16 -> theory oops hello
3325.04 -> okay
3325.839 -> let's make sure we compile
3327.68 -> so
3329.119 -> a little bit of an anticlimactic end but
3331.28 -> let's move this back to
3333.28 -> not a ridiculous
3335.119 -> high contrast uh
3337.52 -> to be
3338.64 -> uh other one
3341.44 -> and we can see that uh visually not a
3344.4 -> lot has changed from our application but
3346.24 -> we've done a lot to change the different
3348.16 -> controls
3349.52 -> we have almost wrapped up and i just
3351.599 -> want to do a quick recap of the eight
3353.599 -> steps we did so you can think about the
3355.68 -> changes you made and how they might
3357.52 -> apply to applications you are currently
3359.44 -> working on
3360.72 -> uh that aren't a dumpling shop because
3362.799 -> this is fun but you know there's a lot
3364.72 -> of other cool things out there that are
3366.72 -> using accessibility and it's important
3369.04 -> that all of them uh
3371.44 -> uh
3372.24 -> think about accessibility and make these
3374 -> changes so
3375.68 -> the first and probably the coolest is if
3378.64 -> you update your application to version
3380.24 -> 14 you can automatically change that
3382.96 -> page title and again
3385.839 -> this is like super cool super built in
3388.319 -> it's very new but if i look for that
3390.64 -> routes definition
3392.88 -> i can see that all i had to do was add
3394.799 -> that title and now i'm seeing these
3396.799 -> unique page titles up at the top so that
3399.2 -> was step one step two we changed this
3402 -> color here
3403.28 -> of this
3404.799 -> icon to make sure that it had the
3406.48 -> highest possible contrast ratio and met
3408.64 -> with cag guidelines
3410.559 -> in step three we changed the semantic
3413.119 -> html of our purchase button and our
3415.92 -> story to make sure that they're using
3418.24 -> semantic html
3420.799 -> in the next one we made sure that we had
3422.88 -> selectable controls by again using aria
3425.92 -> to apply an aria value to this slider to
3428.64 -> make sure that we were giving the user
3430.559 -> context with aria labels to ensure that
3433.76 -> we were notifying them what they were
3435.28 -> doing on the screen
3437.44 -> and then we went over to our other
3439.119 -> control and simplified our controls
3444.559 -> of our checklist here
3446.4 -> of all of our fillings so that instead
3448.319 -> of using nested controls and a
3450.16 -> complicated pattern with low
3451.92 -> accessibility we could simplify the
3454.079 -> controls with a similar result to ensure
3457.119 -> that we have higher accessibility of our
3459.76 -> control system
3461.76 -> and that was everything we did without
3463.76 -> any angular package
3466.079 -> then we went and we added the angular
3468.48 -> cdk accessibility package or ally
3471.599 -> package and we went in and we changed
3474.319 -> three things there
3476.319 -> we added the focus trap to control focus
3479.839 -> of this color
3481.2 -> dialogue
3482.88 -> we also announced changes when we exit
3485.52 -> the color dialog as well as when we make
3487.76 -> a purchase
3489.119 -> let's go in dark mode for this
3492.319 -> uh using the live announcer to announce
3494.559 -> those changes
3495.92 -> and finally we looked at high contrast
3498.16 -> mode to ensure that users with a
3500.799 -> selection for a specific uh
3504 -> change on their screen or a visual
3506.24 -> indication of preference are being
3508.24 -> respected by your application using the
3510.559 -> built-in high contrast mix-in that we
3512.96 -> provide
3514 -> and so we did all of that and we fixed
3516 -> eight super quick super easy things
3518.799 -> uh for how to fix accessibility in this
3521.119 -> app
3522.359 -> congratulations you addressed common web
3525.28 -> accessibility issues in your angular app
3529.2 -> what was your favorite step
3531.28 -> my personal favorite is angular v14's
3534.319 -> new streamlined page title options
3536.96 -> directly in the router
3538.96 -> it's a game changer for out of the box
3541.2 -> accessibility
3543.28 -> to see all of the solutions check out
3545.52 -> the main branch in the github repository
3549.44 -> you now know the key steps required to
3551.68 -> resolving eight common ally pitfalls in
3554.48 -> your angular application
3557.839 -> you so much for joining me don't forget
3560.319 -> to follow angular on twitter and youtube
3563.52 -> and i'll see you next time
3569.76 -> [Music]
3578.88 -> you
Source: https://www.youtube.com/watch?v=Gm_bD1abFXI