Skip to content

Instantly share code, notes, and snippets.

@stekhn
Created September 14, 2024 10:03
Show Gist options
  • Save stekhn/d95ae9b1ebce6e529a8fd70e082181e1 to your computer and use it in GitHub Desktop.
Save stekhn/d95ae9b1ebce6e529a8fd70e082181e1 to your computer and use it in GitHub Desktop.
Expandable login form using the CSS :target selector, hash navigation and ARIA attributes for enhanced accessibility. Initially hidden.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Expandable Form</title>
<style>
html,
body {
height: 75%;
}
body {
display: flex;
align-items: center;
justify-content: center;
margin: 0;
padding: 1rem;
font-family: sans-serif;
}
section {
width: 300px;
display: flex;
flex-direction: column;
align-items: center;
}
#form-wrapper {
width: 100%;
}
#form-wrapper #login {
max-height: 0;
overflow: hidden;
}
#form-wrapper:target #login {
max-height: 100%;
overflow: visible;
}
#form-wrapper a[href="#form-wrapper"] {
text-decoration: none;
margin-bottom: 2rem;
}
#form-wrapper:target a[href="#form-wrapper"] {
pointer-events: none;
background: lightgray;
color: slategrey;
}
.input-group {
display: flex;
flex-direction: column;
margin: 0.5rem 0;
}
label {
margin-bottom: 0.25rem;
}
input {
padding: 0.5rem;
font-family: sans-serif;
font-size: 1rem;
border: 1px solid lightgray;
border-radius: 0.25rem;
}
button,
.button {
display: block;
width: 100%;
margin: 0.5rem 0;
padding: 0.5rem;
font-family: sans-serif;
font-size: 1rem;
text-align: center;
background-color: #007bff;
color: white;
border: none;
border-radius: 0.25rem;
box-sizing: border-box;
cursor: pointer;
}
.black {
background: black;
}
.close {
display: block;
color: slategray;
text-align: center;
text-decoration: none;
cursor: pointer;
}
</style>
<script>
document.addEventListener("DOMContentLoaded", function () {
const externalLoginLink = document.querySelector(
'a[href="#form-wrapper"]',
);
const loginForm = document.querySelector("#login");
const formElements = [
loginForm,
...loginForm.querySelectorAll(
"input, label, select, textarea, button, a",
),
];
function updateAriaAttributes() {
const isExpanded = window.location.hash === "#form-wrapper";
externalLoginLink.setAttribute("aria-expanded", isExpanded);
formElements.forEach((element) => {
element.setAttribute("aria-hidden", !isExpanded);
element.toggleAttribute("hidden", !isExpanded);
});
}
externalLoginLink.setAttribute("aria-controls", "login");
updateAriaAttributes();
window.addEventListener("hashchange", updateAriaAttributes);
});
</script>
</head>
<body>
<section>
<button type="button" class="button">Company Login</button>
<span class="spacer">– Or login with –</span>
<div id="form-wrapper">
<!-- Button to expand the form -->
<a href="#form-wrapper" class="button black">External Login</a>
<!-- Login form -->
<form id="login" action="#" method="post">
<div class="input-group">
<label for="email">Email address</label>
<input tabindex="1" id="email" name="email" type="email" />
</div>
<div class="input-group">
<label for="password">Password</label>
<input tabindex="2" id="password" name="password" type="password" />
</div>
<div class="input-group">
<input class="button black" type="submit" value="Login" />
</div>
<!-- Button to close the form -->
<a href="#" class="close">Close login</a>
</form>
</div>
</section>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment