diff options
author | 2022-07-06 06:41:15 +0400 | |
---|---|---|
committer | 2022-07-06 14:04:35 -0700 | |
commit | 024233feeb257f2ddc8c9caa54da4d31b3ddf4a1 (patch) | |
tree | 97a9399f588a92ad66b1d7296d88979ec43f1f9b | |
parent | 48058fac99828695b35749c7783670b633d41447 (diff) | |
download | bun-024233feeb257f2ddc8c9caa54da4d31b3ddf4a1.tar.gz bun-024233feeb257f2ddc8c9caa54da4d31b3ddf4a1.tar.zst bun-024233feeb257f2ddc8c9caa54da4d31b3ddf4a1.zip |
fix a11y issues on landing
-rw-r--r-- | packages/bun-landing/index.css | 93 | ||||
-rw-r--r-- | packages/bun-landing/page.tsx | 132 |
2 files changed, 139 insertions, 86 deletions
diff --git a/packages/bun-landing/index.css b/packages/bun-landing/index.css index 6c2a6a9d7..3af3361b1 100644 --- a/packages/bun-landing/index.css +++ b/packages/bun-landing/index.css @@ -65,6 +65,7 @@ main { max-width: var(--max-width); display: grid; grid-template-columns: auto auto; + overflow-y: hidden; } main, @@ -226,15 +227,12 @@ header { align-items: center; border: 1px solid var(--orange); margin-top: 1rem; - display: grid; + display: flex; + justify-content: space-between; align-content: center; white-space: nowrap; margin-bottom: 1rem; -} - -#code-box { font-family: var(--monospace-font); - position: relative; } #curl:hover { @@ -244,7 +242,7 @@ header { #curl::before { display: block; - content: "$"; + content: "$" / ""; color: var(--orange); pointer-events: none; width: 1ch; @@ -267,21 +265,20 @@ header { } #code-box-copy { - position: absolute; - right: 16px; - top: 0; - bottom: 0; height: 100%; display: flex; align-items: center; - z-index: 5; color: var(--orange-light); transition: transform 0.05s linear; transition-property: color, transform; transform-origin: center center; cursor: pointer; + background: transparent; + border: none; + font-size: inherit; + font-family: inherit; } #code-box-copy:hover { @@ -302,6 +299,8 @@ header { align-items: center; width: min-content; white-space: nowrap; + list-style-type: none; + padding: 0; } .Tab { @@ -311,15 +310,25 @@ header { padding-bottom: 8px; border-bottom: 1px solid #ccc; cursor: pointer; + padding: 0; +} + +.TabButton { + background: transparent; + border: none; padding: 16px 16px; + color: inherit; + font-size: inherit; + font-family: inherit; + cursor: inherit; } -.Tab[data-tab="react"]:hover, -.Graphs--active-react .Tab[data-tab="react"], -.Tab[data-tab="sqlite"]:hover, -.Graphs--active-sqlite .Tab[data-tab="sqlite"], -.Tab[data-tab="ffi"]:hover, -.Graphs--active-ffi .Tab[data-tab="ffi"] { +.TabButton[data-tab="react"]:hover, +.Graphs--active-react .TabButton[data-tab="react"], +.TabButton[data-tab="sqlite"]:hover, +.Graphs--active-sqlite .TabButton[data-tab="sqlite"], +.TabButton[data-tab="ffi"]:hover, +.Graphs--active-ffi .TabButton[data-tab="ffi"] { border-bottom-color: aquamarine; background-color: rgba(130, 216, 247, 0.1); border-right-color: aquamarine; @@ -335,11 +344,14 @@ header { .BarGraph-heading { font-weight: 500; font-size: 1.5rem; + margin: 0; } .BarGraphList { flex: 1; position: relative; + list-style-type: none; + padding: 0; } .BarGraph, .ActiveTab, @@ -350,6 +362,7 @@ header { .BarGraph-subheading { font-size: 0.9rem; color: rgb(135, 134, 134); + margin: 0; } .BarGraphList { @@ -390,15 +403,18 @@ header { height: var(--opposite); background-color: rgb(93, 89, 134); - transform-origin: bottom center; - transform: scaleY(var(--level)); position: relative; + height: calc(200px * var(--level)); } .BarGraphItem { border-right: 1px dashed var(--dark-border); border-top: 1px dashed var(--dark-border); border-bottom: 1px dashed var(--dark-border); + min-height: 200px; + display: flex; + flex-direction: column; + justify-content: flex-end; } .BarGraphItem--deno { @@ -406,7 +422,6 @@ header { } .BarGraph--horizontal .BarGraphBar { - min-height: 200px; } .BarGraph--vertical .BarGraphBar { @@ -434,8 +449,7 @@ header { } .BarGraph--horizontal .BarGraphBar-label { - transform: scaleY(var(--inverse)); - top: calc(-20px * var(--inverse)); + top: -22px; } .BarGraphItem--bun .BarGraphBar { @@ -484,13 +498,13 @@ header { } .BarGraphKeyItem-value { - color: #666; + color: #7a7a7a; margin-top: 0.5rem; } .BarGraphKeyItem-viewSource { margin-top: 0.5rem; - color: #666; + color: #7a7a7a; text-transform: lowercase; font-weight: thin; font-size: 0.8rem; @@ -520,7 +534,7 @@ header { } .DemphasizedLabel { - color: #666; + color: #7a7a7a; font-weight: 300; } @@ -572,7 +586,7 @@ header { } .Tag--Command:before { - content: "❯"; + content: "❯" / ""; color: rgba(255, 255, 255, 0.35); margin-top: auto; margin-bottom: auto; @@ -603,12 +617,12 @@ header { .Tag--React:before { color: rgba(130, 216, 247, 0.5); - content: "<"; + content: "<" / ""; } .Tag--React:after { color: rgba(130, 216, 247, 0.5); - content: ">"; + content: ">" / ""; } .Tag--Bun { @@ -852,16 +866,17 @@ li { margin: 0; gap: 0rem; width: 100%; + border-top: 1px solid rgba(200, 200, 200, 0.1); } .Tab { width: 100%; - padding-top: 16px; - padding-bottom: 16px; + border-bottom-color: #333; } - .Tab { - border-bottom-color: #333; + .TabButton { + padding-top: 16px; + padding-bottom: 16px; } #pitch-content { @@ -873,10 +888,6 @@ li { .Graphs--active-ffi .Tab[data-tab="ffi"] { background-color: rgba(100, 100, 100, 0.1); } - - .Tabs { - border-top: 1px solid rgba(200, 200, 200, 0.1); - } } #explain p > code { @@ -926,3 +937,13 @@ li { img { object-fit: contain; } + +.visually-hidden { + clip: rect(0 0 0 0); + clip-path: inset(50%); + height: 1px; + overflow: hidden; + position: absolute; + white-space: nowrap; + width: 1px; +}
\ No newline at end of file diff --git a/packages/bun-landing/page.tsx b/packages/bun-landing/page.tsx index baefebe6d..56937f54f 100644 --- a/packages/bun-landing/page.tsx +++ b/packages/bun-landing/page.tsx @@ -64,14 +64,15 @@ const Label = ({ children, replace }) => { }; const BarGraphItem = ({ type, amount = 0, label, max = 0 }) => ( - <div + <li className={`BarGraphItem BarGraphItem--${type}`} style={{ "--amount": amount, "--max": max }} > + <div className="visually-hidden">{`${type}: ${fmt.format(amount)} ${label}`}</div> <div style={{ "--amount": amount, "--max": max }} - title={`${amount} ${label}`} className="BarGraphBar" + aria-hidden > <div style={{ "--amount": amount, "--max": max }} @@ -80,11 +81,11 @@ const BarGraphItem = ({ type, amount = 0, label, max = 0 }) => ( {fmt.format(amount)} </div> </div> - </div> + </li> ); const BarGraphLabel = ({ name, version, source }) => ( - <a href={source} target="_blank" className="BarGraphKeyItem"> + <a href={source} target="_blank" className="BarGraphKeyItem" aria-label={`${name} benchmark source`}> <div className="BarGraphKeyItem-label">{name}</div> <div className="BarGraphKeyItem-value">{version}</div> <div className="BarGraphKeyItem-viewSource">View source</div> @@ -104,6 +105,7 @@ const Zig = () => ( className="Zig" viewBox="0 0 400 140" > + <title>Zig</title> <g fill="#F7A41D"> <g> <polygon points="46,22 28,44 19,30" /> @@ -187,9 +189,9 @@ const InstallBox = ({ desktop = false }) => ( </div> <div id="code-box"> <div id="curl">curl https://bun.sh/install | bash</div> - <div className="unselectable" id="code-box-copy"> + <button className="unselectable" id="code-box-copy" aria-label="Copy installation script"> copy - </div> + </button> </div> <a className="unselectable" @@ -240,11 +242,12 @@ export default ({ inlineCSS }) => ( <body> <div id="header-wrap"> <header> - <a href="/" id="logo-link"> - <img height="61px" src={`/logo@2x.png`} alt="Bun" id="logo" /> + <a href="/" id="logo-link" aria-label="home"> + <img height="61px" src="/logo.png" srcSet="/logo.png 1x, /logo@2x.png 2x" alt="Bun logo" id="logo" /> <img height="31.65px" - src={`/Bun@2x.png`} + src="/Bun.png" + srcSet="/Bun.png 1x, /Bun@2x.png 2x" alt="Bun" id="logo-text" /> @@ -288,27 +291,33 @@ export default ({ inlineCSS }) => ( </div> <div className="Graphs Graphs--active-react"> - <div className="Tabs"> - <div data-tab="react" className="Tab"> - Bun.serve - </div> - <div data-tab="sqlite" className="Tab"> - bun:sqlite - </div> - <div data-tab="ffi" className="Tab"> - bun:ffi - </div> - </div> + <ul className="Tabs" role="tablist"> + <li className="Tab"> + <button data-tab="react" aria-controls="react-tab-content" className="TabButton" role="tab" aria-selected tabIndex={0}> + Bun.serve + </button> + </li> + <li className="Tab"> + <button data-tab="sqlite" aria-controls="sqlite-tab-content" className="TabButton" role="tab" tabIndex={-1}> + bun:sqlite + </button> + </li> + <li className="Tab"> + <button data-tab="ffi" aria-controls="ffi-tab-content" className="TabButton" role="tab" tabIndex={-1}> + bun:ffi + </button> + </li> + </ul> <div id="active-tab" className="ActiveTab"> - <div className="BarGraph BarGraph--react BarGraph--horizontal BarGraph--dark"> - <div className="BarGraph-heading"> + <div id="react-tab-content" className="BarGraph BarGraph--react BarGraph--horizontal BarGraph--dark"> + <h2 className="BarGraph-heading"> Server-side rendering React - </div> - <div title="oha -z 5s" className="BarGraph-subheading"> + </h2> + <p className="BarGraph-subheading"> HTTP requests per second (Linux AMD64) - </div> + </p> - <div style={{ "--count": 3 }} className="BarGraphList"> + <ul style={{ "--count": 3 }} className="BarGraphList"> <BarGraphItem type="bun" amount={48936} @@ -327,7 +336,7 @@ export default ({ inlineCSS }) => ( label="requests per second" max={Math.max(48936, 16288, 12289) * 1.25} /> - </div> + </ul> <div style={{ "--count": 3 }} className="BarGraphKey"> <BarGraphLabel @@ -348,13 +357,13 @@ export default ({ inlineCSS }) => ( </div> </div> - <div className="BarGraph--sqlite BarGraph BarGraph--horizontal BarGraph--dark"> - <div className="BarGraph-heading">Load a huge table</div> - <div className="BarGraph-subheading"> + <div id="sqlite-tab-content" className="BarGraph--sqlite BarGraph BarGraph--horizontal BarGraph--dark"> + <h2 className="BarGraph-heading">Load a huge table</h2> + <p className="BarGraph-subheading"> Average queries per second - </div> + </p> - <div style={{ "--count": 3 }} className="BarGraphList"> + <ul style={{ "--count": 3 }} className="BarGraphList"> <BarGraphItem type="bun" amount={(1000 / 16.6).toFixed(2)} @@ -379,7 +388,7 @@ export default ({ inlineCSS }) => ( Math.max(1000 / 16.6, 1000 / 42.96, 1000 / 104.69) * 1.25 )} /> - </div> + </ul> <div style={{ "--count": 3 }} className="BarGraphKey"> <BarGraphLabel @@ -400,11 +409,11 @@ export default ({ inlineCSS }) => ( </div> </div> - <div className="BarGraph BarGraph--ffi BarGraph--horizontal BarGraph--dark"> - <div className="BarGraph-heading">How fast can it get?</div> - <div className="BarGraph-subheading">Operations per second</div> + <div id="ffi-tab-content" className="BarGraph BarGraph--ffi BarGraph--horizontal BarGraph--dark"> + <h2 className="BarGraph-heading">How fast can it get?</h2> + <p className="BarGraph-subheading">Operations per second</p> - <div style={{ "--count": 3 }} className="BarGraphList"> + <ul style={{ "--count": 3 }} className="BarGraphList"> <BarGraphItem type="bun" amount={(115473441).toFixed(2)} @@ -424,12 +433,12 @@ export default ({ inlineCSS }) => ( <BarGraphItem type="deno" amount={(2891761).toFixed(2)} - label="oeprations per iteration" + label="operations per iteration" max={Math.ceil( Math.max(115473441, 43478261, 2891761) * 1.25 )} /> - </div> + </ul> <div style={{ "--count": 3 }} className="BarGraphKey"> <BarGraphLabel @@ -456,7 +465,7 @@ export default ({ inlineCSS }) => ( </div> <section id="explain-section"> <div id="explain"> - <h1>Tell me more about Bun</h1> + <h2>Tell me more about Bun</h2> <p> Bun is a modern JavaScript runtime like Node or Deno. It was built from scratch to focus on three main things: @@ -487,7 +496,7 @@ export default ({ inlineCSS }) => ( future infrastructure, as well as developer productivity through better, simpler tooling. </p> - <h1>Batteries included</h1> + <h2>Batteries included</h2> <ul id="batteries"> <li> Web APIs like{" "} @@ -559,7 +568,7 @@ export default ({ inlineCSS }) => ( </li> </ul> - <h1>How does Bun work?</h1> + <h2>How does Bun work?</h2> <p> Bun.js uses the{" "} <a href="https://github.com/WebKit/WebKit/tree/main/Source/JavaScriptCore"> @@ -584,7 +593,7 @@ export default ({ inlineCSS }) => ( transpiler, npm client, bundler, SQLite client, HTTP client, WebSocket client and more. </p> - <h1>Why is Bun fast?</h1> + <h2>Why is Bun fast?</h2> <p> An enormous amount of time spent profiling, benchmarking and optimizing things. The answer is different for every part of Bun, @@ -598,7 +607,7 @@ export default ({ inlineCSS }) => ( Sponsor the Zig Software Foundation </a> </p> - <h1>Getting started</h1> + <h2>Getting started</h2> <p> To install bun, run this{" "} <a target="_blank" href="https://bun.sh/install"> @@ -654,8 +663,8 @@ export default { <a href="https://bun.sh/discord">Bun's Discord</a> </p> - <h1>Bun CLI</h1> - <Group title="npm takes 160ms to run a script that does nothing"> + <h2>Bun CLI</h2> + <Group> <Command>bun run</Command> <p> The same command for running JavaScript & TypeScript files @@ -675,7 +684,7 @@ export default { </div>{" "} </Group> - <Group title="JavaScript package managers are not using the fastest system calls"> + <Group> <Command>bun install</Command> <p> bun install is an npm-compatible package manager. You probably @@ -705,11 +714,11 @@ export default { </Label> </Group> - <h1>What is the license?</h1> + <h2>What is the license?</h2> <p> MIT License, excluding dependencies which have various licenses. </p> - <h1>How do I see the source code?</h1> + <h2>How do I see the source code?</h2> <p> Bun is on <a href="https://github.com/Jarred-Sumner/bun">GitHub</a> </p> @@ -722,11 +731,34 @@ export default { <script dangerouslySetInnerHTML={{ __html: ` -[...document.querySelectorAll(".Tab")].map(el => el.addEventListener("click", function(e) { +[...document.querySelectorAll(".TabButton")].map(el => el.addEventListener("click", function(e) { var tab = e.srcElement.getAttribute("data-tab"); + [...document.querySelectorAll(".TabButton")].map(el => { + var active = el.getAttribute("data-tab") === tab; + el.setAttribute("tabindex", active ? 0 : -1); + el.setAttribute("aria-selected", active); + }); document.querySelector(".Graphs").setAttribute("class", "Graphs Graphs--active-" + tab); })); +document.body.addEventListener("keydown", e => { + var tabs = [...document.querySelectorAll(".TabButton")]; + var activeTabEl = document.querySelector(".TabButton[aria-selected='true']"); + var activeTabIndex = tabs.indexOf(activeTabEl); + if (e.key === 'ArrowRight' || e.key === 'ArrowDown') { + e.preventDefault(); + activeTabIndex = (activeTabIndex + 1) % tabs.length; + tabs[activeTabIndex].click(); + tabs[activeTabIndex].focus(); + } + if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') { + e.preventDefault(); + activeTabIndex = (activeTabIndex + tabs.length - 1) % tabs.length; + tabs[activeTabIndex].click(); + tabs[activeTabIndex].focus(); + } +}); + document.querySelector("#code-box-copy").addEventListener("click", async e => { var el = document.querySelector("#code-box"); await navigator.clipboard.writeText("curl https://bun.sh/install | bash"); |