Initial commit
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Non-ARIA interactive patterns</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; }
|
||||
body { font-family: -apple-system, Segoe UI, Roboto, sans-serif; margin: 0; color: #1a1a1a; background: #fff; }
|
||||
main { max-width: 760px; margin: 0 auto; padding: 48px 24px; }
|
||||
h1 { font-size: 30px; } h2 { font-size: 20px; margin-top: 40px; }
|
||||
|
||||
/* A custom dropdown with NO aria — just a div with a click handler. */
|
||||
.cmenu { position: relative; display: inline-block; }
|
||||
.cbtn { cursor: pointer; user-select: none; border: 1px solid #d1d5db; border-radius: 8px; padding: 10px 16px; font-size: 15px; background: #fff; }
|
||||
.cbtn.is-open { background: #eef2ff; border-color: #4f46e5; color: #4f46e5; }
|
||||
.cpanel { position: absolute; top: calc(100% + 6px); left: 0; min-width: 200px; background: #fff; border: 1px solid #e5e7eb; border-radius: 10px; box-shadow: 0 10px 30px rgba(0,0,0,.12); padding: 8px; }
|
||||
.cpanel { display: none; }
|
||||
.cpanel.is-open { display: block; }
|
||||
.cpanel a { display: block; padding: 8px 12px; border-radius: 6px; color: #1a1a1a; text-decoration: none; }
|
||||
|
||||
/* A custom modal with NO aria — div trigger + div overlay. */
|
||||
.open-x { cursor: pointer; display: inline-block; border: 1px solid #d1d5db; border-radius: 8px; padding: 10px 16px; font-size: 15px; }
|
||||
.ovl { position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 50; display: none; align-items: center; justify-content: center; }
|
||||
.ovl.is-open { display: flex; }
|
||||
.box { background: #fff; border-radius: 14px; padding: 28px; max-width: 440px; width: 90%; }
|
||||
.x { float: right; cursor: pointer; font-size: 22px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<h1>Non-ARIA patterns</h1>
|
||||
<p>A custom dropdown and modal built from plain <div>s with click handlers and no ARIA at all — the kind the recognizer can only find via real event listeners + drive-and-diff.</p>
|
||||
|
||||
<h2>Custom dropdown</h2>
|
||||
<div class="cmenu">
|
||||
<div class="cbtn" id="cbtn">Resources ▾</div>
|
||||
<div class="cpanel" id="cpanel">
|
||||
<a href="#docs">Documentation</a>
|
||||
<a href="#guides">Guides</a>
|
||||
<a href="#api">API reference</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>Custom modal</h2>
|
||||
<div class="open-x" id="openx">Contact us</div>
|
||||
<div class="ovl" id="ovl">
|
||||
<div class="box">
|
||||
<span class="x" id="closex">×</span>
|
||||
<h3>Contact us</h3>
|
||||
<p>Reach the team at hello@example.com — we usually reply within a day.</p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
const cbtn = document.getElementById("cbtn"), cpanel = document.getElementById("cpanel");
|
||||
cbtn.addEventListener("click", () => {
|
||||
const open = cpanel.classList.toggle("is-open");
|
||||
cbtn.classList.toggle("is-open", open);
|
||||
});
|
||||
const ovl = document.getElementById("ovl");
|
||||
document.getElementById("openx").addEventListener("click", () => ovl.classList.add("is-open"));
|
||||
document.getElementById("closex").addEventListener("click", () => ovl.classList.remove("is-open"));
|
||||
ovl.addEventListener("click", (e) => { if (e.target === ovl) ovl.classList.remove("is-open"); });
|
||||
document.addEventListener("keydown", (e) => { if (e.key === "Escape") { ovl.classList.remove("is-open"); cpanel.classList.remove("is-open"); cbtn.classList.remove("is-open"); } });
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user