PageSourceSearch

https://www.a11ywithlindsey.com/blog/accessible-interactive-components-react/

html a11ywithlindsey.com collected 2026-10-02 04:09:06 UTC 159,427 bytes, 414 lines download raw bytes

1<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta http-equiv="x-ua-compatible" content="ie=edge"/><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/><style data-href="/styles.bf63ffca541d1ab536ba.css" id="gatsby-global-css">@import url(https://fonts.googleapis.com/css?family=PT+Sans:400,700|PT+Serif);@import url(https://use.fontawesome.com/releases/v5.3.1/css/all.css);:root[data-user-reduced-motion] .menu a{padding:.875rem;text-decoration:none}.menu-main{grid-row:1/span 2;grid-column:3}.menu{margin:0;padding:0;list-style:none}.menu a{position:relative;display:inline-block;text-transform:uppercase;letter-spacing:2px;font-weight:700;font-size:1rem;padding:.375rem;border:none;transition:all .3s;text-decoration:none}.menu-main a{color:var(--marron)}.menu a:hover{padding:.375rem}.privacy-policy a{text-transform:none;font-size:.75rem}@media only screen and (min-width:767px){.menu-main{grid-row:2;grid-column:2/span 2;justify-self:end;align-self:end}.menu-main li{display:inline-block}.menu a{font-size:1.125rem;padding:.875rem}.menu a:hover{padding:.875rem}.privacy-policy a{text-transform:none;font-size:.75rem}}@media screen and (prefers-reduced-motion:reduce){:root:not([data-user-reduced-motion]) .menu a{padding:.375rem;text-decoration:none}:root[data-user-reduced-motion] .menu a{padding:.375rem;text-decoration:none}}@media screen and (prefers-reduced-motion:reduce) and (min-width:767px){:root:not([data-user-reduced-motion]) .menu a{padding:.875rem;text-decoration:none}:root[data-user-reduced-motion] .menu a{padding:.875rem;text-decoration:none}}.toggle{grid-column:1/span 2;align-self:center}@media only screen and (min-width:767px){.toggle{grid-column:3/span 1;grid-row:1/span 1}}.header-wrapper{margin:0 auto;padding:0 1.5rem;max-width:52rem;display:grid}.header__right{display:flex}.logo{grid-column:1/span 1;grid-row:2/span 1;align-self:center;margin:0}.logo img{width:175px}@media only screen and (min-width:767px){.logo img{width:200px}.header-wrapper{grid-template-rows:3rem 5.875rem;grid-template-columns:25% auto 13rem}}.formkit-form[data-uid="4218bd5fb5"] *{font-family:PT Sans,sans-serif;box-sizing:border-box}.formkit-form[data-uid="4218bd5fb5"]{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.formkit-form[data-uid="4218bd5fb5"] legend{border:none;font-size:inherit;margin-bottom:10px;padding:0;position:relative;display:table}.formkit-form[data-uid="4218bd5fb5"] fieldset{border:0;padding:.01em 0 0;margin:0;min-width:0}.formkit-form[data-uid="4218bd5fb5"] body:not(:-moz-handler-blocked) fieldset{display:table-cell}.formkit-form[data-uid="4218bd5fb5"] h1,.formkit-form[data-uid="4218bd5fb5"] h2,.formkit-form[data-uid="4218bd5fb5"] h3,.formkit-form[data-uid="4218bd5fb5"] h4,.formkit-form[data-uid="4218bd5fb5"] h5,.formkit-form[data-uid="4218bd5fb5"] h6{color:inherit;font-family:"PT Serif",serif}.formkit-form[data-uid="4218bd5fb5"] p{color:inherit;font-size:inherit;font-weight:inherit}.formkit-form[data-uid="4218bd5fb5"][data-format=modal]{display:none}.formkit-form[data-uid="4218bd5fb5"][data-format="slide in"]{display:none}.formkit-form[data-uid="4218bd5fb5"] .formkit-checkboxes,.formkit-form[data-uid="4218bd5fb5"] .formkit-input,.formkit-form[data-uid="4218bd5fb5"] .formkit-select{width:100%}.formkit-form[data-uid="4218bd5fb5"] .formkit-button,.formkit-form[data-uid="4218bd5fb5"] .formkit-submit{border:2px solid;border-radius:16px;color:#640d23;display:inline-block;cursor:pointer;overflow:hidden;padding:0;position:relative;vertical-align:middle}.formkit-form[data-uid="4218bd5fb5"] .formkit-button>span,.formkit-form[data-uid="4218bd5fb5"] .formkit-submit>span{display:block;transition:all .3s ease-in-out;padding:12px 24px}.formkit-form[data-uid="4218bd5fb5"] .formkit-input{background:transparent;font-size:15px;padding:12px;flex:1 0 auto;line-height:1.4;margin:0;transition:border-color .3s ease-out}.formkit-form[data-uid="4218bd5fb5"] .formkit-input:focus{border-color:#1677be;transition:border-color .3s ease}.convertkit-signup--footer .formkit-form[data-uid="4218bd5fb5"] .formkit-input::-webkit-input-placeholder{color:#640d23}.convertkit-signup--footer .formkit-form[data-uid="4218bd5fb5"] .formkit-input:-ms-input-placeholder{color:#640d23}.convertkit-signup--footer .formkit-form[data-uid="4218bd5fb5"] .formkit-input::placeholder{color:#640d23}.convertkit-signup--sidebar .formkit-form[data-uid="4218bd5fb5"] .formkit-input::-webkit-input-placeholder{color:#640d23}.convertkit-signup--sidebar .formkit-form[data-uid="4218bd5fb5"] .formkit-input:-ms-input-placeholder{color:#640d23}.convertkit-signup--sidebar .formkit-form[data-uid="4218bd5fb5"] .formkit-input::placeholder{color:#640d23}.formkit-form[data-uid="4218bd5fb5"] [data-group=dropdown]{position:relative;display:inline-block;width:100%}.formkit-form[data-uid="4218bd5fb5"] [data-group=dropdown]:before{content:"";top:calc(50% - 2.5px);right:10px;position:absolute;pointer-events:none;border-color:#4f4f4f transparent transparent;border-style:solid;border-width:6px 6px 0;
1height:0;width:0;z-index:999}.formkit-form[data-uid="4218bd5fb5"] [data-group=dropdown] select{height:auto;width:100%;cursor:pointer;color:#333;line-height:1.4;margin-bottom:0;-webkit-appearance:none;appearance:none;font-size:15px;padding:12px 25px 12px 12px;border:1px solid #e3e3e3;background:#fff}.formkit-form[data-uid="4218bd5fb5"] [data-group=checkboxes]{text-align:left;margin:0}.formkit-form[data-uid="4218bd5fb5"] [data-group=checkboxes] [data-group=checkbox]{margin-bottom:10px}.formkit-form[data-uid="4218bd5fb5"] [data-group=checkboxes] [data-group=checkbox] *{cursor:pointer}.formkit-form[data-uid="4218bd5fb5"] [data-group=checkboxes] [data-group=checkbox]:last-of-type{margin-bottom:0}.formkit-form[data-uid="4218bd5fb5"] [data-group=checkboxes] [data-group=checkbox] input[type=checkbox]{display:none}.formkit-form[data-uid="4218bd5fb5"] [data-group=checkboxes] [data-group=checkbox] input[type=checkbox]+label:after{content:none}.formkit-form[data-uid="4218bd5fb5"] [data-group=checkboxes] [data-group=checkbox] input[type=checkbox]:checked+label:after{border-color:#fff;content:""}.formkit-form[data-uid="4218bd5fb5"] [data-group=checkboxes] [data-group=checkbox] input[type=checkbox]:checked+label:before{background:#10bf7a;border-color:#10bf7a}.formkit-form[data-uid="4218bd5fb5"] [data-group=checkboxes] [data-group=checkbox] label{position:relative;display:inline-block;padding-left:28px}.formkit-form[data-uid="4218bd5fb5"] [data-group=checkboxes] [data-group=checkbox] label:after,.formkit-form[data-uid="4218bd5fb5"] [data-group=checkboxes] [data-group=checkbox] label:before{position:absolute;content:"";display:inline-block}.formkit-form[data-uid="4218bd5fb5"] [data-group=checkboxes] [data-group=checkbox] label:before{height:16px;width:16px;border:1px solid #e3e3e3;background:#fff;left:0;top:3px}.formkit-form[data-uid="4218bd5fb5"] [data-group=checkboxes] [data-group=checkbox] label:after{height:4px;width:8px;border-left:2px solid #4d4d4d;border-bottom:2px solid #4d4d4d;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);left:4px;top:8px}.formkit-form[data-uid="4218bd5fb5"] .formkit-alert{background:#f9fafb;border:1px solid #e3e3e3;border-radius:5px;flex:1 0 auto;list-style:none;margin:25px auto;padding:12px;width:100%}.formkit-form[data-uid="4218bd5fb5"] .formkit-alert:empty{display:none}.formkit-form[data-uid="4218bd5fb5"] .formkit-alert-success{background:#d3fbeb;border-color:#10bf7a;color:#0c905c}.formkit-form[data-uid="4218bd5fb5"] .formkit-alert-error{background:#fde8e2;border-color:#f2643b;color:#ea4110}.formkit-form[data-uid="4218bd5fb5"] .formkit-spinner{display:flex;height:0;margin:0 auto;position:absolute;top:0;left:0;right:0;width:0;overflow:hidden;transition:all .3s ease-in-out}.formkit-form[data-uid="4218bd5fb5"] .formkit-spinner>div{margin:auto;width:12px;height:12px;background-color:#fff;opacity:.3;border-radius:100%;display:inline-block;-webkit-animation:formkit-bouncedelay-formkit-form-data-uid-4218bd5fb5- 1.4s ease-in-out infinite both;animation:formkit-bouncedelay-formkit-form-data-uid-4218bd5fb5- 1.4s ease-in-out infinite both}.formkit-form[data-uid="4218bd5fb5"] .formkit-spinner>div:first-child{-webkit-animation-delay:-.32s;animation-delay:-.32s}.formkit-form[data-uid="4218bd5fb5"] .formkit-spinner>div:nth-child(2){-webkit-animation-delay:-.16s;animation-delay:-.16s}.formkit-form[data-uid="4218bd5fb5"] .formkit-submit[data-active] .formkit-spinner{opacity:1;height:100%;width:50px}.formkit-form[data-uid="4218bd5fb5"] .formkit-submit[data-active] .formkit-spinner~span{opacity:0}@-webkit-keyframes formkit-bouncedelay-formkit-form-data-uid-4218bd5fb5-{0%,80%,to{-webkit-transform:scale(0);transform:scale(0)}40%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes formkit-bouncedelay-formkit-form-data-uid-4218bd5fb5-{0%,80%,to{-webkit-transform:scale(0);transform:scale(0)}40%{-webkit-transform:scale(1);transform:scale(1)}}.formkit-form[data-uid="4218bd5fb5"]{max-width:700px}.formkit-form[data-uid="4218bd5fb5"] [data-style=clean]{width:100%}.formkit-form[data-uid="4218bd5fb5"] .formkit-fields{display:flex;flex-wrap:wrap;margin:0 auto}.formkit-form[data-uid="4218bd5fb5"] .formkit-field,.formkit-form[data-uid="4218bd5fb5"] .formkit-submit{margin:0 0 15px;flex:1 0 100%}.formkit-form[data-uid="4218bd5fb5"] .formkit-powered-by{font-size:12px;margin:0}.formkit-form[data-uid="4218bd5fb5"] .formkit-powered-by[data-active=false]{opacity:.5}.formkit-form[data-uid="4218bd5fb5"][min-width~="700"] [data-style=clean],.formkit-form[data-uid="4218bd5fb5"][min-width~="800"] [data-style=clean]{padding:10px}.formkit-form[data-uid="4218bd5fb5"][min-width~="700"] .formkit-fields[data-stacked=false],.formkit-form[data-uid="4218bd5fb5"][min-width~="800"] .formkit-fields[data-stacked=false]{margin-left:-5px;margin-right:-5px}.formkit-form[data-uid="4218bd5fb5"][min-width~="700"] .formkit-fields[data-stacked=false] .formkit-field,.formkit-form[data-uid="4218bd5fb5"][min-width~="700"] .formkit-fields[data-stacked=false] .formkit-submit,.formkit-form[data-uid="4218bd5fb5"][min-width~="800"] .formkit-fields[data-stacked=false] .formkit-field,.formkit-form[data-uid="4218bd5fb5"][min-width~="800"] .formkit-fields[data-stacked=false] .formkit-submit{margin:0 5px 15px}.formkit-form[data-uid="4218bd5fb5"][min-width~="700"] .formkit-fields[data-stacked=false] .formkit-field,.formkit-form[data-uid="4218bd5fb5"][min-width~="800"] .formkit-fields[data-stacked=false] .formkit-field{flex:100 1 auto}.formkit-form[data-uid="4218bd5fb5"][min-width~="700"] .formkit-fields[data-stacked=false] .formkit-submit,.formkit-form[data-uid="4218bd5fb5"][min-width~="800"] .formkit-fields[data-stacked=false] .formkit-submit{flex:1 1 auto}.convertkit-signup--white-bg{padding:2rem;background:#fff;box-shadow:0 2px 4px rgba(0,0,0,.11);font-weight:700}.formkit-form h2{margin-top:0}.formkit-input--email,.formkit-input--name{margin-bottom:.75rem}.formkit-submit{border-radius:5px;padding:5px;font-weight:500;font-family:PT Sans,sans-serif;color:#fff;border:1px solid #640d23;background:transparent;font-size:1rem;-webkit-appearance:none;appearance:none}.convertkit-signup--footer input{background:transparent;border:#640d23;border-bottom:2px solid #640d23;color:#640d23;font-size:1rem}
1.convertkit-signup.convertkit-signup--footer{width:65%;float:right}.convertkit-signup.convertkit-signup--footer .formkit-form[data-uid="4218bd5fb5"] .formkit-input{background:transparent!important}footer{background:var(--off-white);padding:15px 0;color:var(--marron)}.footer-wrapper{margin:0 auto;max-width:52rem;padding:0 20px}.footer-menu li{list-style:none;text-align:left}.footer-details{display:flex;flex-direction:column}footer a{color:var(--marron)}footer a:focus{outline:solid 2px var(--marron)}footer input:focus{outline:solid 2px var(--marron)}.social{display:flex;padding:0}.social li{list-style:none;padding:1rem}.social a{font-size:1.5rem;border-bottom:none}.credit{font-size:.75rem;margin:2.5rem 20px 1rem}@media only screen and (min-width:767px){.footer-wrapper{display:flex;justify-content:space-between}.social{justify-content:flex-end}.credit{text-align:center}.convertkit-signup--footer{align-self:flex-end}}:root{--teal:#24728a;--vermillion:#c03711;--white:#fff;--peach:#fed8ce}:root[data-user-reduced-motion=true] *{-webkit-animation-play-state:paused!important;animation-play-state:paused!important;transition:none!important;scroll-behavior:auto!important}:root[data-user-reduced-motion=true] a{padding-bottom:0;border-bottom:none;text-decoration:underline}body{margin:0;font-family:PT Sans,sans-serif;background:var(--off-white);color:var(--marron);font-size:1.125rem}h1,h2,h3,h4,h5,h6{font-family:"PT Serif",serif}.visually-hidden{position:absolute;left:-10000px;top:auto;width:1px;height:1px;overflow:hidden}.focusable.visually-hidden:focus{position:relative;left:0;width:auto;height:auto;overflow:auto;border-bottom:none}.wrapper{margin:0 auto;max-width:52rem;padding:20px}.content__heading{background:var(--pale-blue);color:var(--navy)}.content__heading a{color:var(--navy)}.promo{position:fixed;-webkit-transform:translateY(-80px);transform:translateY(-80px);width:100%;z-index:10;background:var(--white);box-shadow:1px 1px 5px 0 rgba(0,0,0,.2);padding:.5rem 0;text-align:center;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s}.promo-showing .promo{-webkit-transform:translateY(0);transform:translateY(0)}time{position:relative;display:inline-block;font-family:"PT Serif",serif;color:var(--vermillion);font-style:italic;font-weight:700}p{line-height:1.5}a{padding-bottom:2px;border-bottom:2px solid;text-decoration:none;color:var(--marron);font-weight:700;transition:padding-bottom .3s ease}a:hover,p a:focus{padding-bottom:4px}p a:focus{outline:1px solid #1e3650}li{line-height:1.5}img{max-width:100%}.gatsby-resp-image-link{border-bottom:none;padding:0}.gatsby-resp-image-link:hover{padding:0}.gatsby-resp-image-wrapper{margin-bottom:1rem}h2 a,h3 a{color:var(--marron);font-size:inherit}code{font-weight:700;font-size:1.25rem;padding:2px 5px;line-height:1.5}h2 code{font-size:1.75rem}pre{background:var(--navy);color:var(--off-white);display:block;margin:0 auto;padding:1rem;overflow:auto;max-width:590px}pre code{font-size:.9325rem;font-weight:400}.gatsby-highlight{margin:1rem 0}.language-html .tag,.language-jsx .tag{color:#fdb4cf}.language-html .attr-value,.language-jsx .attr-name{color:#b2dfeb}.language-html .attr-value .punctuation:first-child{color:#fdb4cf}.language-css,.language-scss{color:#b2dfeb}.language-css .selector,.language-scss .selector{color:#fdb4cf}.language-css .property,.language-css .punctuation,.language-scss .property,.language-scss .punctuation{color:#fff}.language-js .keyword,.language-jsx .keyword{color:#fdb4cf}.language-js .function,.language-jsx .function{color:#b2dfeb}.language-js .string,.language-jsx .string{color:#f8b4a0}.language-js .number,.language-jsx .operator{color:#b2dfeb}.language-js .comment,.language-jsx .operator{color:#c4c4c4}.language-js .operator,.language-jsx .operator{color:#fdb4cf}.language-json .property{color:#f8b4a0}.language-json .string{color:#b2dfeb}.language-diff .inserted{color:#a9f9b2}.language-diff .deleted{color:#f8b4a0}.gatsby-highlight-code-line{display:block;margin-right:-1rem;margin-left:-1rem;padding-right:1rem;padding-left:.25rem;
1border-left:8px solid #c03711;background:#305282}video{max-width:100%}audio,video{display:block;margin:1rem 0}blockquote:not(.twitter-tweet){position:relative;margin:3rem auto;border-left:8px solid var(--vermillion);padding:3rem;width:60%;font-size:1.4rem;font-weight:500;line-height:1.6;color:var(--marron)}twitterwidget{margin-left:auto;margin-right:auto}input{background:transparent;border:none;border-bottom:2px solid}input[type=submit]{cursor:pointer}.breadcrumb ol{padding:0}.breadcrumb li{display:inline;list-style:none;padding-right:7px}.breadcrumb li:not(:last-child):after{content:" \BB   ";padding-left:3px}.breadcrumb a:focus{padding-bottom:4px;outline:1px solid #1e3650}blockquote.twitter-tweet{display:inline-block;font-family:Helvetica Neue,Roboto,Segoe UI,Calibri,sans-serif;font-size:12px;font-weight:700;line-height:16px;border-radius:5px;border-color:#eee #ddd #bbb;border-style:solid;border-width:1px;box-shadow:0 1px 3px rgba(0,0,0,.15);margin:10px 5px;padding:0 16px 16px;max-width:468px}blockquote.twitter-tweet p{font-size:16px;font-weight:400;line-height:20px}blockquote.twitter-tweet a{color:inherit;font-weight:400;text-decoration:none;outline:0 none}blockquote.twitter-tweet a:focus,blockquote.twitter-tweet a:hover{text-decoration:underline}.source{max-width:590px;margin:0 auto}.sidebar--white-bg{padding:2rem;background:#fff;box-shadow:0 2px 4px rgba(0,0,0,.11);font-weight:700}.right-arrow{border:solid;border-width:0 3px 3px 0;display:inline-block;transform:rotate(-45deg);-webkit-transform:rotate(-45deg);padding:3px}.toggle__button{opacity:0}.toggle__button+label{margin-left:20px;margin-top:1px;position:relative}.toggle__button+label:before{content:"";position:absolute;left:-39px;top:-2px;border:2px solid;border-radius:10px;width:15px;height:15px;transition:all .3s}.toggle__button:focus+label:before{box-shadow:1px 1px 10px #1e3650}.toggle__button:hover+label:before{cursor:pointer}.toggle__button+label:after{content:"";position:absolute;border-radius:14px;border:2px solid;left:-45px;top:-6px;z-index:-10;width:35px;height:24px}.toggle__button:checked+label:before{left:-30px;background:#f3e9ea}.center{width:50%;display:block;margin:1rem auto}@media screen and (prefers-reduced-motion:reduce){:root:not([data-user-reduced-motion]) *{-webkit-animation-play-state:paused!important;animation-play-state:paused!important;transition:none!important;scroll-behavior:auto!important}:root:not([data-user-reduced-motion]) a{padding-bottom:0;border-bottom:none;text-decoration:underline}}.call-to-action{background:#fff;color:#24728a;padding:1rem 2rem}.call-to-action p:first-of-type{display:none}.call-to-action a{background:#c03711;color:#fff;border-radius:16px;padding:12px 14px;font-weight:500;font-size:1.25rem;display:inline-block;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s}.call-to-action a:focus,.call-to-action a:hover{-webkit-transform:scale(1.1);transform:scale(1.1);padding:12px 14px}@media only screen and (min-width:767px){.call-to-action{display:grid;grid-template-columns:25% 75%;grid-template-rows:repeat(3,1fr);max-height:240px;margin:2rem auto 3rem;max-width:650px;padding:0}.call-to-action h2,.call-to-action p{grid-column-start:2;place-self:center;text-align:center}.call-to-action p:first-of-type{display:block;margin:-.375rem 0 0;grid-column-start:1;grid-row-start:1;grid-row-end:3;place-self:auto}}:root{--pale-blue:#b5d8ff}:root[data-user-reduced-motion=true] .hero__cta__link{text-decoration:none;padding:12px 14px;border:2px solid}:root[data-user-reduced-motion=true] .hero__cta__link:hover{-webkit-transform:scale(1.05);transform:scale(1.05)}.hero{padding:3rem 0;background:var(--pale-blue);color:var(--navy)}.hero__text-wrapper{max-width:52rem;margin:0 auto;padding:1.5rem}.hero__cta__link{border-radius:16px;border:2px solid;padding:12px 14px;font-weight:500;color:var(--navy);font-size:1.25rem;display:inline-block;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s}.hero__cta__link:focus,.hero__cta__link:hover{-webkit-transform:scale(1.1);transform:scale(1.1);padding:12px 14px}.hero__cta__link:focus{outline:solid 3px var(--navy)}@media only screen and (min-width:767px){.hero__body--break{display:block}.hero__body p{line-height:1.5}}@media screen and (prefers-reduced-motion:reduce){:root:not([data-user-reduced-motion]) .hero__cta__link{text-decoration:none;padding:12px 14px;border:2px solid}:root:not([data-user-reduced-motion]) .hero__cta__link:hover{-webkit-transform:scale(1.05);transform:scale(1.05)}}:root{--marron:#640d23;--off-white:#f3e9ea;--navy:#1e3650}:root[data-user-reduced-motion=true] .blog__more-link{text-decoration:none;padding:12px 14px;border:2px solid}:root[data-user-reduced-motion=true] .blog__more-link:hover{-webkit-transform:scale(1.05);transform:scale(1.05)}.book{background-color:var(--navy);padding:1rem 0;text-align:center}.book,.book a{color:var(--off-white)}.blog{max-width:52rem;padding:2rem 1.5rem;margin:0 auto}.blog__items{margin:2rem 0}.blog__title{margin:.625rem 0;font-size:1.3125rem}.blog__more-link{border-radius:16px;border:2px solid;padding:12px 14px;font-weight:500;color:var(--marron);font-size:1.25rem;display:inline-block;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s}.blog__more-link:focus,.blog__more-link:hover{padding:12px 14px;-webkit-transform:scale(1.1);transform:scale(1.1)}.supporters-tier ul{display:flex;list-style:none}.supporters-tier li{margin:0 .5rem}@media screen and (prefers-reduced-motion:reduce){:root:not([data-user-reduced-motion]) .blog__more-link{text-decoration:none;padding:12px 14px;border:2px solid}:root:not([data-user-reduced-motion]) .blog__more-link:hover{-webkit-transform:scale(1.05);transform:scale(1.05)}}.featured-image-block{margin:3rem 0;background:#fff;box-shadow:0 2px 4px rgba(0,0,0,.11)}.featured-image-block__wrapper{position:relative;padding:3rem 2rem}.featured-image-block__img{position:absolute;right:-14px;top:-56px}.featured-image-block__img img{border-radius:60px;border:6px solid #fed8ce}.source a:focus{padding-bottom:4px;outline:2px solid #1e3650}main p img{max-width:100%;width:100%;height:100%}</style><meta name="generator" content="Gatsby 2.32.13"/><link rel="sitemap" type="application/xml" href="/sitemap.xml"/>
1<link rel="preconnect" href="https://www.google-analytics.com"/><link rel="dns-prefetch" href="https://www.google-analytics.com"/><link rel="alternate" type="application/rss+xml" href="/rss.xml"/><title data-react-helmet="true">A Guide to Accessible Interactive Components using React Libraries | a11y with Lindsey</title><meta data-react-helmet="true" name="viewport" content="width=device-width"/><meta data-react-helmet="true" name="description" content="Content Warning: This blog post contains gifs. I’ve wanted to write this blog post ever since I wrote  a11y and JS - A Seemingly…"/><meta data-react-helmet="true" name="keywords" content="accessibility, components, react, interactive"/><meta data-react-helmet="true" name="twitter:card" content="summary_large_image"/><meta data-react-helmet="true" name="twitter:site" content="@littlekope0903"/><meta data-react-helmet="true" name="twitter:creator" content="@littlekope0903"/><meta data-react-helmet="true" name="twitter:title" content="A Guide to Accessible Interactive Components using React Libraries"/><meta data-react-helmet="true" name="twitter:description" content="Content Warning: This blog post contains gifs. I’ve wanted to write this blog post ever since I wrote  a11y and JS - A Seemingly…"/><meta data-react-helmet="true" name="twitter:image" content="https://www.a11ywithlindsey.com/static/4f6d2f662ae1363d5d50e340950f7e42/f534f/react-a11y.png"/><meta data-react-helmet="true" name="og:url" content="https://www.a11ywithlindsey.com/blog/accessible-interactive-components-react"/><meta data-react-helmet="true" name="og:type" content="article"/><meta data-react-helmet="true" name="og:title" content="A Guide to Accessible Interactive Components using React Libraries"/><meta data-react-helmet="true" name="og:image" content="https://www.a11ywithlindsey.com/static/4f6d2f662ae1363d5d50e340950f7e42/f534f/react-a11y.png"/><link as="script" rel="preload" href="/component---src-templates-blog-post-js-7bb63e0dd5d181f92da8.js"/><link as="script" rel="preload" href="/app-c9c16c8991030db0db65.js"/><link as="script" rel="preload" href="/framework-25679e2f2e739b4a55ca.js"/><link as="script" rel="preload" href="/styles-407fe62976dc5310c43e.js"/><link as="script" rel="preload" href="/webpack-runtime-04ee07f01a3316bb5a37.js"/><link as="fetch" rel="preload" href="/page-data/blog/accessible-interactive-components-react/page-data.json" crossorigin="anonymous"/><link as="fetch" rel="preload" href="/page-data/sq/d/3649515864.json" crossorigin="anonymous"/><link as="fetch" rel="preload" href="/page-data/app-data.json" crossorigin="anonymous"/></head><body><div id="___gatsby"><div style="outline:none" tabindex="-1" id="gatsby-focus-wrapper"><div><a class="focusable visually-hidden" href="#main-content">Skip to main content</a><div class="content"><header><div class="header-wrapper"><div class="logo"><a style="color:white;text-decoration:none;border-bottom:none" href="/"><span class="visually-hidden"> <!-- -->a11y with Lindsey<!-- --> </span><img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMzEuNDIgNDguMjIiPgogIDxkZWZzPgogICAgPHN0eWxlPi5jbHMtMXtmb250LXNpemU6MTJweDtmb250LWZhbWlseTpQVE1vbm8tUmVndWxhciwgUFQgTW9ubzt9LmNscy0xLC5jbHMtMntmaWxsOiM2NDBkMjM7fTwvc3R5bGU+CiAgPC9kZWZzPgogIDx0aXRsZT5hMTF5IHdpdGggbGluZHNleTwvdGl0bGU+CiAgPGcgaWQ9IndpdGgtbGluZHNleSI+CiAgICA8dGV4dCBjbGFzcz0iY2xzLTEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDgxLjg0IDQwLjQpIj5saW5kc2V5PC90ZXh0PgogICAgPHRleHQgY2xhc3M9ImNscy0xIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzMC44NCA0MC40KSI+d2l0aDwvdGV4dD4KICA8L2c+CiAgPGcgaWQ9ImExMXktaWNvbi1ib2R5Ij4KICAgIDxwYXRoIGNsYXNzPSJjbHMtMiIgZD0iTTc0Ljc4LDI5LjQ5YTEyLjg5LDEyLjg5LDAsMCwwLDcuOTEtMTEuODgsMSwxLDAsMCwwLTIsMEExMC44OSwxMC44OSwwLDAsMSw3My4zNCwyNy45aDBsLS4wOSwwYTEwLjYzLDEwLjYzLDAsMCwxLTMuNC41NUExMC44OSwxMC44OSwwLDAsMSw1OC45MywxNy42MWExLDEsMCwxLDAtMiwwQTEyLjg5LDEyLjg5LDAsMCwwLDY4Ljg4LDMwLjQ1TDY2LjkzLDQ1LjlsLTQuNTQtLjMxYTEsMSwwLDAsMC0xLjA3LjkzLDEsMSwwLDAsMCwuOTMsMS4wNmw1LjQ4LjM5aC4wN2ExLDEsMCwwLDAsMS0uODhMNzAuOSwzMC40NGExMi43OCwxMi43OCwwLDAsMCwyLS4zM2w0LjI0LDE1LjA3LTQuMzEsMS40N2ExLDEsMCwwLDAtLjYyLDEuMjgsMSwxLDAsMCwwLC45NC42NywxLjI2LDEuMjYsMCwwLDAsLjMzLS4wNWw1LjItMS43OWExLDEsMCwwLDAsLjY0LTEuMjFaTTUyLjA5LDI2LjMzSDQ5LjMzczAsMCwwLS4wOFYxLjM4QTEsMSwwLDAsMCw0Ny44OC41TDQxLjM5LDMuODlBMSwxLDAsMCwwLDQxLDUuMjRhMSwxLDAsMCwwLDEuMzUuNDJsNS0yLjYzVjI2LjI1czAsLjA2LDAsLjA4SDQ0LjU5YTEsMSwwLDAsMCwwLDJoNy41YTEsMSwwLDAsMCwwLTJabS0xMywwSDM2LjM0YS4xOS4xOSwwLDAsMCwwLS4wOFYxLjM4QTEsMSwwLDAsMCwzNC45LjVMMjguNDIsMy44OWExLDEsMCwxLDAsLjkyLDEuNzdsNS0yLjYzVjI2LjI1czAsLjA2LDAsLjA4SDMxLjYxYTEsMSwwLDAsMCwwLDJoNy41YTEsMSwwLDAsMCwwLTJaTTIxLDE3LjMzbDIuNTctMy4yNUExLDEsMCwwLDAsMjIsMTIuODRMMTkuMzMsMTYuMmExMi42NCwxMi42NCwwLDAsMC01LjQ1LTEuN3YtNmExLDEsMCwxLDAtMiwwdjZBMTIuNzgsMTIuNzgsMCwwLDAsNiwxNi40NGwtMi44Ni0zLjZhMSwxLDAsMSwwLTEuNTYsMS4yNGwyLjgxLDMuNTVBMTIuODcsMTIuODcsMCwwLDAsMCwyNy4zM2ExLDEsMCwwLDAsMiwwLDEwLjg5LDEwLjg5LDAsMCwxLDIxLjc3LDAsMSwxLDAsMCwwLDIsMEExMi44NiwxMi44NiwwLDAsMCwyMSwxNy4zM1oiLz4KICA8L2c+CiAgPGcgaWQ9ImExMXktaWNvbi1leWViYWxscyI+CiAgICA8cGF0aCBjbGFzcz0iY2xzLTIiIGQ9Ik0xNi41MywyMy42OUEzLjY1LDMuNjUsMCwxLDEsMTIuODgsMjAsMy42NCwzLjY0LDAsMCwxLDE2LjUzLDIzLjY5WiIvPgogICAgPHBhdGggY2xhc3M9ImNscy0yIiBkPSJNNjkuODEsMjUuMzRhMy42NSwzLjY1LDAsMSwwLTMuNjQtMy42NEEzLjY1LDMuNjUsMCwwLDAsNjkuODEsMjUuMzRaIi8+CiAgPC9nPgo8L3N2Zz4K" alt=""/></a></div><nav class="menu-main"><ul class="menu"><li class="menu-item"><a href="/about">About</a></li><li class="menu-item"><a href="/blog">Blog</a></li><li><a href="https://egghead.io/instructors/lindsey-kopacz">Egghead</a></li></ul></nav></div></header><div><div class="content"><main id="main-content"><div class="content__heading"><div class="wrapper"><nav class="breadcrumb"><ol><li><a href="/">Home</a></li><li><a href="/blog">Blog</a></li><li>
1A Guide to Accessible Interactive Components using React Libraries</li></ol></nav><h1>A Guide to Accessible Interactive Components using React Libraries</h1></div></div><div class="content__body"><div class="wrapper"><p style="font-style:italic"> <!-- -->Note: this blog is an archive and not actively maintained. Some information may be out of date. If you&#x27;d like to see what I am working on or work with me in a consulting capacity, visit my website<!-- --> <a href="https://lindseykopacz.com/">lindseykopacz.com</a>.</p><time>May 29, 2020</time><p><em>Content Warning: This blog post contains gifs.</em></p><p>I’ve wanted to write this blog post ever since I wrote <a href="/blog/a11y-js-seemingly-unconventional-romance">a11y and JS - A Seemingly Unconventional Romance</a>. I love JavaScript, and my job is to code in React. I often observe folks (rightly) critique that React Apps are inaccessible. According to the <a href="https://webaim.org/projects/million/#frameworks">WebAIM Million report</a>, “the adoption of <!-- -->[React]<!-- --> corresponded with <!-- -->[5.7%]<!-- --> more accessibility errors than the average home page.”</p><p>WebAIM Million tests the sample using the WAVE stand-alone API. The WAVE tool catches all crawlable issues, which don’t involve a ton of interactivity. I’m not going to use this blog post to talk about those issues. If you’re interested in learning more about that, I’ve created an <a href="https://a11y-with-lindsey.ck.page/b4e437f629">Email Course</a> on the topic.</p><p>There are two points that I want to drive home about JavaScript frameworks:</p><blockquote><p>First, Front End JavaScript Frameworks render HTML. Second, JavaScript frameworks don’t produce inaccessible HTML. Web developers produce inaccessible HTML.</p></blockquote><p>Before you read this blog post, I’d recommend brushing up on how to fix some common HTML errors.</p><p>There are a decent amount of folks who know how to write accessible HTML using React. For those folks, I’ve created a reference for creating accessible interactive components. I want to remove the barrier and utilize well-supported libraries.</p><p>I write this under the assumption that you are familiar with React basics and the syntax of JSX. If you are not familiar with it, I suggest that you read through the following resources:</p><ol><li>Read through the <a href="https://reactjs.org/docs/getting-started.html">React docs</a> and play around with their <a href="https://reactjs.org/tutorial/tutorial.html">Tutorial</a>.</li><li>Have a basic familiarity with <a href="https://reactjs.org/docs/hooks-intro.html">React Hooks</a>, particularly useState and useEffect.</li><li>Understand using the <a href="https://reactjs.org/docs/jsx-in-depth.html#spread-attributes">spread operator</a> into a React Component.</li><li>Understand how the <a href="https://reactjs.org/docs/composition-vs-inheritance.html#containment">children prop</a> is used in React.</li><li>Understand the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map">map array method</a>.</li><li>Have a basic understanding of using <code class="language-text">npm</code> if you are using the command line. Tatiana Mac goes over a ton of the basics in her <a href="https://tatianamac.com/posts/beginner-eleventy-tutorial-partii/">eleventy series</a> if you want a great and funny intro to npm and the command line.</li></ol><p>I use CodeSandbox for my examples. It will help you play with the code without setting up an environment. I recommend forking my examples, playing with the styling, and manually test the components.</p><h2>React Hamburger Menu</h2><p><em>NOTE: This is using react-burger-menu version 2.6.13. I’ll do my best to keep this blog post up to date</em></p><p>One React library I like to use if I am in a pinch is the <a href="https://github.com/negomi/react-burger-menu">react-burger-menu</a>. Fun fact, my first contribution to open source was to this library! And of course, it was an accessibility improvement. Naturally 💁🏼‍♀️.</p><p>What are some features of an accessible hamburger menu?</p><ol><li>The hamburger button has a clear focus state.</li><li>The hamburger button has some text that labels it, even if it’s visually-hidden.</li><li>You cannot focus on the links inside the menu when the menu is closed. This experience happens very often when we have a menu that slides in.</li><li>The menu closes on the Escape keypress.</li><li>There is a clear way to close the menu, like a Close button inside the menu, or use the hamburger button to close it.</li></ol><p>Below I’ve created a quick demo of what we expect the functionality to be:</p><p>How to install:</p><ol><li>If you’re on your local: In your project directory, enter <code class="language-text">npm install react-burger-menu</code> in the command line. If you are in CodeSandbox, go to the “Dependencies” section and add <code class="language-text">react-burger-menu</code> as a dependency. There are many different hamburger menu animation styles you can use. I chose <code class="language-text">slide</code> for this example, but you can see how all the options animate in the <a href="https://negomi.github.io/react-burger-menu/">demo</a>.</li><li>In the <code class="language-text">src</code> directory, create a component called <code class="language-text">BurgerMenu.js</code>
1. Import the desired Menu <a href="https://github.com/negomi/react-burger-menu#animations">animation</a> and use that component to add links to your menu. I am using the <code class="language-text">noOverlay</code> prop on my Menu because I don’t like the look of overlays.</li></ol><div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">&#x27;react&#x27;</span>
2<span class="token keyword">import</span> <span class="token punctuation">{</span> slide <span class="token keyword">as</span> Menu <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#x27;react-burger-menu&#x27;</span>
3
4<span class="token keyword">const</span> <span class="token function-variable function">BurgerMenu</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
5  <span class="token keyword">return</span> <span class="token punctuation">(</span>
6    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Menu</span></span> <span class="token attr-name">noOverlay</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
7      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>menu-item<span class="token punctuation">&quot;</span></span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
8        Home
9      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
10      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>menu-item<span class="token punctuation">&quot;</span></span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/about<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
11        About
12      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
13      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>menu-item<span class="token punctuation">&quot;</span></span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/contact<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
14        Contact
15      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
16    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Menu</span></span><span class="token punctuation">&gt;</span></span>
17  <span class="token punctuation">)</span>
18<span class="token punctuation">}</span>
19
20<span class="token keyword">export</span> <span class="token keyword">default</span> BurgerMenu</code></pre></div><ol start="3"><li>Add it to the <code class="language-text">App.js</code> component.</li></ol><div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">
20import</span> React <span class="token keyword">from</span> <span class="token string">&#x27;react&#x27;</span>
21<span class="token keyword">import</span> <span class="token string">&#x27;./styles.css&#x27;</span>
22<span class="token keyword">import</span> BurgerMenu <span class="token keyword">from</span> <span class="token string">&#x27;./components/BurgerMenu&#x27;</span>
23
24<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
25  <span class="token keyword">return</span> <span class="token punctuation">(</span>
26    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;
26</span>App<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
27      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">BurgerMenu</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
28      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
29        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>header</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
30          </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span> <span class="token attr-name">style</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> margin<span class="token operator">:</span> <span class="token number">0</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Welcome to a website</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
31        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>header</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
32      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
33    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
34  <span class="token punctuation">)</span>
35<span class="token punctuation">}</span></code></pre></div><ol start="4"><li>Create a CSS file and import it into your react component. Add some CSS to position some of the elements.</li></ol><div class="gatsby-highlight has-highlighted-lines" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">&#x27;react&#x27;</span>
36<span class="token keyword">import</span> <span class="token punctuation">{</span> slide <span class="token keyword">as</span> Menu <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#x27;react-burger-menu&#x27;</span>
37
38<span class="gatsby-highlight-code-line"><span class="token keyword">import</span> <span class="token string">&#x27;./burger.css&#x27;</span></span></code></pre></div><div class="gatsby-highlight" data-language="css"><pre class="language-css"><code class="language-css"><span class="token selector">.bm-burger-button</span> <span class="token punctuation">{</span>
39  <span class="token property">position</span><span class="token punctuation">:</span> fixed<span class="token punctuation">;</span>
40  <span class="token property">width</span><span class="token punctuation">:</span> 36px<span class="token punctuation">;</span>
41  <span class="token property">height</span><span class="token punctuation">:</span> 30px<span class="token punctuation">;</span>
42  <span class="token property">left</span><span class="token punctuation">:</span> 36px<span class="token punctuation">;</span>
43  <span class="token property">top</span><span class="token punctuation">:</span> 36px<span class="token punctuation">;</span>
44<span class="token punctuation">}</span>
45
46<span class="token selector">.bm-burger-bars</span> <span class="token punctuation">{</span>
47  <span class="token property">background</span><span class="token punctuation">:</span> #000<span class="token punctuation">;</span>
48<span class="token punctuation">}</span>
49
50<span class="token selector">.bm-cross-button</span> <span class="token punctuation">{</span>
51  <span class="token property">height</span><span class="token punctuation">:</span> 24px<span class="token punctuation">;</span>
52  <span class="token property">width</span><span class="token punctuation">:</span> 24px<span class="token punctuation">;</span>
53<span class="token punctuation">}</span>
54
55<span class="token selector">.bm-cross</span> <span class="token punctuation">{</span>
56  <span class="token property">background</span><span class="token punctuation">:</span> #bdc3c7<span class="token punctuation">;</span>
57<span class="token punctuation">}</span>
58
59<span class="token selector">.bm-menu-wrap</span> <span class="token punctuation">{</span>
60  <span class="token property">position</span><span class="token punctuation">:</span> fixed<span class="token punctuation">;</span>
61  <span class="token property">height</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span>
62<span class="token punctuation">}</span>
63
64<span class="token selector">.bm-menu</span> <span class="token punctuation">{</span>
65  <span class="token property">background</span><span class="token punctuation">:</span> #373a47<span class="token punctuation">;</span>
66  <span class="token property">padding</span><span class="token punctuation">:</span> 2.5em 1.5em 0<span class="token punctuation">;</span>
67  <span class="token property">font-size</span><span class="token punctuation">:</span> 1.15em<span class="token punctuation">;</span>
68<span class="token punctuation">}</span>
69
70<span class="token selector">.bm-item-list</span> <span class="token punctuation">{</span>
71  <span class="token property">padding</span><span class="token punctuation">:</span> 0.8em<span class="token punctuation">;</span>
72<span class="token punctuation">}</span>
73
74<span class="token selector">.bm-item</span> <span class="token punctuation">{</span>
75  <span class="token property">display</span><span class="token punctuation">:</span> block<span class="token punctuation">;</span>
76  <span class="token property">color</span><span class="token punctuation">:</span> #bdc3c7<span class="token punctuation">;</span>
77<span class="token punctuation">}</span></code></pre></div><p>Even if a library says it’s accessible, I always do some manual testing with both my ke
77yboard and VoiceOver.</p><ol><li>Navigate through the component on a keyboard 👍</li></ol><p><img src="/52ee1232f7ac0e8463e3f815d25e7179/hamburger-keyboard-test.gif" alt="Opening and closing a hamburger bmenu using a hmaburger button and shifting focus to the links inside upon open."/></p><ol start="2"><li>Go through the hamburger menu using VoiceOver on Safari.</li></ol><video controls=""><source src="/ef347886c64714d82721cfebb46b17f6/hamburger-voiceover-test.mov" type="video/mp4"/></video><p>When we use Voiceover, we navigate to visually-hidden menu items. We can remedy this by adding aria-hidden and toggling it on menu open. Because the library doesn’t include this attribute, we will add an effect (<code class="language-text">useEffect</code>) on the parent component. I made that conclusion because I saw a note about properties in the <a href="https://github.com/negomi/react-burger-menu/#open-state">docs</a>. I’ll add that attribute to the appropriate element when the component has mounted. <em>Learn more about the <a href="https://reactjs.org/docs/hooks-effect.html">useEffect</a> hook</em>.</p><p>In the App.js parent component, we want to set the <code class="language-text">aria-hidden</code> attribute on the <code class="language-text">bm-menu-wrap</code> class:</p><div class="gatsby-highlight has-highlighted-lines" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
78<span class="gatsby-highlight-code-line">  React<span class="token punctuation">.</span><span class="token function">useEffect</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line">    <span class="token keyword">const</span> menuWrap <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">&#x27;.bm-menu-wrap&#x27;</span><span class="token punctuation">)</span></span><span class="gatsby-highlight-code-line">    <span class="token keyword">if</span> <span class="token punctuation">(</span>menuWrap<span class="token punctuation">)</span> <span class="token punctuation">{</span></span><span class="gatsby-highlight-code-line">      menuWrap<span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span><span class="token string">&#x27;aria-hidden&#x27;</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span></span><span class="gatsby-highlight-code-line">    <span class="token punctuation">}</span></span><span class="gatsby-highlight-code-line">  <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span></span>
79  <span class="token keyword">return</span> <span class="token punctuation">(</span>
80    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>App<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
81<span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">BurgerMenu</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text"></span>
82<span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
83<span class="token plain-text">        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>header</span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
84<span class="token plain-text">          </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span> <span class="token attr-name">style</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span> margin<span class="token operator">:</span> <span class="token number">0</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Welcome to a website</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
85<span class="token plain-text">        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>header</span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
86<span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
87<span class="token plain-text">    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
88  <span class="token punctuation">)</span>
89<span class="token punctuation">}</span></code></pre></div><p>
89In the <a href="https://github.com/negomi/react-burger-menu#state-change"><code class="language-text">react-burger-menu</code> docs</a>, I saw the <code class="language-text">onStateChange</code> prop. I am going to use that to toggle the <code class="language-text">aria-hidden</code> attribute dependent on the <code class="language-text">isOpen</code> state.</p><div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Menu</span></span> <span class="token attr-name">noOverlay</span> <span class="token attr-name">onStateChange</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>toggleMenu<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
90  </span><span class="token punctuation">{</span><span class="token comment">/* All the links */</span><span class="token punctuation">}</span><span class="token plain-text">
91</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Menu</span></span><span class="token punctuation">&gt;</span></span></code></pre></div><div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">const</span> <span class="token function-variable function">toggleMenu</span> <span class="token operator">=</span> <span class="token parameter">state</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
92  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span>
93<span class="token punctuation">}</span></code></pre></div><p>I prefer using destructuring to save a couple of lines of code. <em>Read more about destructuring assignment in the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">MDN Docs</a> (go to the “Unpacking fields from objects passed as function parameter” section).</em></p><div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">const</span> <span class="token function-variable function">toggleMenu</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> isOpen <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
94  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>isOpen<span class="token punctuation">)</span>
95<span class="token punctuation">}</span></code></pre></div><p>Then I use the <code class="language-text">isOpen</code> state to control the aria-hidden attribute value.</p><div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">const</span> <span class="token function-variable function">toggleMenu</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> isOpen <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
96  <span class="token keyword">const</span> menuWrap <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">&#x27;.bm-menu-wrap&#x27;</span><span class="token punctuation">)</span>
97  isOpen
98    <span class="token operator">?</span> menuWrap<span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span><span class="token string">&#x27;aria-hidden&#x27;</span><span class="token punctuation">,</span> <span class="token boolean">
98false</span><span class="token punctuation">)</span>
99    <span class="token operator">:</span> menuWrap<span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span><span class="token string">&#x27;aria-hidden&#x27;</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span>
100<span class="token punctuation">}</span></code></pre></div><p>Now we want to make sure that everything is working how we would expect on a screen reader.</p><p>On VoiceOver:</p><video controls=""><source src="/a6f339feafed5b16e178c6f9fca6f115/hamburger-voiceover-test-pass.mov" type="video/mp4"/></video><p>As a note:</p><p>As of this writing, the Menu doesn’t work if you add a menu using unordered lists of list items. I found why that is in the code, and I plan on making a PR when I finally have some spare time 😁. I prefer to write my menus using unordered lists. However, I wanted to be sure I made that disclaimer, so you didn’t have to go through the debugging pain that I did.</p><iframe src="https://codesandbox.io/embed/peaceful-dew-06mzr?fontsize=14&amp;hidenavigation=1&amp;theme=dark" style="width:100%;height:500px;border:0;border-radius:4px;overflow:hidden" title="a11y-react-burger-menu" allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr" sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"></iframe><h2>React Modal</h2><p><em>NOTE: This is using react-modal version 3.11.2. I’ll do my best to keep this blog post up to date</em></p><p>First, let’s go over what makes a modal accessible:</p><ul><li>Can’t focus inside of the modal until it’s open. If someone cannot see where their keyboard is focused, this is poor user experience.</li><li>When the modal is open, focus trapping occurs. Focus trapping means that when the blur event occurs on the last focusable element of the modal, we go to the top of the modal content. This process ensures focus won’t be anywhere else on the screen except inside the modal, and it won’t be “behind” it.</li><li>Closes on ESC keypress.</li><li>Upon close, focuses on the thing it was on last.</li></ul><p>How to install:</p><ol><li>If you’re on your local: In your project directory, enter <code class="language-text">npm install react-modal</code> in the command line. If you are in CodeSandbox, go to the “Dependencies” section and add <code class="language-text">react-modal</code> as a dependency.</li><li>In the <code class="language-text">src</code> directory, create a component called <code class="language-text">Modal.js</code>. Import <code class="language-text">ReactModal</code> and create the base of your function component.</li></ol><div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">&#x27;react&#x27;</span>
101<span class="token keyword">import</span> ReactModal <span class="token keyword">from</span> <span class="token string">&#x27;react-modal&#x27;</span>
102
103<span class="token keyword">const</span> <span class="token function-variable function">Modal</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
104  <span class="token keyword">return</span> <span class="token punctuation">(</span>
105    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">ReactModal</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
106      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Hey</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
107    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">
107ReactModal</span></span><span class="token punctuation">&gt;</span></span>
108  <span class="token punctuation">)</span>
109<span class="token punctuation">}</span>
110
111<span class="token keyword">export</span> <span class="token keyword">default</span> Modal</code></pre></div><ol start="3"><li>Attach the Modal to the root of your app. This line of code adds <code class="language-text">aria-hidden</code> on the <code class="language-text">#root</code> when the modal is open and removes it when it is closed. Adding <code class="language-text">aria-hidden</code> helps with focus trapping.</li></ol><div class="gatsby-highlight has-highlighted-lines" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">&#x27;react&#x27;</span>
112<span class="token keyword">import</span> ReactModal <span class="token keyword">from</span> <span class="token string">&#x27;react-modal&#x27;</span>
113
114<span class="gatsby-highlight-code-line">ReactModal<span class="token punctuation">.</span><span class="token function">setAppElement</span><span class="token punctuation">(</span><span class="token string">&#x27;#root&#x27;</span><span class="token punctuation">)</span></span>
115<span class="token keyword">const</span> <span class="token function-variable function">Modal</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
116  <span class="token keyword">return</span> <span class="token punctuation">(</span>
117    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">ReactModal</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
118<span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Hey</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
119<span class="token plain-text">    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">ReactModal</span></span><span class="token punctuation">&gt;</span></span>
120  <span class="token punctuation">)</span>
121<span class="token punctuation">}</span>
122
123<span class="token keyword">export</span> <span class="token keyword">default</span> Modal</code></pre></div><ol start="4"><li>Add the <code class="language-text">useState</code> hook to the Modal component. Use the hook to destructure an <code class="language-text">isOpen</code> variable and <code class="language-text">setIsOpen</code> function. The initial state of the modal being open is <code class="language-text">false</code> (because we don’t want to start with an open modal)</li></ol><div class="gatsby-highlight has-highlighted-lines" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="gatsby-highlight-code-line"><span class="token keyword">import</span> React<span class="token punctuation">,</span> <span class="token punctuation">{</span> useState <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#x27;react&#x27;</span></span><span class="token keyword">import</span> ReactModal <span class="token keyword">from</span> <span class="token string">&#x27;react-modal&#x27;</span>
124
125ReactModal<span class="token punctuation">.</span><span class="token function">setAppElement</span><span class="token punctuation">(</span><span class="token string">&#x27;#root&#x27;</span><span class="token punctuation">)</span>
126
127<span class="token keyword">const</span> <span class="token function-variable function">Modal</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
128<span class="gatsby-highlight-code-line">  <span class="token keyword">const</span> <span class="token punctuation">[</span>isOpen<span class="token punctuation">,</span> setIsOpen<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token boolean">
128false</span><span class="token punctuation">)</span></span>  <span class="token keyword">return</span> <span class="token punctuation">(</span>
129    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">ReactModal</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
130<span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Hey</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
131<span class="token plain-text">    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">ReactModal</span></span><span class="token punctuation">&gt;</span></span>
132  <span class="token punctuation">)</span>
133<span class="token punctuation">}</span>
134
135<span class="token keyword">export</span> <span class="token keyword">default</span> Modal</code></pre></div><ol start="5"><li>Next, we want to create two functions: <code class="language-text">openModal</code> and <code class="language-text">closeModal</code>. These functions set the <code class="language-text">isOpen</code> state.</li></ol><div class="gatsby-highlight has-highlighted-lines" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">const</span> <span class="token function-variable function">Modal</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
136  <span class="token keyword">const</span> <span class="token punctuation">[</span>isOpen<span class="token punctuation">,</span> setIsOpen<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span>
137
138<span class="gatsby-highlight-code-line">  <span class="token keyword">const</span> <span class="token function-variable function">openModal</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">setIsOpen</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span></span><span class="gatsby-highlight-code-line">  <span class="token keyword">const</span> <span class="token function-variable function">closeModal</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">setIsOpen</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span></span>
139  <span class="token keyword">return</span> <span class="token punctuation">(</span>
140    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">ReactModal</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
141<span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Hey</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
142<span class="token plain-text">    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">
142ReactModal</span></span><span class="token punctuation">&gt;</span></span>
143  <span class="token punctuation">)</span>
144<span class="token punctuation">}</span></code></pre></div><ol start="6"><li>Now we want to add some props to <code class="language-text">ReactModal</code> to make it work the way we want to. The most important ones we want to pass are <code class="language-text">isOpen</code> and <code class="language-text">onRequestClose</code>. <code class="language-text">isOpen</code> takes on the <code class="language-text">isOpen</code> state, and <code class="language-text">onRequestClose</code> should take the <code class="language-text">closeModal</code> function. The latter is crucial to ensure that the Modal closes on the Escape key.</li></ol><div class="gatsby-highlight has-highlighted-lines" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">const</span> <span class="token function-variable function">Modal</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
145  <span class="token keyword">const</span> <span class="token punctuation">[</span>isOpen<span class="token punctuation">,</span> setIsOpen<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span>
146
147  <span class="token keyword">const</span> <span class="token function-variable function">openModal</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">setIsOpen</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span>
148  <span class="token keyword">const</span> <span class="token function-variable function">closeModal</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">setIsOpen</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span>
149
150  <span class="token keyword">return</span> <span class="token punctuation">(</span>
151<span class="gatsby-highlight-code-line">    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">ReactModal</span></span> <span class="token attr-name">isOpen</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>isOpen<span class="token punctuation">}</span></span> <span class="token attr-name">onRequestClose</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>closeModal<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span></span><span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Hey</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
152<span class="token plain-text">    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">ReactModal</span></span><span class="token punctuation">&gt;</span></span>
153  <span class="token punctuation">)</span>
154<span class="token punctuation">}</span></code></pre></div><ol start="7"><li>This is great, but how are we supposed to open the Modal 😂? Let’s create a button to open the modal and pass the <code class="language-text">onClick</code> prop the <code class="language-text">openModal</code> function. I’ll place this button right before the ReactModal component. Because React must have a singular parent element, I am going to use a React Fragment. <em>Read more about <a href="https://reactjs.org/docs/fragments.html">Fragments</a></em>.</li></ol><div class="gatsby-highlight has-highlighted-lines" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">const</span> <span class="token function-variable function">
154Modal</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
155  <span class="token keyword">const</span> <span class="token punctuation">[</span>isOpen<span class="token punctuation">,</span> setIsOpen<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span>
156
157  <span class="token keyword">const</span> <span class="token function-variable function">openModal</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">setIsOpen</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span>
158  <span class="token keyword">const</span> <span class="token function-variable function">closeModal</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">setIsOpen</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span>
159
160  <span class="token keyword">return</span> <span class="token punctuation">(</span>
161    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
162<span class="gatsby-highlight-code-line"><span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>openModal<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Open Me!</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span></span><span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">ReactModal</span></span> <span class="token attr-name">isOpen</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>isOpen<span class="token punctuation">}</span></span> <span class="token attr-name">onRequestClose</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>closeModal<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
163<span class="token plain-text">        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Hey</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
164<span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">ReactModal</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
165<span class="token plain-text">    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span></span><span class="token punctuation">&gt;</span></span>
166  <span class="token punctuation">)</span>
167<span class="token punctuation">}</span></code></pre></div><ol start="8"><li>As it is, this Modal closes on the escape key. But I want to create a button that always inside the modal to close it to make it evident to non-keyboard users.</li></ol><div class="gatsby-highlight has-highlighted-lines" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">const</span> <span class="token function-variable function">
167Modal</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
168  <span class="token keyword">const</span> <span class="token punctuation">[</span>isOpen<span class="token punctuation">,</span> setIsOpen<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span>
169
170  <span class="token keyword">const</span> <span class="token function-variable function">openModal</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">setIsOpen</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span>
171  <span class="token keyword">const</span> <span class="token function-variable function">closeModal</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">setIsOpen</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span>
172
173  <span class="token keyword">return</span> <span class="token punctuation">(</span>
174    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
175<span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>openModal<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Open Me!</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
176<span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">ReactModal</span></span> <span class="token attr-name">isOpen</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>isOpen<span class="token punctuation">}</span></span> <span class="token attr-name">onRequestClose</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>closeModal<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
177<span class="gatsby-highlight-code-line"><span class="token plain-text">        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>closeModal<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Close</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span></span><span class="token plain-text">        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Hey</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
178<span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">
178ReactModal</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
179<span class="token plain-text">    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span></span><span class="token punctuation">&gt;</span></span>
180  <span class="token punctuation">)</span>
181<span class="token punctuation">}</span></code></pre></div><ol start="9"><li>Now that this is all configured, let’s make it dynamic with the children prop and a button text.</li></ol><div class="gatsby-highlight has-highlighted-lines" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="gatsby-highlight-code-line"><span class="token keyword">const</span> <span class="token function-variable function">Modal</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> children<span class="token punctuation">,</span> openButtonText <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span></span>  <span class="token keyword">const</span> <span class="token punctuation">[</span>isOpen<span class="token punctuation">,</span> setIsOpen<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span>
182
183  <span class="token keyword">const</span> <span class="token function-variable function">openModal</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">setIsOpen</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span>
184  <span class="token keyword">const</span> <span class="token function-variable function">closeModal</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">setIsOpen</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span>
185
186  <span class="token keyword">return</span> <span class="token punctuation">(</span>
187    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
188<span class="gatsby-highlight-code-line"><span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>openModal<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>openButtonText<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span></span><span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">ReactModal</span></span> <span class="token attr-name">isOpen</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>isOpen<span class="token punctuation">}</span></span> <span class="token attr-name">onRequestClose</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>closeModal<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
189<span class="token plain-text">        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>closeModal<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Close</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
190<span class="gatsby-highlight-code-line"><span class="token plain-text">        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>children<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span></span><span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">
190ReactModal</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
191<span class="token plain-text">    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
192<span class="token plain-text">  )</span>
193<span class="token plain-text">}</span></code></pre></div><ol start="10"><li>And on our App component, let’s add the Modal component and the props!</li></ol><div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">&#x27;react&#x27;</span>
194<span class="token keyword">import</span> Modal <span class="token keyword">from</span> <span class="token string">&#x27;./components/Modal&#x27;</span>
195<span class="token keyword">import</span> <span class="token string">&#x27;./styles.css&#x27;</span>
196
197<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
198  <span class="token keyword">return</span> <span class="token punctuation">(</span>
199    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>App<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
200      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Hello CodeSandbox</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
201      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Start editing to see some magic happen!</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
202      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Modal</span></span> <span class="token attr-name">openButtonText</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>Sign up!<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
203        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>form</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
204          </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
205            </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>label</span> <span class="token attr-name">for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>email-input<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Email:</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>label</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
206            </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>email<span class="token punctuation">&quot;</span></span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>email-input<span class="token punctuation">&quot;</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>email<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
207          </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
208          </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
209            </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>label</span> <span class="token attr-name">for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>password-input<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Password:</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>label</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
210            </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>password<span class="token punctuation">&quot;</span></span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>password-input<span class="token punctuation">&quot;</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>password<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
211          </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
212        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>form</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
213      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">
213Modal</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
214    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
215  <span class="token punctuation">)</span>
216<span class="token punctuation">}</span></code></pre></div><p>Now we manually test as always.</p><p><img src="/686d426cd62cda494b0327827f3abc5e/accessible-modal.gif" alt="Focusing on a Signup! button. Focus shifts inside of the modal where there&#x27;s an email and password form and stays inside."/></p><video controls=""><source src="/ac02ffca36957575dcb19ebb405cb50c/voiceover-modal.mov" type="video/mp4"/></video><iframe src="https://codesandbox.io/embed/a11y-react-modal-k4p4q?fontsize=14&amp;hidenavigation=1&amp;theme=dark" style="width:100%;height:500px;border:0;border-radius:4px;overflow:hidden" title="a11y-react-modal" allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr" sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"></iframe><blockquote><p>Note: I wanted to do the “harder” ones first. The reason I consider the previous two harder is because they take a smidge of configuration, and you have to know where the loopholes are. The next two sections will be less complicated as they need no setup out of the box to be accessible. All you need to do is follow the documentation. I’ll pretty much be walking you through my understanding of the docs and what the standard features are.</p></blockquote><h2>React Accordion</h2><p><em>
216NOTE: This is using react-accessible-accordion version 3.0.1. I’ll do my best to keep this blog post up to date</em></p><p>To get up an accessible accordion, I use <code class="language-text">react-accessible-accordion</code>. Here are the features of an accessible accordion:</p><ul><li>The Accordion Headings are buttons that open and close on <code class="language-text">space</code> or <code class="language-text">enter</code></li><li>Pressing the tab key moves to the next focusable element.</li><li>Cannot access the inside of a closed accordion with the keyboard.</li><li>Up &amp; Down Arrow goes to the Previous &amp; Next Accordion header when focused on another accordion header.</li></ul><p>How to install:</p><ol><li>If you’re on your local: In your project directory, enter <code class="language-text">npm install react-accessible-accordion</code> in the command line. If you are in CodeSandbox, go to the “Dependencies” section and add <code class="language-text">react-accessible-accordion</code> as a dependency.</li><li>In the <code class="language-text">src</code> directory, create a component called <code class="language-text">Accordion.js</code>. We’ll be importing a bunch of components from the library, as shown below.</li></ol><div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">&#x27;react&#x27;</span>
217<span class="token keyword">import</span> <span class="token punctuation">{</span>
218  Accordion <span class="token keyword">as</span> AccordionComponent<span class="token punctuation">,</span>
219  AccordionItem<span class="token punctuation">,</span>
220  AccordionItemHeading<span class="token punctuation">,</span>
221  AccordionItemButton<span class="token punctuation">,</span>
222  AccordionItemPanel<span class="token punctuation">,</span>
223<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#x27;react-accessible-accordion&#x27;</span></code></pre></div><ol start="3"><li>Create the base of your function component.</li></ol><div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">&#x27;react&#x27;</span>
224<span class="token keyword">import</span> <span class="token punctuation">{</span>
225  Accordion <span class="token keyword">as</span> AccordionComponent<span class="token punctuation">,</span>
226  AccordionItem<span class="token punctuation">,</span>
227  AccordionItemHeading<span class="token punctuation">,</span>
228  AccordionItemButton<span class="token punctuation">,</span>
229  AccordionItemPanel<span class="token punctuation">,</span>
230<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#x27;react-accessible-accordion&#x27;</span>
231
232<span class="token keyword">const</span> <span class="token function-variable function">Accordion</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>
233  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">AccordionComponent</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
234    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">AccordionItem</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
235      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">AccordionItemHeading</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
236        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">AccordionItemButton</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Heading 1</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">AccordionItemButton</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
237      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">AccordionItemHeading</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
238      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">AccordionItemPanel</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
239        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean dapibus
240        malesuada feugiat. Etiam commodo purus in ex pharetra vulputate. Nam
241        mattis, lacus quis tristique dapibus, ante dolor vehicula est, sit amet
242        feugiat risus neque ac odio. Pellentesque et vulputate magna. Nam
243        suscipit condimentum dictum.
244      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">AccordionItemPanel</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
245    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">AccordionItem</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
246    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">AccordionItem</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
247      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">AccordionItemHeading</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
248        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">AccordionItemButton</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Heading 2</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">AccordionItemButton</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
249      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">AccordionItemHeading</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
250      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">AccordionItemPanel</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
251        Fusce dapibus, libero sed finibus placerat, nunc augue pulvinar libero,
252        in vehicula nisl nisi ac nunc. Vestibulum convallis magna id lacus
253        rhoncus, in efficitur ante vehicula. Donec vel finibus ipsum, non
254        gravida orci. Maecenas ornare urna vitae porta dignissim. In hac
255        habitasse platea dictumst.
256      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">AccordionItemPanel</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
257    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">AccordionItem</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
258    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">AccordionItem</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
259      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">AccordionItemHeading</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
260        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">AccordionItemButton</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Heading 3</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">AccordionItemButton</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
261      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">AccordionItemHeading</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
262      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">AccordionItemPanel</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
263        Vestibulum id volutpat ante, pharetra pharetra nunc. In suscipit turpis
264        vel molestie consectetur. Duis eu congue massa. Duis eu ligula dictum,
265        consectetur elit vitae, tristique nibh.
266      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">AccordionItemPanel</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
267    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">AccordionItem</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
268  </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">AccordionComponent</span></span><span class="token punctuation">&gt;</span></span>
269<span class="token punctuation">)</span>
270
271<span class="token keyword">export</span> <span class="token keyword">default</span> Accordion</code></pre></div><p>Now let’s add it to the App component.</p><div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">
271import</span> React <span class="token keyword">from</span> <span class="token string">&#x27;react&#x27;</span>
272<span class="token keyword">import</span> <span class="token string">&#x27;./styles.css&#x27;</span>
273
274<span class="token keyword">import</span> Accordion <span class="token keyword">from</span> <span class="token string">&#x27;./components/Accordion&#x27;</span>
275
276<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
277  <span class="token keyword">return</span> <span class="token punctuation">(</span>
278    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>App<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
279      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Hello CodeSandbox</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
280      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Start editing to see some magic happen!</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
281      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Accordion</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
282    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
283  <span class="token punctuation">)</span>
284<span class="token punctuation">}</span></code></pre></div><p>I want to make this Accordion more reusable. Instead of hardcoding the accordion headings and content, I want to pass a data array using a prop. Then we can map through the data and make our code 
284cleaner.</p><div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> data <span class="token operator">=</span> <span class="token punctuation">[</span>
285  <span class="token punctuation">{</span>
286    heading<span class="token operator">:</span> <span class="token string">&#x27;Heading 1&#x27;</span><span class="token punctuation">,</span>
287    body<span class="token operator">:</span>
288      <span class="token string">&#x27;Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean dapibus malesuada feugiat. Etiam commodo purus in ex pharetra vulputate. Nam mattis, lacus quis tristique dapibus, ante dolor vehicula est, sit amet feugiat risus neque ac odio. Pellentesque et vulputate magna. Nam suscipit condimentum dictum. &#x27;</span><span class="token punctuation">,</span>
289  <span class="token punctuation">}</span><span class="token punctuation">,</span>
290  <span class="token punctuation">{</span>
291    heading<span class="token operator">:</span> <span class="token string">&#x27;Heading 2&#x27;</span><span class="token punctuation">,</span>
292    body<span class="token operator">:</span>
293      <span class="token string">&#x27;Fusce dapibus, libero sed finibus placerat, nunc augue pulvinar libero, in vehicula nisl nisi ac nunc. Vestibulum convallis magna id lacus rhoncus, in efficitur ante vehicula. Donec vel finibus ipsum, non gravida orci. Maecenas ornare urna vitae porta dignissim. In hac habitasse platea dictumst. &#x27;</span><span class="token punctuation">,</span>
294  <span class="token punctuation">}</span><span class="token punctuation">,</span>
295  <span class="token punctuation">{</span>
296    heading<span class="token operator">:</span> <span class="token string">&#x27;Heading 3&#x27;</span><span class="token punctuation">,</span>
297    body<span class="token operator">:</span>
298      <span class="token string">&#x27;Vestibulum id volutpat ante, pharetra pharetra nunc. In suscipit turpis vel molestie consectetur. Duis eu congue massa. Duis eu ligula dictum, consectetur elit vitae, tristique nibh.&#x27;</span><span class="token punctuation">,</span>
299  <span class="token punctuation">}</span><span class="token punctuation">,</span>
300<span class="token punctuation">]</span></code></pre></div><p>Now to add that data array as a prop on our Accordion component.</p><div class="gatsby-highlight has-highlighted-lines" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
301  <span class="token keyword">return</span> <span class="token punctuation">(</span>
302    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>App<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
303<span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Hello CodeSandbox</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
304<span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Start editing to see some magic happen!</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
305<span class="gatsby-highlight-code-line"><span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Accordion</span></span> <span class="token attr-name">data</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>data<span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text"></span></span><span class="token plain-text">    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
306  <span class="token punctuation">)</span>
307<span class="token punctuation">}</span></code></pre></div><p>And then refactor our Accordion to map through the data.</p><div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">const</span> <span class="token function-variable function">Accordion</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> data <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>
308  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">AccordionComponent</span></span> <span class="token attr-name">allowZeroExpanded</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>allowZeroExpanded<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
309    </span><span class="token punctuation">{</span>data<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> heading<span class="token punctuation">,</span> body <span class="token punctuation">}</span><span class="token punctuation">,</span> i</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>
310      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">AccordionItem</span></span> <span class="token attr-name">key</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>i<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
311        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">AccordionItemHeading</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
312          </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">AccordionItemButton</span></span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>heading<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">AccordionItemButton</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
313        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">AccordionItemHeading</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
314        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">AccordionItemPanel</span></span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>body<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">AccordionItemPanel</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
315      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">AccordionItem</span></span><span class="token punctuation">&gt;</span></span>
316    <span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token plain-text">
317  </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">AccordionComponent</span></span><span class="token punctuation">&gt;</span></span>
318<span class="token punctuation">)</span></code></pre></div><p>And that’s all you need to do. Let’s test to make sure all the features are working.</p><p>On a keyboard:</p><p><img src="/ad99fc869fc24a4b2e29628147a6cb93/keyboard-accordion.gif" alt="Demonstration using the tab key to open and close the accordion"/></p><p>And on voiceover:</p><video controls=""><source src="/c219516ac5b9c5c1901d575128410525/accordion-voiceover.mov" type="video/mp4"/></video><p>A few cleanup items and personal preferences that have nothing to do with accessibility:</p><p>When I have more than one prop, I like to create an object of props and spread them into the component. I want to set <code class="language-text">allowZeroExpanded</code> to <code class="language-text">true</code>. So I will add the <code class="language-text">data</code> array as a property to an object we’ll call accordionProps. We will also add an <code class="language-text">allowZeroExpanded</code> property with a value of true.</p><div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> accordionProps <span class="token operator">=</span> <span class="token punctuation">{</span>
319  data<span class="token operator">:</span> <span class="token punctuation">[</span>
320    <span class="token punctuation">{</span>
321      heading<span class="token operator">:</span> <span class="token string">&#x27;Heading 1&#x27;</span><span class="token punctuation">,</span>
322      body<span class="token operator">:</span>
323        <span class="token string">&#x27;Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean dapibus malesuada feugiat. Etiam commodo purus in ex pharetra vulputate. Nam mattis, lacus quis tristique dapibus, ante dolor vehicula est, sit amet feugiat risus neque ac odio. Pellentesque et vulputate magna. Nam suscipit condimentum dictum. &#x27;</span><span class="token punctuation">,</span>
324    <span class="token punctuation">}</span><span class="token punctuation">,</span>
325    <span class="token punctuation">{</span>
326      heading<span class="token operator">:</span> <span class="token string">&#x27;Heading 2&#x27;</span><span class="token punctuation">,</span>
327      body<span class="token operator">:</span>
328        <span class="token string">&#x27;Fusce dapibus, libero sed finibus placerat, nunc augue pulvinar libero, in vehicula nisl nisi ac nunc. Vestibulum convallis magna id lacus rhoncus, in efficitur ante vehicula. Donec vel finibus ipsum, non gravida orci. Maecenas ornare urna vitae porta dignissim. In hac habitasse platea dictumst. &#x27;</span><span class="token punctuation">,</span>
329    <span class="token punctuation">}</span><span class="token punctuation">,</span>
330    <span class="token punctuation">{</span>
331      heading<span class="token operator">:</span> <span class="token string">&#x27;Heading 3&#x27;</span><span class="token punctuation">,</span>
332      body<span class="token operator">:</span>
333        <span class="token string">&#x27;Vestibulum id volutpat ante, pharetra pharetra nunc. In suscipit turpis vel molestie consectetur. Duis eu congue massa. Duis eu ligula dictum, consectetur elit vitae, tristique nibh.&#x27;</span><span class="token punctuation">,</span>
334    <span class="token punctuation">}</span><span class="token punctuation">,</span>
335  <span class="token punctuation">]</span><span class="token punctuation">,</span>
336  allowZeroExpanded<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
337<span class="token punctuation">}</span></code></pre></div><p>Then we can add them in using the spread operator.</p><div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Accordion</span></span> <span class="token spread"><span class="token punctuation">{</span><span class="token operator">...</span>accordionProps<span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span></code></pre></div><p>would be the same as</p><div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Accordion</span></span>
338  <span class="token attr-name">data</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>accordionProps<span class="token punctuation">.</span>data<span class="token punctuation">}</span></span>
339  <span class="token attr-name">allowZeroExpanded</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>accordionProps<span class="token punctuation">.</span>allowZeroExpanded<span class="token punctuation">}</span></span>
340<span class="token punctuation">/&gt;</span></span></code></pre></div><iframe src="https://codesandbox.io/embed/a11y-accordion-react-8524z?fontsize=14&amp;hidenavigation=1&amp;theme=dark" style="width:100%;height:500px;border:0;border-radius:4px;overflow:hidden" title="a11y-accordion-react" allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr" sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"></iframe><h2>React Tabs</h2><p><em>NOTE: This is using react-tabs version 3.1.0. I’ll do my best to keep this blog post up to date</em></p><p>To get up an accessible tablist, I use <code class="language-text">react-tabs</code>. Here are the features of an accessible tablist:</p><ul><li>It can only access the content of the tab that’s visible.</li><li>Right arrow and left arrow keys switch the tab.</li></ul><p>Getting started:</p><ol><li>If you’re on your local: In your project directory, enter <code class="language-text">npm install react-tabs</code> in the command line. If you are in CodeSandbox, go to the “Dependencies” section and add <code class="language-text">react-tabs</code> as a dependency.</li><li>In the <code class="language-text">src</code> directory, create a component called <code class="language-text">Tabs.js</code>. We’ll be importing a bunch of components from the library, as shown below.</li></ol><div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">
340import</span> React <span class="token keyword">from</span> <span class="token string">&#x27;react&#x27;</span>
341<span class="token keyword">import</span> <span class="token punctuation">{</span> Tab<span class="token punctuation">,</span> Tabs <span class="token keyword">as</span> TabsComponent<span class="token punctuation">,</span> TabList<span class="token punctuation">,</span> TabPanel <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&#x27;react-tabs&#x27;</span></code></pre></div><ol><li>Create the base of your function component.</li></ol><div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">const</span> <span class="token function-variable function">Tabs</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>
342  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">TabsComponent</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
343    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">TabList</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
344      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Tab</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Item 1</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Tab</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
345      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Tab</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Item 2</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Tab</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
346      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Tab</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Item 3</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Tab</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
347    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">TabList</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
348    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">TabPanel</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Hi from item 1</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">TabPanel</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
349    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">TabPanel</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Hi from item 2</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">TabPanel</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
350    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">TabPanel</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Hi from item 3</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">TabPanel</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
351  </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">TabsComponent</span></span><span class="token punctuation">&gt;</span></span>
352<span class="token punctuation">)</span>
353
354<span class="token keyword">export</span> <span class="token keyword">default</span> Tabs</code></pre></div><p>Now let’s add it to the App component.</p><div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">
354import</span> React <span class="token keyword">from</span> <span class="token string">&#x27;react&#x27;</span>
355<span class="token keyword">import</span> <span class="token string">&#x27;./styles.css&#x27;</span>
356
357<span class="token keyword">import</span> Tabs <span class="token keyword">from</span> <span class="token string">&#x27;./components/Tabs&#x27;</span>
358
359<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
360  <span class="token keyword">return</span> <span class="token punctuation">(</span>
361    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>App<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
362      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Hello CodeSandbox</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
363      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Start editing to see some magic happen!</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
364      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Tabs</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
365    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
366  <span class="token punctuation">)</span>
367<span class="token punctuation">}</span></code></pre></div><p>We are going to do the same thing that we did for the Accordion component, and add a data prop and make that an array. We will map through to make all the tabs and panels.</p><div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js"><span class="token keyword">const</span> data <span class="token operator">=</span> <span class="token punctuation">[</span>
368  <span class="token punctuation">{</span>
369    heading<span class="token operator">:</span> <span class="token string">&#x27;Item 1&#x27;</span><span class="token punctuation">,</span>
370    body<span class="token operator">:</span> <span class="token string">&#x27;Hi from item 1&#x27;</span><span class="token punctuation">,</span>
371  <span class="token punctuation">}</span><span class="token punctuation">,</span>
372  <span class="token punctuation">{</span>
373    heading<span class="token operator">:</span> <span class="token string">&#x27;Item 2&#x27;</span><span class="token punctuation">,</span>
374    body<span class="token operator">:</span> <span class="token string">&#x27;Hi from item 2&#x27;</span><span class="token punctuation">,</span>
375  <span class="token punctuation">}</span><span class="token punctuation">,</span>
376  <span class="token punctuation">{</span>
377    heading<span class="token operator">:</span> <span class="token string">&#x27;Item 3&#x27;</span><span class="token punctuation">,</span>
378    body<span class="token operator">:</span> <span class="token string">&#x27;Hi from item 3&#x27;</span><span class="token punctuation">,</span>
379  <span class="token punctuation">}</span><span class="token punctuation">,</span>
380<span class="token punctuation">]</span></code></pre></div><p>Now to add that data array as a prop on our Tabs component.</p><div class="gatsby-highlight has-highlighted-lines" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
381  <span class="token keyword">return</span> <span class="token punctuation">(</span>
382    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>App<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
383<span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Hello CodeSandbox</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
384<span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Start editing to see some magic happen!</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">&gt;</span></span><span class="token plain-text"></span>
385<span class="gatsby-highlight-code-line"><span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Tabs</span></span> <span class="token attr-name">data</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>data<span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text"></span></span><span class="token plain-text">    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
386  <span class="token punctuation">)</span>
387<span class="token punctuation">}</span></code></pre></div><p>And refactoring the Tabs component using the map method.</p><div class="gatsby-highlight" data-language="jsx"><pre class="language-jsx"><code class="language-jsx"><span class="token keyword">const</span> <span class="token function-variable function">Tabs</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> data <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>
388  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">TabsComponent</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
389    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">TabList</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
390      </span><span class="token punctuation">{</span>data<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> heading <span class="token punctuation">}</span><span class="token punctuation">,</span> i</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>
391        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Tab</span></span> <span class="token attr-name">key</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>i<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>heading<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Tab</span></span><span class="token punctuation">&gt;</span></span>
392      <span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token plain-text">
393    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">TabList</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
394    </span><span class="token punctuation">{</span>data<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> body <span class="token punctuation">}</span><span class="token punctuation">,</span> i</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>
395      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">TabPanel</span></span> <span class="token attr-name">key</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>i<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>body<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">TabPanel</span></span><span class="token punctuation">&gt;</span></span>
396    <span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token plain-text">
397  </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">TabsComponent</span></span><span class="token punctuation">&gt;</span></span>
398<span class="token punctuation">)</span></code></pre></div><p>Then, as always, we manually test!</p><p>On a keyboard:</p><p><img src="/9d94fb26fe0bdbf8e68d59c760a841a3/keyboard-tabs.gif" alt="Focus shifting other tabs using the keyboard."/></p><p>On VoiceOver:</p><video controls=""><source src="/0a11e68fcc1da3c0ca582ab951914991/voiceover-tabs.mov" type="video/mp4"/></video><iframe src="https://codesandbox.io/embed/a11y-tabs-s205s?fontsize=14&amp;hidenavigation=1&amp;theme=dark" style="width:100%;height:500px;border:0;border-radius:4px;overflow:hidden" title="a11y-tabs" allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr" sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"></iframe><h2>Sources &amp; React/JavaScript Resources</h2><ul><li><a href="https://www.a11ymatters.com/pattern/mobile-nav/">a11y Matters - mobile navigation</a></li><li><a href="https://www.w3.org/TR/wai-aria-practices/examples/dialog-modal/dialog.html">W3C-WAI Modal Features</a></li><li><a href="https://www.w3.org/TR/wai-aria-practices/examples/accordion/accordion.html">W3C-WAI Accordion Features</a></li><li><a href="https://www.w3.org/TR/wai-aria-practices/examples/tabs/tabs-1/tabs.html">W3C-WAI Tabs Features</a></li></ul><p>All the React/JavaScript resources mentioned</p><ul><li><a href="https://reactjs.org/docs/getting-started.html">React docs</a></li><li><a href="https://reactjs.org/tutorial/tutorial.html">
398React Tutorial</a>.</li><li><a href="https://reactjs.org/docs/hooks-intro.html">React Hooks</a>.</li><li><a href="https://reactjs.org/docs/jsx-in-depth.html#spread-attributes">Using the Spread operator with Props</a></li><li><a href="https://reactjs.org/docs/composition-vs-inheritance.html#containment">The children prop in React</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map">.map() array method</a></li><li><a href="https://reactjs.org/docs/hooks-effect.html">useEffect hook</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">MDN Docs - Destructuring assignment</a></li><li><a href="https://reactjs.org/docs/fragments.html">React Fragments</a></li></ul><p>Other Resources:</p><ul><li><a href="https://tatianamac.com/posts/beginner-eleventy-tutorial-partii/">Tatiana Mac’s NPM helper - Eleventy series</a></li></ul><h2>Conclusion</h2><p>I wrote this blog post because I wanted to help React developers who care about creating inclusive apps, but get stuck overthinking accessible interactivity. I wanted to make sure there was an quick reference for some of the most common interactive components that are often not accessible. I hope this helps you!</p><p>If you liked this blog post and are interested in learning more about accessibility, take my <a href="https://a11y-with-lindsey.ck.page/b4e437f629">10 days of a11y</a> free email course.</p><p>Cheers! Have a great week!</p><div class="featured-image-block"><div class="featured-image-block__wrapper"><div class="featured-image-block__img"><img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcgSlBFRyB2ODApLCBxdWFsaXR5ID0gNzUK/9sAQwAIBgYHBgUIBwcHCQkICgwUDQwLCwwZEhMPFB0aHx4dGhwcICQuJyAiLCMcHCg3KSwwMTQ0NB8nOT04MjwuMzQy/9sAQwEJCQkMCwwYDQ0YMiEcITIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy/8AAEQgAZABkAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A9yxis3W7k22nSOGAOMCtgqDXMeKSTFHEejc0Ac1YGSUPK5yG6e9WGiUnoKcMQwKg4wKYJcmgCu1ihbp1qNtMGMgVeD5Iq1E470AY8VybV1t7o7omOEc9VP8AhWjbSmC42g8A8D0o1G0jubZhtByKwYL9ljKyt++t2CMT3X+E0Aeo6XdCe3AznHI+laFcZ4Z1JZXKZwVOcfz/AMa7LNAC0UUUAFFGaKAErlfFP/H7br7f1rq65TxOoOqWWehHP4ZoAx5kPFVwhBzVbUtfgtZzHLHIq9m28UsF/FcIHjcMp7igC0g55qzGuTVUOMZzQ19HCu52AA7mgDVWE456GuS8R2DWVyL5FzCwKSr6qf8ADrWnF4stDKIow8p/2VzWnK8OpWbI6YDDlTQBx2j6qbHVIpN+cHDf7Q/+uK9ls51uLZXU5GOD7V88akkulao9uxP7s/IfVe1ex+BtRN7o8eeSq4oA6uiiigAopaKAILu4W0tJrhlLLEhcgdSBXBazrF7rD209nZmOJAx84xmRQCCPmIIAru/PSRCGA5GCDWIsENhY3+mqQsb7pbcH+6eoH0P6EUAeOatrF/mUt5MiRnDMkZAH1JJqjp3iPypRuIRSefT866PW7CNkeBFkTfw4Vcq3ofrXIXWktawSP5LBFGTuoA9Di1C3NmZ2uYVjxneZBiuW1PxJG7lLeNpU7ORgH6ZpkPgR5tE+0I3+liPzNnqeuK0NQ0I6jaw6pYorRyoHKdCp70AYsXiKWCZVaKKPv87H+grprLxU9tsNxBI0bDIeHEi479Dn9Kw00b7VdLJd2s7sAB8o9K6yDSbS3tXumgEGxSxOeeByTQBzXim6stZmtLzTZ0mT/VynoVJ+7kHnnmvRvh3BLbadKkqspQ7RuGM/4/WuZ0Dwfb2ejC4u13Xd2yyMjdE5yBiu60JpRYl5GPzN8oPpQB0Ik96eJBWf5tHnUAaHmiis7z6KAKQnYVHdKl9bPHLGXCqWBGQVOOoI5H1rYfTI2+6cVWk0plBIII9M0AeeXdtchiIr1yOwlRWx+IANY76dLeXUcd1cNMgYNsVQq/U46/ia2NauGs3dB1LYBPQVSimnSIujKWbHJFAHU6fGAhUYPGKwLq0udKuJzZy+XBK5bypE3JuPXGCCp/T2pV1OeOEiMr5xHGc4BqUHUryzaO7mjZDz8qYoApJdakz8W9t9fPI/TbW1ZWNxehDfzx+SCD5ESkBiOm5ieR7YH41huzWsmQ2QOxrX07U/PRShyDQBv3Fu08lvg4WNize4q+sgVQoGAOAKzWmbzEO/ChMFfUnvTvtIx1oA0DLTTNVA3I9aYbketAGh51FZhuuetFAHSC8mH8efqBVeaeaQENKSD2HAqEvTGegDntfsA4LMAVcYPsa4S3+2WFyImkH2RmIYydIz2Oewr1K5VZ4mjfof0rjdQsfJlkjkHyuMEj+dAEVva3pdStrBIGOAyvx0zWkTqMNsXcQxgZAVRuYkHHSsCBJLJPLXIUHIMcrJn8BWzp6SynLKEQ8nByT+NAHNvputXcpuNQnwpb5IU4H44rrLK3is4FAwFQcmrckQwCQAB0rhvHuqzwRR6dAdiOA8pB5I7D9M0AdTJrVurM0k8aD/AGmAqrL4r0uH71/D/wABbP8AKvIQdyFCcN1B/pUIwDyDQB6w/jrSUztuGcgZ+VD/AFqjN8R7Ff8AVW9w598D+tecBo/7jf8AfX/1qPMXtEPxJoA7pviQ275dO495f/rUVwvmD/nkn6/40UAfTJehUkl+4pPv2qroOt6XrEbCAhrhPvRuf1HqKmvr2WLKgYAoAWcQ2yF55QT/AHV/xrjbvVEvdbu7VlVUjjj
398ZAB67sn36D9KvXVxJMTuJNcXql1/Z/i+1lY4juIfKb654/pQB1EIiRssAT2zWrDcx7ACVA9Kx4V81eKtR27qQcUAaOfPkB/gHQetULnwrpPim+vLe6aWC9hSN0miPVGBABU8HBVvTrWhH8qZrL0O9ZviVfWwb7tgoI9wwP/s9AHI6z8Kda07dLazW93bD/lopKsPqp6fgTXK3HhvWYAWksJCB1KEP/ImvpW8QLplzvPWJuPwrxFfETovlO3BABP8AX+VAHBYor3XT9H0Lxb4et5tR0+JrlQUaeP5HJHqRjPGOteZeNfCzeHNVxCh+wTDML5zyByD75oA5iijFFAHR2uo3VhfQ3ltIY5lbIYV7rbTG+soJJ1UmSMM2B6iiigChe2MCAlVIP1ry7x/GqLbSLncshAP4f/WoooA3fD1xJNawM5ySozXYLGpjGaKKAHwxqTz61yWlkw/GC72HG62OfyX/AAoooA9Eu5GeymDHP7tv5V86XJOQfUUUUAeq/DSRpPDsoY5xMcfkKt+P7WK58IXhlXJiAkQ/3WB/wJH40UUAeG0UUUAf/9k=" width="100" height="100" alt=""/></div><div class="featured-image-block__content"><h2 style="margin:0">About Lindsey </h2><p>Lindsey is an accessibility expert, JavaScript lover, and Front End Developer who&#x27;s passionate about inclusivity both inside and outside the web. Read more about her on the<!-- --> <a href="/about">About Page</a></p></div></div></div></div></div></main></div></div><footer><div class="footer-wrapper"><nav class="footer-menu" style="align-self:flex-start"><ul class="menu"><li class="menu-item"><a href="/about">About</a></li><li class="menu-item"><a href="/blog">Blog</a></li><li><a href="https://egghead.io/instructors/lindsey-kopacz">Egghead</a></li><li class="menu-item privacy-policy"><a href="/privacy-policy">Privacy Policy</a></li></ul></nav><div class="footer-details"><ul class="social"><li><a href="https://www.linkedin.com/in/lindsey-kopacz-70a09033" aria-label="Lindsey&#x27;s LinkedIn"><i class="fab fa-linkedin-in" aria-hidden="true"></i></a></li><li><a href="https://twitter.com/LittleKope/" aria-label="Lindsey&#x27;s Twitter"><i class="fab fa-twitter" aria-hidden="true"></i></a></li><li><a href="https://github.com/lkopacz" aria-label="Lindsey&#x27;s Github"><i class="fab fa-github" aria-hidden="true"></i></a></li></ul></div></div><div class="credit">Logo and Color Scheme design by<!-- --> <a href="https://www.linkedin.com/in/raquel-breternitz/">Raquel Breternitz</a></div></footer></div></div></div><div id="gatsby-announcer" style="position:absolute;top:0;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border:0" aria-live="assertive" aria-atomic="true"></div></div>
398<script>
399  
400  
401  if(true) {
402    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
403    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
404    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
405    })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
406  }
407  if (typeof ga === "function") {
408    ga('create', 'UA-122458440-1', 'auto', {});
409      
410      
411      
412      
413      
414      }</script>
414<script id="gatsby-script-loader">/*<![CDATA[*/window.pagePath="/blog/accessible-interactive-components-react";/*]]>*/</script>
414<script id="gatsby-chunk-mapping">/*<![CDATA[*/window.___chunkMapping={"polyfill":["/polyfill-d22790a7c7927829ee5c.js"],"app":["/app-c9c16c8991030db0db65.js"],"component---cache-caches-gatsby-plugin-offline-app-shell-js":["/component---cache-caches-gatsby-plugin-offline-app-shell-js-47c8d8b7529f7a984452.js"],"component---src-pages-2018-year-in-review-index-md":["/component---src-pages-2018-year-in-review-index-md-7e36ad4ac1bc0a9e91bb.js"],"component---src-pages-4-things-ive-learned-about-dyslexia-index-md":["/component---src-pages-4-things-ive-learned-about-dyslexia-index-md-fb8cbf8a54c6e52750d0.js"],"component---src-pages-404-js":["/component---src-pages-404-js-9105c1b52b661e85fbb5.js"],"component---src-pages-a-11-y-taught-js-p-1-index-md":["/component---src-pages-a-11-y-taught-js-p-1-index-md-baaa521f4f042d6084b1.js"],"component---src-pages-a-11-y-taught-js-p-2-index-md":["/component---src-pages-a-11-y-taught-js-p-2-index-md-9c78a3f9c72a0722efad.js"],"component---src-pages-a-11-y-testing-workflow-index-md":["/component---src-pages-a-11-y-testing-workflow-index-md-5072eec7bd8716f2b294.js"],"component---src-pages-about-js":["/component---src-pages-about-js-a634a7feecb654f3ac4d.js"],"component---src-pages-accessible-basic-nav-index-mdx":["/component---src-pages-accessible-basic-nav-index-mdx-145a78c7b6905c52c4d4.js"],"component---src-pages-accessible-styled-checkboxes-index-mdx":["/component---src-pages-accessible-styled-checkboxes-index-mdx-9d88f66b6034d62131c4.js"],"component---src-pages-accessible-styled-radio-index-mdx":["/component---src-pages-accessible-styled-radio-index-mdx-4eea5ef8febd4edd7169.js"],"component---src-pages-aria-labels-index-md":["/component---src-pages-aria-labels-index-md-00b64ae9de57e0c88758.js"],"component---src-pages-aria-states-index-mdx":["/component---src-pages-aria-states-index-mdx-8d61eff6bf020cf9cb60.js"],"component---src-pages-blog-birthday-1-index-md":["/component---src-pages-blog-birthday-1-index-md-1475138db4ca702a553e.js"],"component---src-pages-blog-js":["/component---src-pages-blog-js-51eb9cf945d0e3813104.js"],"component---src-pages-cli-tools-index-md":["/component---src-pages-cli-tools-index-md-5f30ea05ecfaeed8b162.js"],"component---src-pages-color-and-accessibility-index-md":["/component---src-pages-color-and-accessibility-index-md-23e02559abbc593a9c64.js"],"component---src-pages-data-viz-a-11-y-bar-chart-index-mdx":["/component---src-pages-data-viz-a-11-y-bar-chart-index-mdx-a90ae6d29b13fa2908b6.js"],"component---src-pages-donut-chart-index-md":["/component---src-pages-donut-chart-index-md-a41753978d1183f30803.js"],"component---src-pages-first-month-blogging-index-md":["/component---src-pages-first-month-blogging-index-md-0864b5ff08461051a9e5.js"],"component---src-pages-focus-within-index-md":["/component---src-pages-focus-within-index-md-8caf05d0403fa4d3564a.js"],"component---src-pages-html-5-aria-index-md":["/component---src-pages-html-5-aria-index-md-075b77dd86deec1b46d8.js"],"component---src-pages-index-js":["/component---src-pages-index-js-e7ddbcd01a9d56b9c798.js"],"component---src-pages-input-range-index-mdx":["/component---src-pages-input-range-index-mdx-ca6a45435d92d4b18530.js"],"component---src-pages-js-a-11-y-index-md":["/component---src-pages-js-a-11-y-index-md-0c8cdd7f5d545f0d4139.js"],"component---src-pages-js-accordion-index-md":["/component---src-pages-js-accordion-index-md-c197ef475baf396d0e5e.js"],"component---src-pages-js-tips-index-mdx":["/component---src-pages-js-tips-index-mdx-98c2242788d31e558911.js"],"component---src-pages-keyboard-accessibility-101-index-md":["/component---src-pages-keyboard-accessibility-101-index-md-309be05a43452239777f.js"],"component---src-pages-manual-testing-checklist-index-md":["/component---src-pages-manual-testing-checklist-index-md-bd58d3233712e3b03ce2.js"],"component---src-pages-my-blogging-workflow-index-md":["/component---src-pages-my-blogging-workflow-index-md-5937a3c244d09236d9de.js"],"component---src-pages-my-rant-this-isnt-edge-case-index-md":["/component---src-pages-my-rant-this-isnt-edge-case-index-md-fb032cbf703f451e317d.js"],"component---src-pages-negative-impact-inaccessible-forms-index-md":["/component---src-pages-negative-impact-inaccessible-forms-index-md-87f10f0ec741b1bc1363.js"],"component---src-pages-podcast-a-11-y-index-md":["/component---src-pages-podcast-a-11-y-index-md-d691a0a51bbf0faafcc3.js"],"component---src-pages-privacy-policy-js":["/component---src-pages-privacy-policy-js-75c24a7d6f1704329ac4.js"],"component---src-pages-react-packages-a-11-y-index-mdx":["/component---src-pages-react-packages-a-11-y-index-mdx-b10e2f78dbd62f951915.js"],"component---src-pages-reduce-motion-index-md":["/component---src-pages-reduce-motion-index-md-7e2a1f550bea9fcc0ced.js"],"component---src-pages-speaker-accessibility-index-md":["/component---src-pages-speaker-accessibility-index-md-6da78a9a1aeabb2cabfb.js"],"component---src-pages-thank-you-order-js":["/component---src-pages-thank-you-order-js-52a50d7cff3629b1106e.js"],"component---src-pages-thanks-digest-js":["/component---src-pages-thanks-digest-js-0b6ed1ecacbebe316533.js"],"component---src-pages-thanks-egghead-js":["/component---src-pages-thanks-egghead-js-3a320d4c621f5772281d.js"],"component---src-pages-thanks-email-course-js":["/component---src-pages-thanks-email-course-js-14f5384ca3de8db85d7a.js"],"component---src-pages-thanksgiving-2018-index-md":["/component---src-pages-thanksgiving-2018-index-md-1e92c5c8a3ba3721e340.js"],"component---src-pages-transitioning-from-remote-index-md":["/component---src-pages-transitioning-from-remote-index-md-f1b41fae929af23657d4.js"],"component---src-pages-twitter-a-11-y-index-md":["/component---src-pages-twitter-a-11-y-index-md-d0a912665ab0b5d3fc26.js"],"component---src-pages-writing-alternative-text-that-matters-index-md":["/component---src-pages-writing-alternative-text-that-matters-index-md-c764088123aced4a7b8d.js"],"component---src-templates-blog-post-js":["/component---src-templates-blog-post-js-7bb63e0dd5d181f92da8.js"]};/*]]>*/</script>
414<script src="/polyfill-d22790a7c7927829ee5c.js" nomodule=""></script>
414<script src="/webpack-runtime-04ee07f01a3316bb5a37.js" async=""></script>
414<script src="/styles-407fe62976dc5310c43e.js" async=""></script>
414<script src="/framework-25679e2f2e739b4a55ca.js" async=""></script>
414<script src="/app-c9c16c8991030db0db65.js" async=""></script>
414<script src="/component---src-templates-blog-post-js-7bb63e0dd5d181f92da8.js" async=""></script>
414</body></html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.