A credential step login form built with pure HTML and CSS that separates authentication inputs into structured steps. It enhances progressive input clarity and guided login flow within modern authentication interfaces.
Usage
Use this component when interfaces require step by step authentication flow, such as multi stage login systems, email first authentication, secure verification processes, or onboarding login sequences.
Implementation
The layout is implemented using sequential input grouping with conditional visibility styling, allowing each step to appear progressively. CSS manages spacing, transitions, and responsive alignment across screen sizes.
HTML
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Credential Step Login</title>
<link rel="stylesheet" href="style.css"/>
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@500;600;700&family=Outfit:wght@300;400;500;600&display=swap" rel="stylesheet"/>
</head>
<body>
<div class="bg">
<div class="bg__blob bg__blob--1"></div>
<div class="bg__blob bg__blob--2"></div>
</div>
<main class="wrapper">
<!-- Brand -->
<div class="brand">
<div class="brand__mark">
<svg viewBox="0 0 28 28" fill="none">
<rect x="1" y="1" width="26" height="26" rx="7" fill="var(--accent)"/>
<path d="M8 14.5L12.5 19L20 10" stroke="white" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</div>
<span class="brand__name">Stylosheet</span>
</div>
<!-- Card -->
<div class="card" id="card">
<!-- Step Tracker -->
<div class="steps" id="stepTracker">
<div class="step step--done" id="s1">
<div class="step__circle">
<svg viewBox="0 0 12 12" fill="none"><path d="M2 6.5l3 3 5-5" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg>
</div>
<span class="step__label">Account</span>
</div>
<div class="step__line" id="l1"></div>
<div class="step step--active" id="s2">
<div class="step__circle"><span>2</span></div>
<span class="step__label">Password</span>
</div>
<div class="step__line" id="l2"></div>
<div class="step" id="s3">
<div class="step__circle"><span>3</span></div>
<span class="step__label">Verify</span>
</div>
</div>
<!-- PANEL 1: Email -->
<div class="panel" id="panel-1" data-panel="1" style="display:none">
<div class="panel__head">
<h1 class="panel__title">Welcome back.</h1>
<p class="panel__sub">Enter your account email to get started.</p>
</div>
<div class="panel__body">
<div class="field">
<label class="field__label" for="email">Email address</label>
<div class="field__row">
<span class="field__icon">
<svg viewBox="0 0 18 18" fill="none"><rect x="2" y="4" width="14" height="10" rx="2" stroke="currentColor" stroke-width="1.4"/><path d="M2 6l7 5 7-5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>
</span>
<input class="field__input" type="email" id="email" placeholder="you@example.com" value="alex@verida.io"/>
</div>
</div>
<p class="hint">We'll look up your account before continuing.</p>
</div>
<div class="panel__foot">
<button class="btn btn--primary" onclick="goStep(2)">
<span>Continue</span>
<svg viewBox="0 0 16 16" fill="none"><path d="M3 8h10M9 4l4 4-4 4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>
</button>
</div>
</div>
<!-- PANEL 2: Password -->
<div class="panel" id="panel-2" data-panel="2">
<div class="panel__head">
<div class="avatar-row">
<div class="avatar">A</div>
<div class="avatar-info">
<span class="avatar-name">Sita</span>
<span class="avatar-email">Sita@stylosheet.io</span>
</div>
<button class="switch-btn" onclick="goStep(1)" title="Switch account">
<svg viewBox="0 0 16 16" fill="none"><path d="M2 8a6 6 0 1 0 12 0A6 6 0 0 0 2 8z" stroke="currentColor" stroke-width="1.3"/><path d="M9 5l-3 3 3 3" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg>
Switch
</button>
</div>
<h1 class="panel__title">Enter your password.</h1>
<p class="panel__sub">Credentials are encrypted end-to-end.</p>
</div>
<div class="panel__body">
<div class="field">
<div class="field__labelrow">
<label class="field__label" for="password">Password</label>
<a href="#" class="link">Forgot?</a>
</div>
<div class="field__row">
<span class="field__icon">
<svg viewBox="0 0 18 18" fill="none"><rect x="4" y="8.5" width="10" height="7" rx="1.5" stroke="currentColor" stroke-width="1.4"/><path d="M6 8.5V6a3 3 0 0 1 6 0v2.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/><circle cx="9" cy="12" r="1" fill="currentColor"/></svg>
</span>
<input class="field__input" type="password" id="password" placeholder="••••••••••••"/>
<button type="button" class="field__eye" id="eyeBtn">
<svg id="eyeOpen" viewBox="0 0 18 18" fill="none"><path d="M1.5 9S4 4.5 9 4.5 16.5 9 16.5 9 14 13.5 9 13.5 1.5 9 1.5 9z" stroke="currentColor" stroke-width="1.3"/><circle cx="9" cy="9" r="2" stroke="currentColor" stroke-width="1.3"/></svg>
<svg id="eyeClosed" viewBox="0 0 18 18" fill="none" style="display:none"><path d="M2 2l14 14M7.5 7.6A2 2 0 0 0 10.4 10.5M5.2 5.3C3.5 6.4 2 9 2 9s2.5 4.5 7 4.5a7 7 0 0 0 3.8-1.1M7 3.1A7.3 7.3 0 0 1 9 3c4.5 0 7 6 7 6s-.7 1.3-1.9 2.5" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/></svg>
</button>
</div>
</div>
<div class="strength-wrap">
<div class="strength-bars">
<div class="strength-bar" id="sb1"></div>
<div class="strength-bar" id="sb2"></div>
<div class="strength-bar" id="sb3"></div>
<div class="strength-bar" id="sb4"></div>
</div>
<span class="strength-label" id="strengthLabel">Password strength</span>
</div>
<label class="checkbox">
<input type="checkbox" class="checkbox__input"/>
<span class="checkbox__box"></span>
<span class="checkbox__text">Keep me signed in for 30 days</span>
</label>
</div>
<div class="panel__foot">
<button class="btn btn--primary" onclick="goStep(3)">
<span>Sign in</span>
<svg viewBox="0 0 16 16" fill="none"><path d="M3 8h10M9 4l4 4-4 4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>
</button>
</div>
</div>
<!-- PANEL 3: OTP -->
<div class="panel" id="panel-3" data-panel="3" style="display:none">
<div class="panel__head">
<div class="otp-hero">
<div class="otp-phone">
<svg viewBox="0 0 40 40" fill="none"><rect x="7" y="2" width="26" height="36" rx="5" stroke="var(--accent)" stroke-width="1.6"/><circle cx="20" cy="32" r="1.8" fill="var(--accent)"/><rect x="13" y="7" width="14" height="2.5" rx="1.2" fill="var(--accent)" opacity="0.3"/></svg>
</div>
</div>
<h1 class="panel__title">Two-step verification.</h1>
<p class="panel__sub">Code sent to <strong>al••••@stylosheet.io</strong></p>
</div>
<div class="panel__body">
<div class="otp-group" id="otpGroup">
<input class="otp-input" type="text" maxlength="1" inputmode="numeric" pattern="[0-9]"/>
<input class="otp-input" type="text" maxlength="1" inputmode="numeric" pattern="[0-9]"/>
<input class="otp-input" type="text" maxlength="1" inputmode="numeric" pattern="[0-9]"/>
<span class="otp-sep">—</span>
<input class="otp-input" type="text" maxlength="1" inputmode="numeric" pattern="[0-9]"/>
<input class="otp-input" type="text" maxlength="1" inputmode="numeric" pattern="[0-9]"/>
<input class="otp-input" type="text" maxlength="1" inputmode="numeric" pattern="[0-9]"/>
</div>
<p class="hint hint--center">Didn't receive it? <a href="#" class="link">Resend in 0:48</a></p>
</div>
<div class="panel__foot panel__foot--col">
<button class="btn btn--primary" onclick="goSuccess()">
<span>Verify & Enter</span>
<svg viewBox="0 0 16 16" fill="none"><path d="M3 8h10M9 4l4 4-4 4" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>
</button>
<button class="btn btn--ghost" onclick="goStep(2)">← Back to password</button>
</div>
</div>
<!-- PANEL SUCCESS -->
<div class="panel panel--success" id="panel-success" style="display:none">
<div class="success-ring">
<svg viewBox="0 0 72 72" fill="none"><circle cx="36" cy="36" r="33" stroke="var(--accent)" stroke-width="2" stroke-dasharray="207" stroke-dashoffset="207" class="success-circle"/><path d="M20 36l11 11 21-22" stroke="var(--accent)" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="50" stroke-dashoffset="50" class="success-check"/></svg>
</div>
<h1 class="panel__title">You're in!</h1>
<p class="panel__sub">Welcome back, <strong>Alex</strong>. Redirecting to your workspace…</p>
<div class="redirect-track"><div class="redirect-fill" id="redirectFill"></div></div>
</div>
</div>
<p class="footer-note">New here? <a href="#" class="link">Create an account →</a></p>
</main>
<script src="script.js"></script>
</body>
</html>CSS
/* =====================================================
STYLOSHEET — CREDENTIAL STEP LOGIN
Warm editorial light theme | Playfair + Outfit
===================================================== */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--bg: #f5f0e8;
--surface: #fdfaf5;
--surface-2: #f0ebe0;
--border: #e3ddd2;
--border-focus: #c8a96e;
--accent: #b8834a;
--accent-light: #f5e9d8;
--accent-deep: #8f5f2c;
--text: #1e1a14;
--text-muted: #7a6f60;
--text-faint: #b5ad9f;
--success: #3a9e6f;
--danger: #cc4a3a;
--font-display: 'Playfair Display', serif;
--font-body: 'Outfit', sans-serif;
--radius: 18px;
--radius-sm: 10px;
--shadow: 0 24px 64px rgba(80,50,10,0.13), 0 0 0 1px var(--border);
}
body {
min-height: 100vh;
background: var(--bg);
display: flex;
align-items: center;
justify-content: center;
font-family: var(--font-body);
color: var(--text);
}
/* ── Background Blobs ── */
.bg {
position: fixed;
inset: 0;
overflow: hidden;
pointer-events: none;
z-index: 0;
}
.bg__blob {
position: absolute;
border-radius: 50%;
filter: blur(80px);
opacity: 0.45;
}
.bg__blob--1 {
width: 520px; height: 520px;
background: radial-gradient(circle, #e8c88a 0%, transparent 70%);
top: -120px; right: -100px;
}
.bg__blob--2 {
width: 400px; height: 400px;
background: radial-gradient(circle, #d4b896 0%, transparent 70%);
bottom: -80px; left: -80px;
}
/* ── Wrapper ── */
.wrapper {
position: relative;
z-index: 1;
width: 100%;
max-width: 420px;
padding: 24px 20px;
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
}
/* ── Brand ── */
.brand {
display: flex;
align-items: center;
gap: 10px;
}
.brand__mark svg { width: 30px; height: 30px; }
.brand__name {
font-family: var(--font-display);
font-size: 22px;
font-weight: 700;
color: var(--text);
letter-spacing: -0.3px;
}
/* ── Card ── */
.card {
width: 100%;
background: var(--surface);
border-radius: var(--radius);
border: 1px solid var(--border);
box-shadow: var(--shadow);
overflow: hidden;
animation: slideUp 0.55s cubic-bezier(0.22,1,0.36,1) both;
}
@keyframes slideUp {
from { opacity: 0; transform: translateY(24px); }
to { opacity: 1; transform: translateY(0); }
}
/* ── Step Tracker ── */
.steps {
display: flex;
align-items: center;
justify-content: center;
padding: 22px 32px 0;
gap: 0;
}
.step {
display: flex;
flex-direction: column;
align-items: center;
gap: 5px;
position: relative;
z-index: 1;
}
.step__circle {
width: 34px;
height: 34px;
border-radius: 50%;
border: 2px solid var(--border);
background: var(--surface);
display: flex;
align-items: center;
justify-content: center;
font-size: 13px;
font-weight: 600;
color: var(--text-faint);
transition: all 0.3s ease;
}
.step__label {
font-size: 10.5px;
font-weight: 500;
letter-spacing: 0.05em;
text-transform: uppercase;
color: var(--text-faint);
transition: color 0.3s;
}
/* Active step */
.step--active .step__circle {
border-color: var(--accent);
background: var(--accent-light);
color: var(--accent-deep);
box-shadow: 0 0 0 4px rgba(184,131,74,0.12);
}
.step--active .step__label { color: var(--accent-deep); }
/* Done step */
.step--done .step__circle {
border-color: var(--success);
background: #e8f7f0;
color: var(--success);
}
.step--done .step__label { color: var(--success); }
/* Step lines */
.step__line {
flex: 1;
height: 2px;
background: var(--border);
margin: 0 4px;
margin-bottom: 19px;
border-radius: 2px;
transition: background 0.4s;
}
.step__line--done { background: var(--success); }
.step__line--active { background: var(--accent); }
/* ── Panel ── */
.panel {
padding: 28px 32px 32px;
animation: panelIn 0.4s cubic-bezier(0.22,1,0.36,1) both;
}
@keyframes panelIn {
from { opacity: 0; transform: translateX(16px); }
to { opacity: 1; transform: translateX(0); }
}
.panel--back {
animation: panelBack 0.4s cubic-bezier(0.22,1,0.36,1) both;
}
@keyframes panelBack {
from { opacity: 0; transform: translateX(-16px); }
to { opacity: 1; transform: translateX(0); }
}
.panel__head { margin-bottom: 24px; }
.panel__title {
font-family: var(--font-display);
font-size: 26px;
font-weight: 600;
color: var(--text);
line-height: 1.2;
margin-bottom: 6px;
letter-spacing: -0.4px;
}
.panel__sub {
font-size: 14px;
color: var(--text-muted);
line-height: 1.55;
}
.panel__sub strong { color: var(--text); font-weight: 500; }
/* ── Avatar Row ── */
.avatar-row {
display: flex;
align-items: center;
gap: 11px;
background: var(--surface-2);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
padding: 10px 14px;
margin-bottom: 20px;
}
.avatar {
width: 36px; height: 36px;
border-radius: 50%;
background: var(--accent);
color: white;
font-family: var(--font-display);
font-size: 15px;
font-weight: 700;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.avatar-info {
flex: 1;
display: flex;
flex-direction: column;
gap: 1px;
}
.avatar-name {
font-size: 14px;
font-weight: 600;
color: var(--text);
}
.avatar-email {
font-size: 12px;
color: var(--text-muted);
}
.switch-btn {
display: flex;
align-items: center;
gap: 5px;
background: none;
border: 1px solid var(--border);
border-radius: 6px;
padding: 5px 10px;
font-family: var(--font-body);
font-size: 11.5px;
font-weight: 500;
color: var(--text-muted);
cursor: pointer;
transition: all 0.2s;
}
.switch-btn:hover {
border-color: var(--accent);
color: var(--accent-deep);
}
.switch-btn svg { width: 13px; height: 13px; }
/* ── Panel Body ── */
.panel__body {
display: flex;
flex-direction: column;
gap: 16px;
}
/* ── Fields ── */
.field { display: flex; flex-direction: column; gap: 7px; }
.field__labelrow {
display: flex;
align-items: center;
justify-content: space-between;
}
.field__label {
font-size: 12px;
font-weight: 600;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--text-muted);
}
.field__row {
position: relative;
display: flex;
align-items: center;
}
.field__icon {
position: absolute;
left: 13px;
color: var(--text-faint);
display: flex;
align-items: center;
}
.field__icon svg { width: 16px; height: 16px; }
.field__input {
width: 100%;
background: var(--surface-2);
border: 1.5px solid var(--border);
border-radius: var(--radius-sm);
padding: 12px 42px 12px 40px;
font-family: var(--font-body);
font-size: 14.5px;
font-weight: 400;
color: var(--text);
outline: none;
transition: border-color 0.2s, box-shadow 0.2s, background 0.2s;
}
.field__input::placeholder { color: var(--text-faint); }
.field__input:focus {
border-color: var(--border-focus);
background: white;
box-shadow: 0 0 0 3.5px rgba(184,131,74,0.12);
}
.field__eye {
position: absolute;
right: 0;
background: none;
border: none;
cursor: pointer;
padding: 11px 13px;
color: var(--text-faint);
line-height: 0;
transition: color 0.2s;
}
.field__eye:hover { color: var(--accent); }
.field__eye svg { width: 16px; height: 16px; }
.hint {
font-size: 12.5px;
color: var(--text-faint);
line-height: 1.5;
}
.hint--center { text-align: center; }
.link {
color: var(--accent);
text-decoration: none;
font-weight: 500;
font-size: 12.5px;
transition: color 0.2s;
}
.link:hover { color: var(--accent-deep); }
/* ── Strength Bar ── */
.strength-wrap {
display: flex;
align-items: center;
gap: 10px;
}
.strength-bars {
display: flex;
gap: 4px;
flex: 1;
}
.strength-bar {
flex: 1;
height: 4px;
border-radius: 4px;
background: var(--border);
transition: background 0.3s;
}
.strength-bar.weak { background: var(--danger); }
.strength-bar.fair { background: #e09a30; }
.strength-bar.good { background: #6aaf4a; }
.strength-bar.strong { background: var(--success); }
.strength-label {
font-size: 11.5px;
font-weight: 500;
color: var(--text-faint);
white-space: nowrap;
min-width: 70px;
text-align: right;
}
/* ── Checkbox ── */
.checkbox {
display: flex;
align-items: center;
gap: 10px;
cursor: pointer;
}
.checkbox__input { display: none; }
.checkbox__box {
width: 18px; height: 18px;
flex-shrink: 0;
border: 1.5px solid var(--border);
border-radius: 5px;
background: var(--surface-2);
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s;
}
.checkbox__input:checked + .checkbox__box {
background: var(--accent-light);
border-color: var(--accent);
}
.checkbox__input:checked + .checkbox__box::after {
content: '';
display: block;
width: 9px; height: 6px;
border-left: 1.8px solid var(--accent-deep);
border-bottom: 1.8px solid var(--accent-deep);
transform: rotate(-45deg) translateY(-1px);
}
.checkbox__text {
font-size: 13px;
color: var(--text-muted);
line-height: 1.4;
}
/* ── Panel Footer ── */
.panel__foot {
margin-top: 22px;
display: flex;
gap: 10px;
}
.panel__foot--col {
flex-direction: column;
}
/* ── Buttons ── */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
border-radius: var(--radius-sm);
font-family: var(--font-body);
font-size: 14.5px;
font-weight: 600;
cursor: pointer;
border: none;
transition: all 0.2s;
}
.btn svg { width: 15px; height: 15px; flex-shrink: 0; }
.btn--primary {
flex: 1;
padding: 13px 22px;
background: var(--accent);
color: white;
box-shadow: 0 4px 16px rgba(184,131,74,0.28);
}
.btn--primary:hover {
background: var(--accent-deep);
box-shadow: 0 6px 24px rgba(143,95,44,0.35);
transform: translateY(-1px);
}
.btn--primary:active { transform: translateY(0); }
.btn--ghost {
flex: none;
padding: 13px 18px;
background: transparent;
color: var(--text-muted);
border: 1.5px solid var(--border);
}
.btn--ghost:hover {
border-color: var(--accent);
color: var(--accent-deep);
background: var(--accent-light);
}
.btn--full { flex: 1; width: 100%; }
/* ── OTP ── */
.otp-hero {
display: flex;
justify-content: center;
margin-bottom: 18px;
}
.otp-phone {
width: 52px; height: 52px;
border-radius: 14px;
background: var(--accent-light);
border: 1.5px solid rgba(184,131,74,0.25);
display: flex;
align-items: center;
justify-content: center;
}
.otp-phone svg { width: 28px; height: 28px; }
.otp-group {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}
.otp-sep {
font-size: 18px;
color: var(--text-faint);
line-height: 1;
margin: 0 2px;
}
.otp-input {
width: 46px; height: 54px;
text-align: center;
font-family: var(--font-display);
font-size: 22px;
font-weight: 600;
color: var(--text);
background: var(--surface-2);
border: 1.5px solid var(--border);
border-radius: var(--radius-sm);
outline: none;
transition: border-color 0.2s, box-shadow 0.2s, background 0.2s;
caret-color: var(--accent);
}
.otp-input:focus {
border-color: var(--border-focus);
background: white;
box-shadow: 0 0 0 3.5px rgba(184,131,74,0.12);
}
.otp-input.filled {
border-color: var(--accent);
background: var(--accent-light);
}
/* ── Success ── */
.panel--success {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
padding: 40px 32px 36px;
gap: 10px;
}
.success-ring {
width: 72px; height: 72px;
margin-bottom: 10px;
}
.success-ring svg { width: 100%; height: 100%; }
.success-circle {
animation: drawCircle 0.6s cubic-bezier(0.4,0,0.2,1) 0.1s forwards;
}
.success-check {
animation: drawCheck 0.4s cubic-bezier(0.4,0,0.2,1) 0.65s forwards;
}
@keyframes drawCircle {
to { stroke-dashoffset: 0; }
}
@keyframes drawCheck {
to { stroke-dashoffset: 0; }
}
/* Redirect progress */
.redirect-track {
width: 100%;
height: 3px;
background: var(--border);
border-radius: 3px;
margin-top: 16px;
overflow: hidden;
}
.redirect-fill {
height: 100%;
width: 0%;
background: var(--accent);
border-radius: 3px;
transition: width 2.5s linear;
}
/* ── Footer Note ── */
.footer-note {
font-size: 13px;
color: var(--text-muted);
}
/* ── Responsive ── */
@media (max-width: 460px) {
.panel { padding: 22px 20px 26px; }
.steps { padding: 18px 20px 0; }
.otp-input { width: 40px; height: 50px; font-size: 20px; }
.panel__title { font-size: 22px; }
}Notes
- Built with pure HTML and CSS
- No JavaScript required
- Uses step based authentication structure
- Enhances guided login flow clarity
- Fully responsive across breakpoints
- Suitable for multi step login interfaces
- Easy to customize step transitions and layout
Preview styles shown. Production customization recommended.
Browse More UI Components
Explore hundreds of reusable HTML & CSS UI components built for modern web projects.
Discover buttons, cards, loaders, animations, layouts, and more all with live previews and clean, copy-paste code.
