Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

JS Fest 2019. Mauricio Palma. You can’t read this sentence - A11y automation

134 views

Published on

Exemplum illud exclusive…
How does it feel not being able to read the sentence above? This is what we are doing every day to about 360 million people with visual impairments.
As developers we don’t think very much about this numbers, and yet it’s still our responsibility to include as many people as possible in our applications. In this talk we will learn some important Javascript automation tasks e.g. enhanced color contrast and voice interfaces. Let us dive into some best practices and real-life examples to avoid making the same mistakes all over again in the future.

Published in: Education
  • DOWNLOAD THAT BOOKS INTO AVAILABLE FORMAT (2019 Update) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download Full EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download Full doc Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download doc Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... ......................................................................................................................... ................................................................................................................................... eBook is an electronic version of a traditional print book that can be read by using a personal computer or by using an eBook reader. (An eBook reader can be a software application for use on a computer such as Microsoft's free Reader application, or a book-sized computer that is used solely as a reading device such as Nuvomedia's Rocket eBook.) Users can purchase an eBook on diskette or CD, but the most popular method of getting an eBook is to purchase a downloadable file of the eBook (or other reading material) from a Web site (such as Barnes and Noble) to be read from the user's computer or reading device. Generally, an eBook can be downloaded in five minutes or less ......................................................................................................................... .............. Browse by Genre Available eBooks .............................................................................................................................. Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Cookbooks, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, ......................................................................................................................... ......................................................................................................................... .....BEST SELLER FOR EBOOK RECOMMEND............................................................. ......................................................................................................................... Blowout: Corrupted Democracy, Rogue State Russia, and the Richest, Most Destructive Industry on Earth,-- The Ride of a Lifetime: Lessons Learned from 15 Years as CEO of the Walt Disney Company,-- Call Sign Chaos: Learning to Lead,-- StrengthsFinder 2.0,-- Stillness Is the Key,-- She Said: Breaking the Sexual Harassment Story That Helped Ignite a Movement,-- Atomic Habits: An Easy & Proven Way to Build Good Habits & Break Bad Ones,-- Everything Is Figureoutable,-- What It Takes: Lessons in the Pursuit of Excellence,-- Rich Dad Poor Dad: What the Rich Teach Their Kids About Money That the Poor and Middle Class Do Not!,-- The Total Money Makeover: Classic Edition: A Proven Plan for Financial Fitness,-- Shut Up and Listen!: Hard Business Truths that Will Help You Succeed, ......................................................................................................................... .........................................................................................................................
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Be the first to like this

JS Fest 2019. Mauricio Palma. You can’t read this sentence - A11y automation

  1. 1. 15 years ago…
  2. 2. 7 years ago…
  3. 3. 2012
  4. 4. She had a long history…
  5. 5. The grandma
  6. 6. 2012 From
  7. 7. To
  8. 8. They founded their label and…
  9. 9. The Man
  10. 10. Today
  11. 11. Mauricio Palma Co-founder and all kind of things @WDLK Product Engineer @sinnerschrader everywhere else @palmaswell
  12. 12. But
  13. 13. Why?
  14. 14. Back in The Day
  15. 15. Way harder!
  16. 16. opportunity
  17. 17. Nature of the web
  18. 18. We use our our abilities
  19. 19. You can’t read this sentence A11y automation April, 2019
  20. 20. That was awkward! Right?
  21. 21. Literally hurts!
  22. 22. 217 million
  23. 23. How to fix the numbers?
  24. 24. Blurry Vision
  25. 25. Key Takeaways Publish all information and content from your site in your HTML Use semantic HTML and the appropriate ARIA landmarks Write screen reader friendly markup Provide keyboard navigation
  26. 26. Partial vision loss
  27. 27. Key Takeaways Besides the mentioned semantic HTML and screen reader friendly markup You should follow a linear logical layout, that supports at least 200% magnification
  28. 28. Central vision loss
  29. 29. Key Takeaways Always put form elements in context. Meaning putting buttons, inputs, and notifications together in a logical manner For action elements in your interface use a good combination of colors, shapes, and text Do not rely on colors to convey meaning
  30. 30. Dyslexia
  31. 31. Key Takeaways Align your text to the left and keep a consistent layout Keep content short, clear and simple Consider producing materials in other formats (for example audio or video) Let the users change the contrast between background and text
  32. 32. Colorblindness
  33. 33. Key Takeaways Make sure that colors are not your only method of conveying important information.
  34. 34. Sunlight Bad lightning Temporary disabilities
  35. 35. Persona spectrum Permanent Temporary Situational
  36. 36. We usetechnologyto includemore people
  37. 37. A11y everywhere
  38. 38. You Your codeUnit testsShipCode Test
  39. 39. Friday night deployment?
  40. 40. Color Contrast Automation
  41. 41. AaAaAaAaAa AA || AAA
  42. 42. O(n^2)
  43. 43. 2500
  44. 44. Forward A11y color contrast automation github.com/palmaswell/forward
  45. 45. github.com/palmaswell/forward
  46. 46. Make it easier for users to see and hear content including separating foreground from background. Guideline 1.4 Distinguishable:
  47. 47. AA >= 4.5:1
  48. 48. AAA >= 7:1
  49. 49. AA >= 3:1 Large-scale text
  50. 50. AAA >= 4.5:1 Large-scale text
  51. 51. 24px || 19px bold Large-scale text
  52. 52. Logos and brand Other exceptions
  53. 53. Inactive UI elements Other exceptions
  54. 54. Can your read this? Color contrast 1.6 ratio
  55. 55. Can your read this? Color contrast 8.05 ratio AAA
  56. 56. Note 1: For the sRGB colorspace, the relative luminance of a color is defined as L = 0.2126 * R + 0.7152 * G + 0.0722 * B where R, G and B are defined as: if RsRGB <= 0.03928 then R = RsRGB/12.92 else R = ((RsRGB+0.055)/1.055) ^ 2.4 if GsRGB <= 0.03928 then G = GsRGB/12.92 else G = ((GsRGB+0.055)/1.055) ^ 2.4 if BsRGB <= 0.03928 then B = BsRGB/12.92 else B = ((BsRGB+0.055)/1.055) ^ 2.4 WCAG definition of relative luminance
  57. 57. Excuse me?
  58. 58. Luminance
  59. 59. Relative Luminance
  60. 60. 0
  61. 61. 1
  62. 62. Note 1: For the sRGB color space, the relative luminance of a color is defined as L = 0.2126 * R + 0.7152 * G + 0.0722 * B where R, G and B are defined as: WCAG definition of relative luminance
  63. 63. standardized by the International Electrotechnical Commission sRGB
  64. 64. sRGB
  65. 65. Our visual system
  66. 66. Works in a similar way Default color space Visual SystemWeb Browsers
  67. 67. Chromaticity | Chromaticity | Red | Green | Blue | White point | |--------------|---------|-----------|----------|--------------| | x | 0.6400 | 0.3000 | 0.1500 | 0.3127 | | y | 0.3300 | 0.6000 | 0.0600 | 0.3290 | | Y | 0.2126 | 0.7152 | 0.0722 | 1.0000 |
  68. 68. export enum YValues { r = 0.2126, g = 0.7152, b = 0.0722, } xyY color space Step 1 Y values represent the luminance of a color entry
  69. 69. export function calculateRGBEntry( entry: number, y: Type.YValues): number { const average = entry / 255; return average <= 0.03928 ? average / 12.92 * y : ((average + 0.055) / 1.055 ) ** 2.4 * y; }; Color contrast Step 2
  70. 70. Color contrast Step 2 export function luminance( sRGB: Type.RGB ): number { return calculateRGBEntry(sRGB[0], Type.YValues.r) + calculateRGBEntry(sRGB[1], Type.YValues.g) + calculateRGBEntry(sRGB[2], Type.YValues.b); }
  71. 71. Color contrast Step 2 export function contrastRatio( sRGB: Type.RGB, sRGB2: Type.RGB): number { const light = Math.max(luminance(sRGB), luminance(sRGB2)); const dark = Math.min(luminance(sRGB), luminance(sRGB2)); return +((light + 0.05) / (dark + 0.05)).toFixed(2); }
  72. 72. N colors Aa Aa Aa Aa [ ]
  73. 73. A11y everywhere
  74. 74. Quicksort fast sorting algorithm
  75. 75. SortStep 3 export function quickSort( arr: Type.Color[], cb: (sRGB: Type.RGB) => number, lo: number, hi: number ): void { if (lo < hi) { const pivot = cb(arr[Math.floor((lo + hi) / 2)].rgb); const p = partition(arr, lo, hi, pivot, cb); quickSort(arr, cb, lo, p.hi); quickSort(arr, cb, p.lo, hi); } } export function sort( arr: Type.Color[], cb: (sRGB: Type.RGB) => number) { return quickSort(arr, cb, 0, arr.length - 1); }
  76. 76. SortStep 3 export function quickSort( arr: Type.Color[], cb: (sRGB: Type.RGB) => number, lo: number, hi: number ): void { if (lo < hi) { const pivot = cb(arr[Math.floor((lo + hi) / 2)].rgb); const p = partition(arr, lo, hi, pivot, cb); quickSort(arr, cb, lo, p.hi); quickSort(arr, cb, p.lo, hi); } } export function sort( arr: Type.Color[], cb: (sRGB: Type.RGB) => number) { return quickSort(arr, cb, 0, arr.length - 1); }
  77. 77. SortStep 3 export function quickSort( arr: Type.Color[], cb: (sRGB: Type.RGB) => number, lo: number, hi: number ): void { if (lo < hi) { const pivot = cb(arr[Math.floor((lo + hi) / 2)].rgb); const p = partition(arr, lo, hi, pivot, cb); quickSort(arr, cb, lo, p.hi); quickSort(arr, cb, p.lo, hi); } } export function sort( arr: Type.Color[], cb: (sRGB: Type.RGB) => number) { return quickSort(arr, cb, 0, arr.length - 1); }
  78. 78. SortStep 3 export function partition( arr: Type.Color[], lo: number, hi: number, pivot: number, cb: (sRGB: Type.RGB) => number): { lo: number, hi: number} { if (lo <= hi) { if (cb(arr[lo].rgb) < pivot) { return partition(arr, lo + 1, hi, pivot, cb); } if (cb(arr[hi].rgb) > pivot) { return partition(arr, lo, hi - 1, pivot, cb); } if (lo <= hi) { swap(arr, lo, hi); return partition(arr, lo + 1, hi - 1, pivot, cb); } } return { lo, hi }; }
  79. 79. SortStep 3 export function quickSort( arr: Type.Color[], cb: (sRGB: Type.RGB) => number, lo: number, hi: number ): void { if (lo < hi) { const pivot = cb(arr[Math.floor((lo + hi) / 2)].rgb); const p = partition(arr, lo, hi, pivot, cb); quickSort(arr, cb, lo, p.hi); quickSort(arr, cb, p.lo, hi); } } export function sort( arr: Type.Color[], cb: (sRGB: Type.RGB) => number) { return quickSort(arr, cb, 0, arr.length - 1); }
  80. 80. AaAaAaAaAa QuicksortStep 3
  81. 81. Aa Aa AaAaAa Sorted by luminance Step 3
  82. 82. Binary Search efficient algorithm that searches a sorted list
  83. 83. Aa Aa AaAaAa Binary Search Step 4 AAA color contrast check Match!
  84. 84. SearchStep 4 function lowerSearch<T extends QuickSearch>( arr: Array<T>, el: T, val: number, lo: number, hi: number): number | [] { const mid = Math.floor((lo + hi) / 2); const prev = mid - 1; const next = mid + 1; const midRatio = contrastRatio(arr[mid].rgb, el.rgb); if (lo < hi) { if (midRatio > val && prev >= 0) { if (contrastRatio(arr[prev].rgb, el.rgb) < val) { return mid; } return lowerSearch(arr, el, val, lo, mid); } if (midRatio < val && next < arr.length) { if (contrastRatio(arr[next].rgb, el.rgb) > val) { return next; } return lowerSearch(arr, el, val, mid, hi) } if (mid === val) { return mid; } } return []; }; export function search( arr: Type.Color[], el: Type.Color, val: Type.A11yRatio, type?: Type.Search): number | [] { if (type === Type.Search.upper) { return upperSearch(arr, el, val, 0, arr.length); } return lowerSearch(arr, el, val, 0, arr.length); };
  85. 85. SearchStep 4 function lowerSearch<T extends QuickSearch>( arr: Array<T>, el: T, val: number, lo: number, hi: number): number | [] { const mid = Math.floor((lo + hi) / 2); const prev = mid - 1; const next = mid + 1; const midRatio = contrastRatio(arr[mid].rgb, el.rgb); if (lo < hi) { if (midRatio > val && prev >= 0) { if (contrastRatio(arr[prev].rgb, el.rgb) < val) { return mid; } return lowerSearch(arr, el, val, lo, mid); } if (midRatio < val && next < arr.length) { if (contrastRatio(arr[next].rgb, el.rgb) > val) { return next; } return lowerSearch(arr, el, val, mid, hi) } if (mid === val) { return mid; } } return []; }; export function search( arr: Type.Color[], el: Type.Color, val: Type.A11yRatio, type?: Type.Search): number | [] { if (type === Type.Search.upper) { return upperSearch(arr, el, val, 0, arr.length); } return lowerSearch(arr, el, val, 0, arr.length); };
  86. 86. SearchStep 4 function lowerSearch<T extends QuickSearch>( arr: Array<T>, el: T, val: number, lo: number, hi: number): number | [] { const mid = Math.floor((lo + hi) / 2); const prev = mid - 1; const next = mid + 1; const midRatio = contrastRatio(arr[mid].rgb, el.rgb); if (lo < hi) { if (midRatio > val && prev >= 0) { if (contrastRatio(arr[prev].rgb, el.rgb) < val) { return mid; } return lowerSearch(arr, el, val, lo, mid); } if (midRatio < val && next < arr.length) { if (contrastRatio(arr[next].rgb, el.rgb) > val) { return next; } return lowerSearch(arr, el, val, mid, hi) } if (mid === val) { return mid; } } return []; }; export function search( arr: Type.Color[], el: Type.Color, val: Type.A11yRatio, type?: Type.Search): number | [] { if (type === Type.Search.upper) { return upperSearch(arr, el, val, 0, arr.length); } return lowerSearch(arr, el, val, 0, arr.length); };
  87. 87. Enhanced Color
  88. 88. Enhanced colors Step 5 export function createEnhanced( rawColor: Type.Color, aaa: Type.Color[] | [], aa: Type.Color[] | [] ): Type.colorEnhanced { const rgb = rawColor.rgb; return { name: rawColor.name, rgb, aaa, aa, toRGB(): string { return toRGBString(rgb); }, toHEX(): string { return tinyColor(toRGBString(rgb)).toHexString(); }, toHSL(): string { return tinyColor(toRGBString(rgb)).toHslString(); }, toRGBA(alpha: number): string { const color = tinyColor(toRGBString(rgb)); color.setAlpha(alpha); return color.toRgbString() } } }
  89. 89. Enhanced colors Step 5 export function createEnhanced( rawColor: Type.Color, aaa: Type.Color[] | [], aa: Type.Color[] | [] ): Type.colorEnhanced { const rgb = rawColor.rgb; return { name: rawColor.name, rgb, aaa, aa, toRGB(): string { return toRGBString(rgb); }, toHEX(): string { return tinyColor(toRGBString(rgb)).toHexString(); }, toHSL(): string { return tinyColor(toRGBString(rgb)).toHslString(); }, toRGBA(alpha: number): string { const color = tinyColor(toRGBString(rgb)); color.setAlpha(alpha); return color.toRgbString() } } }
  90. 90. Colors Under Control
  91. 91. Demo
  92. 92. It’s open github.com/palmaswell/forward Use it, play with it, make it better!
  93. 93. Benefits New opportunities Offer utility and elegance Profitable Legal compliance
  94. 94. Before: 10% (imaginary number) Middle: x100% After: x1000% A11y costs factors
  95. 95. Questions?
  96. 96. Thanks!Github: @palmaswell Twitter: @palmaswell mauricio.palma@sinnerschrader.com

×