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'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">'react'</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">'react-burger-menu'</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">=></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"><</span><span class="token class-name">Menu</span></span> <span class="token attr-name">noOverlay</span><span class="token punctuation">></span></span><span class="token plain-text"> 7 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</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">"</span>menu-item<span class="token punctuation">"</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">"</span>/<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 8 Home 9 </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>a</span><span class="token punctuation">></span></span><span class="token plain-text"> 10 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</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">"</span>menu-item<span class="token punctuation">"</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">"</span>/about<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 11 About 12 </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>a</span><span class="token punctuation">></span></span><span class="token plain-text"> 13 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</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">"</span>menu-item<span class="token punctuation">"</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">"</span>/contact<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 14 Contact 15 </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>a</span><span class="token punctuation">></span></span><span class="token plain-text"> 16 </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">Menu</span></span><span class="token punctuation">></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">'react'</span> 21<span class="token keyword">import</span> <span class="token string">'./styles.css'</span> 22<span class="token keyword">import</span> BurgerMenu <span class="token keyword">from</span> <span class="token string">'./components/BurgerMenu'</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"><</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">"
26</span>App<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 27 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">BurgerMenu</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> 28 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> 29 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>header</span><span class="token punctuation">></span></span><span class="token plain-text"> 30 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</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">></span></span><span class="token plain-text">Welcome to a website</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text"> 31 </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>header</span><span class="token punctuation">></span></span><span class="token plain-text"> 32 </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> 33 </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></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">'react'</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">'react-burger-menu'</span> 37 38<span class="gatsby-highlight-code-line"><span class="token keyword">import</span> <span class="token string">'./burger.css'</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">=></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">'.bm-menu-wrap'</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">'aria-hidden'</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"><</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">"</span>App<span class="token punctuation">"</span></span><span class="token punctuation">></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"><</span><span class="token class-name">BurgerMenu</span></span> <span class="token punctuation">/></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"><</span>div</span><span class="token punctuation">></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"><</span>header</span><span class="token punctuation">></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"><</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">></span></span><span class="token plain-text">Welcome to a website</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>h2</span><span class="token punctuation">></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"></</span>header</span><span class="token punctuation">></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"></</span>div</span><span class="token punctuation">></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"></</span>div</span><span class="token punctuation">></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"><</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">></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"></</span><span class="token class-name">Menu</span></span><span class="token punctuation">></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">=></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">=></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">=></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">'.bm-menu-wrap'</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">'aria-hidden'</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">'aria-hidden'</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&hidenavigation=1&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">'react'</span> 101<span class="token keyword">import</span> ReactModal <span class="token keyword">from</span> <span class="token string">'react-modal'</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">=></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"><</span><span class="token class-name">ReactModal</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 106 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span><span class="token punctuation">></span></span><span class="token plain-text">Hey</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span><span class="token plain-text"> 107 </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">
107ReactModal</span></span><span class="token punctuation">></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">'react'</span> 112<span class="token keyword">import</span> ReactModal <span class="token keyword">from</span> <span class="token string">'react-modal'</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">'#root'</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">=></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"><</span><span class="token class-name">ReactModal</span></span><span class="token punctuation">></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"><</span>p</span><span class="token punctuation">></span></span><span class="token plain-text">Hey</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></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"></</span><span class="token class-name">ReactModal</span></span><span class="token punctuation">></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">'react'</span></span><span class="token keyword">import</span> ReactModal <span class="token keyword">from</span> <span class="token string">'react-modal'</span> 124 125ReactModal<span class="token punctuation">.</span><span class="token function">setAppElement</span><span class="token punctuation">(</span><span class="token string">'#root'</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">=></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"><</span><span class="token class-name">ReactModal</span></span><span class="token punctuation">></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"><</span>p</span><span class="token punctuation">></span></span><span class="token plain-text">Hey</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></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"></</span><span class="token class-name">ReactModal</span></span><span class="token punctuation">></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">=></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">=></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">=></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"><</span><span class="token class-name">ReactModal</span></span><span class="token punctuation">></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"><</span>p</span><span class="token punctuation">></span></span><span class="token plain-text">Hey</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></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"></</span><span class="token class-name">
142ReactModal</span></span><span class="token punctuation">></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">=></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">=></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">=></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"><</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">></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"><</span>p</span><span class="token punctuation">></span></span><span class="token plain-text">Hey</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></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"></</span><span class="token class-name">ReactModal</span></span><span class="token punctuation">></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">=></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">=></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">=></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"><</span></span><span class="token punctuation">></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"><</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">></span></span><span class="token plain-text">Open Me!</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>button</span><span class="token punctuation">></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"><</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">></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"><</span>p</span><span class="token punctuation">></span></span><span class="token plain-text">Hey</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></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"></</span><span class="token class-name">ReactModal</span></span><span class="token punctuation">></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"></</span></span><span class="token punctuation">></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">=></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">=></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">=></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"><</span></span><span class="token punctuation">></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"><</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">></span></span><span class="token plain-text">Open Me!</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>button</span><span class="token punctuation">></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"><</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">></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"><</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">></span></span><span class="token plain-text">Close</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>button</span><span class="token punctuation">></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"><</span>p</span><span class="token punctuation">></span></span><span class="token plain-text">Hey</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></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"></</span><span class="token class-name">
178ReactModal</span></span><span class="token punctuation">></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"></</span></span><span class="token punctuation">></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">=></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">=></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">=></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"><</span></span><span class="token punctuation">></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"><</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">></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"></</span>button</span><span class="token punctuation">></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"><</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">></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"><</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">></span></span><span class="token plain-text">Close</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>button</span><span class="token punctuation">></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"><</span>div</span><span class="token punctuation">></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"></</span>div</span><span class="token punctuation">></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"></</span><span class="token class-name">
190ReactModal</span></span><span class="token punctuation">></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"></</span>div</span><span class="token punctuation">></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">'react'</span> 194<span class="token keyword">import</span> Modal <span class="token keyword">from</span> <span class="token string">'./components/Modal'</span> 195<span class="token keyword">import</span> <span class="token string">'./styles.css'</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"><</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">"</span>App<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 200 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text">Hello CodeSandbox</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text"> 201 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>h2</span><span class="token punctuation">></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"></</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text"> 202 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</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">"</span>Sign up!<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 203 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>form</span><span class="token punctuation">></span></span><span class="token plain-text"> 204 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> 205 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</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">"</span>email-input<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text">Email:</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>label</span><span class="token punctuation">></span></span><span class="token plain-text"> 206 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</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">"</span>email<span class="token punctuation">"</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">"</span>email-input<span class="token punctuation">"</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">"</span>email<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> 207 </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> 208 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> 209 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</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">"</span>password-input<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text">Password:</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>label</span><span class="token punctuation">></span></span><span class="token plain-text"> 210 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</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">"</span>password<span class="token punctuation">"</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">"</span>password-input<span class="token punctuation">"</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">"</span>password<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> 211 </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span><span class="token plain-text"> 212 </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>form</span><span class="token punctuation">></span></span><span class="token plain-text"> 213 </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">
213Modal</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 214 </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></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'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&hidenavigation=1&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 & Down Arrow goes to the Previous & 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">'react'</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">'react-accessible-accordion'</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">'react'</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">'react-accessible-accordion'</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">=></span> <span class="token punctuation">(</span> 233 <span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">AccordionComponent</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 234 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">AccordionItem</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 235 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">AccordionItemHeading</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 236 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">AccordionItemButton</span></span><span class="token punctuation">></span></span><span class="token plain-text">Heading 1</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">AccordionItemButton</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 237 </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">AccordionItemHeading</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 238 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">AccordionItemPanel</span></span><span class="token punctuation">></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"></</span><span class="token class-name">AccordionItemPanel</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 245 </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">AccordionItem</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 246 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">AccordionItem</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 247 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">AccordionItemHeading</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 248 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">AccordionItemButton</span></span><span class="token punctuation">></span></span><span class="token plain-text">Heading 2</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">AccordionItemButton</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 249 </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">AccordionItemHeading</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 250 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">AccordionItemPanel</span></span><span class="token punctuation">></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"></</span><span class="token class-name">AccordionItemPanel</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 257 </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">AccordionItem</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 258 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">AccordionItem</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 259 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">AccordionItemHeading</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 260 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">AccordionItemButton</span></span><span class="token punctuation">></span></span><span class="token plain-text">Heading 3</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">AccordionItemButton</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 261 </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">AccordionItemHeading</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 262 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">AccordionItemPanel</span></span><span class="token punctuation">></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"></</span><span class="token class-name">AccordionItemPanel</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 267 </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">AccordionItem</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 268 </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">AccordionComponent</span></span><span class="token punctuation">></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">'react'</span> 272<span class="token keyword">import</span> <span class="token string">'./styles.css'</span> 273 274<span class="token keyword">import</span> Accordion <span class="token keyword">from</span> <span class="token string">'./components/Accordion'</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"><</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">"</span>App<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 279 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text">Hello CodeSandbox</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text"> 280 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>h2</span><span class="token punctuation">></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"></</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text"> 281 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">Accordion</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> 282 </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></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">'Heading 1'</span><span class="token punctuation">,</span> 287 body<span class="token operator">:</span> 288 <span class="token string">'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. '</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">'Heading 2'</span><span class="token punctuation">,</span> 292 body<span class="token operator">:</span> 293 <span class="token string">'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. '</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">'Heading 3'</span><span class="token punctuation">,</span> 297 body<span class="token operator">:</span> 298 <span class="token string">'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.'</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"><</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">"</span>App<span class="token punctuation">"</span></span><span class="token punctuation">></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"><</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text">Hello CodeSandbox</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>h1</span><span class="token punctuation">></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"><</span>h2</span><span class="token punctuation">></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"></</span>h2</span><span class="token punctuation">></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"><</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">/></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"></</span>div</span><span class="token punctuation">></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">=></span> <span class="token punctuation">(</span> 308 <span class="token tag"><span class="token tag"><span class="token punctuation"><</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">></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">=></span> <span class="token punctuation">(</span>
310 <span class="token tag"><span class="token tag"><span class="token punctuation"><</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">></span></span><span class="token plain-text"> 311 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">AccordionItemHeading</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 312 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">AccordionItemButton</span></span><span class="token punctuation">></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"></</span><span class="token class-name">AccordionItemButton</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 313 </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">AccordionItemHeading</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 314 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">AccordionItemPanel</span></span><span class="token punctuation">></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"></</span><span class="token class-name">AccordionItemPanel</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 315 </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">AccordionItem</span></span><span class="token punctuation">></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"></</span><span class="token class-name">AccordionComponent</span></span><span class="token punctuation">></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">'Heading 1'</span><span class="token punctuation">,</span> 322 body<span class="token operator">:</span>
323 <span class="token string">'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. '</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">'Heading 2'</span><span class="token punctuation">,</span> 327 body<span class="token operator">:</span> 328 <span class="token string">'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. '</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">'Heading 3'</span><span class="token punctuation">,</span> 332 body<span class="token operator">:</span> 333 <span class="token string">'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.'</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"><</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">/></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"><</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">/></span></span></code></pre></div><iframe src="https://codesandbox.io/embed/a11y-accordion-react-8524z?fontsize=14&hidenavigation=1&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">'react'</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">'react-tabs'</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">=></span> <span class="token punctuation">(</span> 342 <span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">TabsComponent</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 343 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">TabList</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 344 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">Tab</span></span><span class="token punctuation">></span></span><span class="token plain-text">Item 1</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">Tab</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 345 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">Tab</span></span><span class="token punctuation">></span></span><span class="token plain-text">Item 2</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">Tab</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 346 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">Tab</span></span><span class="token punctuation">></span></span><span class="token plain-text">Item 3</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">Tab</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 347 </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">TabList</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 348 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">TabPanel</span></span><span class="token punctuation">></span></span><span class="token plain-text">Hi from item 1</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">TabPanel</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 349 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">TabPanel</span></span><span class="token punctuation">></span></span><span class="token plain-text">Hi from item 2</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">TabPanel</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 350 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">TabPanel</span></span><span class="token punctuation">></span></span><span class="token plain-text">Hi from item 3</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">TabPanel</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 351 </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">TabsComponent</span></span><span class="token punctuation">></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">'react'</span> 355<span class="token keyword">import</span> <span class="token string">'./styles.css'</span> 356 357<span class="token keyword">import</span> Tabs <span class="token keyword">from</span> <span class="token string">'./components/Tabs'</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"><</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">"</span>App<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 362 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text">Hello CodeSandbox</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text"> 363 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>h2</span><span class="token punctuation">></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"></</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text"> 364 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">Tabs</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"> 365 </span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></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">'Item 1'</span><span class="token punctuation">,</span> 370 body<span class="token operator">:</span> <span class="token string">'Hi from item 1'</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">'Item 2'</span><span class="token punctuation">,</span> 374 body<span class="token operator">:</span> <span class="token string">'Hi from item 2'</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">'Item 3'</span><span class="token punctuation">,</span> 378 body<span class="token operator">:</span> <span class="token string">'Hi from item 3'</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"><</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">"</span>App<span class="token punctuation">"</span></span><span class="token punctuation">></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"><</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text">Hello CodeSandbox</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>h1</span><span class="token punctuation">></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"><</span>h2</span><span class="token punctuation">></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"></</span>h2</span><span class="token punctuation">></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"><</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">/></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"></</span>div</span><span class="token punctuation">></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">=></span> <span class="token punctuation">(</span> 388 <span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">TabsComponent</span></span><span class="token punctuation">></span></span><span class="token plain-text"> 389 </span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">TabList</span></span><span class="token punctuation">></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">=></span> <span class="token punctuation">(</span>
391 <span class="token tag"><span class="token tag"><span class="token punctuation"><</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">></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"></</span><span class="token class-name">Tab</span></span><span class="token punctuation">></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"></</span><span class="token class-name">TabList</span></span><span class="token punctuation">></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">=></span> <span class="token punctuation">(</span> 395 <span class="token tag"><span class="token tag"><span class="token punctuation"><</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">></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"></</span><span class="token class-name">TabPanel</span></span><span class="token punctuation">></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"></</span><span class="token class-name">TabsComponent</span></span><span class="token punctuation">></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&hidenavigation=1&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 & 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'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's LinkedIn"><i class="fab fa-linkedin-in" aria-hidden="true"></i></a></li><li><a href="https://twitter.com/LittleKope/" aria-label="Lindsey's Twitter"><i class="fab fa-twitter" aria-hidden="true"></i></a></li><li><a href="https://github.com/lkopacz" aria-label="Lindsey'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.