Formulaire de connexion avec validation email/password en temps réel.
Pas de compte ? S'inscrire
<form class="login-form" id="login-form" novalidate>
<h2>Connexion 👋</h2>
<p>Ravi de vous revoir !</p>
<div class="form-group">
<label for="email">Email <span>*</span></label>
<input type="email" id="email" name="email"
placeholder="vous@exemple.fr" required />
<span class="form-error" id="email-error">Email invalide.</span>
</div>
<div class="form-group">
<label for="password">Mot de passe <span>*</span></label>
<input type="password" id="password" name="password"
placeholder="••••••••" required minlength="6" />
<span class="form-error" id="password-error">6 caractères minimum.</span>
</div>
<a href="#" class="form-forgot">Mot de passe oublié ?</a>
<button type="submit" class="form-submit">Se connecter →</button>
<p class="form-footer">
Pas de compte ? <a href="register.html">S'inscrire</a>
</p>
<div class="form-success" id="form-success" hidden>
✅ Connexion réussie !
</div>
</form>
.login-form { background:#fff; border-radius:20px; border:1px solid #e5e7eb; padding:40px; max-width:420px; width:100%; }
.login-form h2 { font-size:1.5rem; font-weight:800; color:#1A1A2E; margin-bottom:6px; }
.login-form > p { color:#6b7280; font-size:.875rem; margin-bottom:28px; }
.form-group { margin-bottom:20px; }
.form-group label { display:block; font-size:.875rem; font-weight:600; color:#1A1A2E; margin-bottom:8px; }
.form-group label span { color:#FF6584; }
.form-group input {
width:100%; padding:12px 16px;
background:#f9fafb; border:1.5px solid #e5e7eb; border-radius:12px;
color:#1A1A2E; font-size:.875rem; outline:none; transition:all .2s;
}
.form-group input:focus { border-color:#6C63FF; box-shadow:0 0 0 4px rgba(108,99,255,.12); background:#fff; }
.form-group input.error { border-color:#EF4444; }
.form-group input.success { border-color:#10B981; }
.form-error { font-size:.75rem; color:#EF4444; margin-top:4px; display:none; }
.form-error.show { display:block; }
.form-forgot { display:block; text-align:right; font-size:.8rem; color:#6C63FF; text-decoration:none; margin-bottom:20px; font-weight:600; }
.form-submit {
width:100%; padding:13px; background:linear-gradient(135deg,#6C63FF,#0FCCCE);
color:white; border:none; border-radius:999px; font-size:.875rem; font-weight:700;
cursor:pointer; transition:all .2s;
}
.form-submit:hover { transform:translateY(-2px); box-shadow:0 8px 20px rgba(108,99,255,.35); }
.form-footer { text-align:center; font-size:.875rem; color:#6b7280; margin-top:20px; }
.form-footer a { color:#6C63FF; font-weight:600; text-decoration:none; }
.form-success { background:rgba(16,185,129,.1); border:1px solid rgba(16,185,129,.3); border-radius:12px; padding:14px; text-align:center; color:#10B981; font-weight:600; font-size:.875rem; margin-top:16px; }
const loginForm = document.getElementById('login-form');
// Validation en temps réel
loginForm.querySelector('#email').addEventListener('input', validateEmail);
loginForm.querySelector('#password').addEventListener('input', validatePassword);
function validateEmail() {
const input = document.getElementById('email');
const error = document.getElementById('email-error');
const isValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(input.value.trim());
setFieldState(input, error, isValid || !input.value);
return isValid;
}
function validatePassword() {
const input = document.getElementById('password');
const error = document.getElementById('password-error');
const isValid = input.value.length >= 6;
setFieldState(input, error, isValid || !input.value);
return isValid;
}
function setFieldState(input, error, isValid) {
input.classList.toggle('error', !isValid);
input.classList.toggle('success', isValid && input.value !== '');
error.classList.toggle('show', !isValid && input.value !== '');
}
loginForm.addEventListener('submit', function(e) {
e.preventDefault();
const emailOk = validateEmail();
const passOk = validatePassword();
if (emailOk && passOk) {
document.getElementById('form-success').removeAttribute('hidden');
}
});