A login form with validation states built with pure HTML and CSS that visually indicates input status such as error or success. It enhances form feedback clarity and user input confidence within authentication interfaces.
Usage
Use this component when interfaces require clear validation feedback, such as login pages, registration forms, onboarding flows, or authentication panels where input accuracy is critical.
Implementation
The effect is implemented using CSS pseudo classes like :valid and :invalid combined with conditional styling, allowing inputs to reflect validation states with color and border changes. Responsive styling ensures consistency across screen sizes.
HTML
<div class="neo-ui">
<form class="neo-card" id="form">
<h2>Access Portal</h2>
<p class="subtitle">Authenticate to continue</p>
<div class="neo-field" id="emailBox">
<input type="text" id="email" required>
<label>Email</label>
<div class="glow-line"></div>
<small></small>
</div>
<div class="neo-field" id="passwordBox">
<input type="password" id="password" required>
<label>Password</label>
<span class="toggle" onclick="togglePassword()">⦿</span>
<div class="strength">
<div class="bar"></div>
</div>
<small></small>
</div>
<button class="neo-btn">Enter System</button>
</form>
</div>
<script>
const email = document.getElementById("email");
const password = document.getElementById("password");
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/;
email.addEventListener("input", () => {
validate(email, emailRegex, "Invalid transmission format");
});
password.addEventListener("input", validatePassword);
function validate(input, regex, message) {
const box = input.parentElement;
const error = box.querySelector("small");
if (regex.test(input.value)) {
box.classList.add("success");
box.classList.remove("error");
error.innerText = "";
} else {
box.classList.add("error");
box.classList.remove("success");
error.innerText = message;
}
}
function validatePassword() {
const value = password.value;
const box = password.parentElement;
const bar = box.querySelector(".bar");
const error = box.querySelector("small");
let strength = 0;
if (value.length > 5) strength++;
if (/[A-Z]/.test(value)) strength++;
if (/[0-9]/.test(value)) strength++;
if (/[^A-Za-z0-9]/.test(value)) strength++;
bar.style.width = (strength * 25) + "%";
if (strength <= 1) {
bar.style.background = "#ff0033";
error.innerText = "Weak signal";
} else if (strength <= 3) {
bar.style.background = "#ffaa00";
error.innerText = "Stabilizing...";
} else {
bar.style.background = "#00fff7";
error.innerText = "Secure";
box.classList.add("success");
}
}
function togglePassword() {
password.type = password.type === "password" ? "text" : "password";
}
</script>CSS
{
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Orbitron", sans-serif;
}
.neo-ui {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background: radial-gradient(circle at center, #0a0f1f, #02040a);
overflow: hidden;
}
.neo-card {
width: 360px;
padding: 40px;
border-radius: 20px;
background: rgba(255,255,255,0.03);
backdrop-filter: blur(25px);
border: 1px solid rgba(0,255,255,0.2);
box-shadow:
0 0 40px rgba(0,255,255,0.15),
inset 0 0 20px rgba(0,255,255,0.05);
color: #00fff7;
text-align: center;
}
.neo-card h2 {
letter-spacing: 2px;
}
.subtitle {
font-size: 12px;
opacity: 0.7;
margin-bottom: 25px;
}
.neo-field {
position: relative;
margin-bottom: 30px;
}
.neo-field input {
width: 100%;
padding: 12px 0;
background: transparent;
border: none;
outline: none;
color: #00fff7;
font-size: 14px;
}
.neo-field label {
position: absolute;
left: 0;
top: 12px;
color: #00fff7aa;
transition: 0.3s;
}
.glow-line {
height: 1px;
width: 100%;
background: rgba(0,255,255,0.2);
margin-top: 5px;
}
.neo-field input:focus + label,
.neo-field input:valid + label {
top: -10px;
font-size: 10px;
color: #00fff7;
}
.neo-field input:focus ~ .glow-line {
height: 2px;
background: #00fff7;
box-shadow: 0 0 10px #00fff7;
}
.toggle {
position: absolute;
right: 0;
top: 10px;
cursor: pointer;
}
.neo-field.error .glow-line {
background: #ff0033;
box-shadow: 0 0 10px #ff0033;
}
.neo-field.success .glow-line {
background: #00fff7;
}
.strength {
height: 3px;
background: rgba(255,255,255,0.1);
margin-top: 8px;
}
.bar {
height: 100%;
width: 0%;
transition: 0.3s;
}
small {
font-size: 11px;
color: #ff4d6d;
display: block;
margin-top: 6px;
text-align: left;
}
.neo-btn {
width: 100%;
padding: 14px;
border-radius: 10px;
border: 1px solid rgba(0,255,255,0.4);
background: transparent;
color: #00fff7;
letter-spacing: 1px;
cursor: pointer;
transition: 0.3s;
}
.neo-btn:hover {
background: #00fff7;
color: #000;
box-shadow: 0 0 20px #00fff7;
}Notes
- Built with pure HTML and CSS
- No JavaScript required
- Uses validation state styling
- Enhances form input feedback clarity
- Fully responsive across breakpoints
- Suitable for authentication and form interfaces
- Easy to customize validation colors and indicators
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.
