Free Login Page Template (HTML, CSS & JS, 2026)
A clean, accessible login page template — a centered card with labelled email and password fields, show-password toggle and inline validation — responsive and ready to wire to your backend.
This free login page template is a clean, accessible sign-in form: a centered card with properly labelled email and password fields, a show-password toggle, inline validation and a clear submit button. It’s responsive, dependency-free, and built with accessibility in mind so it works for everyone. Wire the form to your own authentication backend and you’re done.
What you get
- A centered, responsive login card that looks right on any screen.
- Accessible fields: real labels,
autocomplete, focus states, and error messaging witharia-live. - A show/hide password toggle and lightweight inline validation.
- Clean CSS-variable theming and zero dependencies.
The HTML
Save as index.html. Every input has a label and an autocomplete attribute so browsers and password managers behave correctly.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Sign in</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<main class="auth">
<form class="card" id="login" novalidate>
<h1>Welcome back</h1>
<p class="sub">Sign in to your account</p>
<div class="field">
<label for="email">Email</label>
<input id="email" name="email" type="email" autocomplete="email"
required placeholder="[email protected]">
</div>
<div class="field">
<label for="password">Password</label>
<div class="pw">
<input id="password" name="password" type="password"
autocomplete="current-password" required minlength="8">
<button type="button" class="toggle" data-toggle aria-label="Show password">Show</button>
</div>
</div>
<p class="error" id="error" role="alert" aria-live="polite"></p>
<button type="submit" class="btn">Sign in</button>
<p class="alt">No account? <a href="#">Create one</a></p>
</form>
</main>
<script src="login.js"></script>
</body>
</html>
The CSS
:root {
--bg: #0b0d14; --card: #141824; --text: #e8ecf4; --muted: #9aa4b8;
--accent: #6ea8ff; --border: #2a3040; --error: #ff8a7a; --radius: 12px;
color-scheme: dark;
}
* { box-sizing: border-box; margin: 0; }
body { font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
background: var(--bg); color: var(--text); }
.auth { min-height: 100vh; display: grid; place-items: center; padding: 20px; }
.card { width: 100%; max-width: 380px; background: var(--card);
border: 1px solid var(--border); border-radius: 16px; padding: 32px; }
h1 { font-size: 24px; }
.sub { color: var(--muted); margin: 6px 0 24px; }
.field { margin-bottom: 16px; }
label { display: block; font-size: 14px; font-weight: 600; margin-bottom: 6px; }
input { width: 100%; padding: 12px 14px; border-radius: var(--radius);
border: 1px solid var(--border); background: #0e1119; color: var(--text); font-size: 15px; }
input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-color: transparent; }
.pw { position: relative; display: flex; }
.toggle { position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
background: none; border: 0; color: var(--muted); font-size: 13px; cursor: pointer; padding: 6px; }
.error { color: var(--error); font-size: 14px; min-height: 20px; margin-bottom: 8px; }
.btn { width: 100%; padding: 13px; border: 0; border-radius: var(--radius);
background: var(--accent); color: #06080f; font-weight: 700; font-size: 15px; cursor: pointer; }
.btn:hover { filter: brightness(1.06); }
.alt { text-align: center; color: var(--muted); margin-top: 18px; font-size: 14px; }
.alt a { color: var(--accent); }
The JavaScript
Save as login.js. This handles the password toggle and basic client-side validation — the server must still validate and authenticate.
const form = document.getElementById('login');
const error = document.getElementById('error');
// show / hide password
document.querySelector('[data-toggle]').addEventListener('click', (e) => {
const input = document.getElementById('password');
const showing = input.type === 'text';
input.type = showing ? 'password' : 'text';
e.target.textContent = showing ? 'Show' : 'Hide';
e.target.setAttribute('aria-label', showing ? 'Show password' : 'Hide password');
});
form.addEventListener('submit', (e) => {
e.preventDefault();
error.textContent = '';
const { email, password } = form.elements;
if (!email.value || !email.validity.valid) {
error.textContent = 'Enter a valid email address.';
email.focus();
return;
}
if (password.value.length < 8) {
error.textContent = 'Password must be at least 8 characters.';
password.focus();
return;
}
// TODO: send to your API over HTTPS
// fetch('/api/login', { method: 'POST', body: JSON.stringify({ email: email.value, password: password.value }) })
console.log('Ready to submit');
});
Wire it to a backend safely
- Always HTTPS. Never send credentials over plain HTTP.
- Validate on the server too. Client-side checks are for UX; the server is the source of truth.
- Never store plain passwords. Hash them with a strong algorithm (bcrypt/argon2) — see Node.js best practices.
- Consider a provider. Auth.js, Clerk or your platform’s auth save you from building (and securing) this yourself.
- Rate-limit and add 2FA for real applications to resist brute-force attacks.
Frequently asked questions
Is this login template secure?
How do I connect the login form to my backend?
console.log in login.js with a fetch POST to your authentication endpoint over HTTPS, sending the email and password, and handle the response (set a session/token on success, show an error on failure). See our guide on building REST APIs for the server side.Is the login page accessible?
<label> tied by for/id, inputs use autocomplete hints so password managers work, focus states are visible, and validation errors are announced to screen readers via role="alert" and aria-live. These are the fundamentals that make a form usable for everyone.Can I add a "remember me" or social login?
Build and test this login form live in XCODX Studio. See also the contact form template, dashboard template and accessibility best practices.