<main>
<div class="wrapper">
<form>
<div>
<label for="email">Email</label>
<input required type="email" id="email" name="email" autocomplete="email">
</div>
<div>
<label for="password">Password</label>
<input required minlength="8" type="password" id="password" name="password" aria-describedby="password-minlength" autocomplete="current-password" class="password-field">
<button type="button" hidden data-pressed="false" class="reveal-password" aria-controls="password" data-text-show="Show password" data-text-hide="Hide password">Show password</button>
<span data-text-shown="Your password is shown" data-text-hidden="Your password is hidden" class="visually-hidden password-announce" aria-live="polite"></span>
<div id="password-minlength">Eight or more characters</div>
</div>
<div><a href="/.well-known/change-password">Forgot password?</a></div>
<button class="submit">Sign in</button>
</form>
</div>
</main>
.visually-hidden {
position: absolute !important;
width: 1px !important;
height: 1px !important;
margin: 0 !important;
padding: 0 !important;
overflow: hidden !important;
clip: rect(0 0 0 0) !important;
-webkit-clip-path: inset(50%) !important;
clip-path: inset(50%) !important;
border: 0 !important;
white-space: nowrap !important;
}
button {
margin-top: 1rem;
}
.has-js::-ms-reveal {
display: none;
}
.has-js::reveal {
display: none;
}
.reveal-password {
padding: 0.2em 1em;
text-transform: capitalize;
border: none;
background: #555;
border-radius: 0;
display: inline-grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
margin-top: 0;
}
.reveal-password:before {
content: attr(data-text-show);
grid-area: 1 / 1;
height: 0px;
visibility: hidden;
}
.submit {
margin-top: 2rem;
}
input {
border: 1px solid;
padding: 0.3em;
}
label {
display: block;
font-size: 1.2rem;
margin-top: 1rem;
}
a {
display: block;
margin-top: 1rem;
}
const formElement = document.querySelector('form');
if (formElement) {
formElement.addEventListener('submit', (event) => {
const formData = new FormData();
fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(result => {
console.log('Success:', result);
})
.catch(error => {
console.error('Error:', error);
});
event.preventDefault();
})
}
const revealPassword = document.querySelector('.reveal-password');
const passwordField = document.querySelector('.password-field');
const passwordAnnounce = document.querySelector('.password-announce');
if (revealPassword && passwordField && passwordAnnounce) {
revealPassword.hidden = false;
passwordField.classList.add('has-js');
revealPassword.addEventListener('click', (event) => {
let isPressed = revealPassword.getAttribute('data-pressed') === 'true';
if (isPressed) {
passwordField.type = 'password';
revealPassword.innerText = revealPassword.dataset.textShow;
passwordAnnounce.innerText = passwordAnnounce.dataset.textHidden;
} else {
passwordField.type = 'text';
revealPassword.innerText = revealPassword.dataset.textHide;
passwordAnnounce.innerText = passwordAnnounce.dataset.textShown;
}
revealPassword.setAttribute('data-pressed', String(!isPressed));
});
}
This Pen doesn't use any external JavaScript resources.