If you are new to web development, then you must have heard about form validation. Validation means - verifying the data received from the user. In this article, we will learn how to do email validation using JavaScript.
| Live email validation form built with HTML, CSS animations, and JavaScript logic |
This is a complete beginner-friendly guide in which we will understand the code of HTML, CSS, and JavaScript and create a beautiful and powerful email validation form using it.
What is email validation?
When a user types an email address in a form, we have to make sure that the email is in a valid format, like: user@example.com
Wrong format, like:
- user@.com
- userexample.com
- user@domain
It is used to prevent JavaScript in the wrong format which makes real-time validation possible.
Step-by-Step Project: JavaScript Email Verification Form
This project is divided into three main parts:
- HTML (Structure)
- CSS (Design and Animation)
- JavaScript (Validation Logic)
Now we will look at each part in detail. The code and explanation of each part is given.
HTML Code
The HTML code below creates a simple and responsive email form. It uses Bootstrap 5 to be mobile friendly and visually appealing.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Email Validation</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- Particles container -->
<div class="particles"></div>
<div class="container mt-5">
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-header wrapper">
<h3 class="title">Rays Coding :- JavaScript Validation</h3>
</div>
<div class="card-body">
<form action="" method="post">
<div class="row">
<div class="col-lg-12">
<div class="mb-3 field">
<input type="email" class="form-control" id="email" name="useremail" autocomplete="off" placeholder=" ">
<label for="email" class="form-label">Email</label>
</div>
</div>
</div>
<div class="row error-row" id="errorRow" style="display: none;">
<div class="col-lg-12">
<div class="mb-3 field">
<div class="alert alert-danger" id="error"></div>
</div>
</div>
</div>
<div class="row success-row" id="successRow" style="display: none;">
<div class="col-lg-12">
<div class="mb-3 field">
<div class="alert alert-success" id="success"></div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="field">
<button type="button" class="btn btn-primary w-100" onclick="validation()">
<span id="btnText">SUBMIT</span>
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
Explanation
- Designed a responsive Bootstrap card.
- Given an email input field where the user will enter his email.
- Given a submit button which will trigger validation.
- Dives are created to show/hide error and success messages.
- Links to external CSS (style.css) and JavaScript (script.js) files are provided.
- There is also a particles container at the top to show background animation.
CSS code: form design and animation
The project uses CSS to give the form a modern and attractive look. It uses backdrop blur, animated labels, and gradient buttons.
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Inter', sans-serif;
}
body {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
height: 100vh;
position: relative;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
/* Animated background particles */
.particles {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 1;
}
.particle {
position: absolute;
width: 3px;
height: 3px;
background: rgba(255, 255, 255, 0.4);
border-radius: 50%;
animation: float 8s ease-in-out infinite;
}
@keyframes float {
0%,
100% {
transform: translateY(0px) rotate(0deg);
opacity: 0.4;
}
50% {
transform: translateY(-80px) rotate(180deg);
opacity: 0.8;
}
}
.container {
position: relative;
z-index: 2;
padding: 0;
margin: 0;
width: 100%;
max-width: 500px;
}
.card {
width: 100%;
max-width: 500px;
margin: 0 20px;
border: none;
box-shadow:
0 25px 50px rgba(0, 0, 0, 0.2),
0 0 0 1px rgba(255, 255, 255, 0.1);
border-radius: 24px;
backdrop-filter: blur(20px);
background: rgba(255, 255, 255, 0.95);
overflow: hidden;
animation: slideUp 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(50px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.wrapper {
background: linear-gradient(135deg, #667eea, #764ba2);
padding: 30px 5px;
position: relative;
overflow: hidden;
}
.wrapper::before {
content: '';
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: radial-gradient(circle, rgba(255, 255, 255, 0.1) 0%, transparent 70%);
animation: rotate 20s linear infinite;
}
@keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.title {
color: #fff;
text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
text-align: center;
font-weight: 700;
font-size: 28px;
position: relative;
z-index: 1;
}
.card-body {
padding: 40px;
background: rgba(255, 255, 255, 0.98);
}
.field {
margin-top: 30px;
position: relative;
}
.field input.form-control {
height: 60px;
width: 100%;
font-size: 18px;
padding: 0 20px;
border: 2px solid #e1e5e9;
border-radius: 16px;
transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(10px);
font-weight: 400;
}
.field input.form-control:focus {
border-color: #667eea;
box-shadow: 0 0 0 4px rgba(102, 126, 234, 0.15);
outline: none;
transform: translateY(-2px);
background: rgba(255, 255, 255, 1);
}
.field input.form-control:valid {
border-color: #10b981;
}
.field label {
position: absolute;
top: 50%;
left: 20px;
color: #9ca3af;
font-size: 16px;
font-weight: 400;
pointer-events: none;
transform: translateY(-50%);
transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
background: rgba(255, 255, 255, 0.9);
padding: 0 8px;
z-index: 5;
}
.field input.form-control:focus~label,
.field input.form-control:valid~label,
.field input.form-control:not(:placeholder-shown)~label {
top: 0;
font-size: 13px;
font-weight: 600;
color: #667eea;
transform: translateY(-50%);
left: 15px;
background: rgba(255, 255, 255, 1);
}
.field button {
height: 60px;
border: none;
border-radius: 16px;
background: linear-gradient(135deg, #667eea, #764ba2);
color: #fff;
font-size: 18px;
font-weight: 600;
transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
position: relative;
overflow: hidden;
cursor: pointer;
}
.field button::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 0;
height: 0;
background: rgba(255, 255, 255, 0.2);
border-radius: 50%;
transition: all 0.4s ease;
transform: translate(-50%, -50%);
}
.field button:hover::before {
width: 300px;
height: 300px;
}
.field button:hover {
background: linear-gradient(135deg, #556cd6, #6d4294);
transform: translateY(-3px);
box-shadow: 0 20px 40px rgba(102, 126, 234, 0.4);
}
.field button:active {
transform: translateY(-1px);
}
.field button:disabled {
opacity: 0.7;
cursor: not-allowed;
transform: none;
}
.field button:disabled:hover {
transform: none;
box-shadow: none;
}
.alert {
margin-top: 20px;
border-radius: 12px;
padding: 16px 20px;
font-weight: 500;
border: none;
animation: slideIn 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
@keyframes slideIn {
from {
opacity: 0;
transform: translateY(-15px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.alert-danger {
background: linear-gradient(135deg, #fef2f2, #fee2e2);
color: #dc2626;
border-left: 4px solid #dc2626;
}
.alert-success {
background: linear-gradient(135deg, #f0fdf4, #dcfce7);
color: #16a34a;
border-left: 4px solid #16a34a;
}
@media screen and (max-width: 768px) {
.card {
width: calc(100% - 40px);
margin: 0 20px;
}
.card-body {
padding: 25px 20px;
}
.title {
font-size: 22px;
}
.field input.form-control {
height: 55px;
font-size: 16px;
}
.field button {
height: 55px;
font-size: 16px;
}
}
/* Loading animation */
.loading {
display: inline-block;
width: 20px;
height: 20px;
border: 2px solid rgba(255, 255, 255, 0.3);
border-radius: 50%;
border-top-color: white;
animation: spin 0.8s linear infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
Explanation
- Particle animation is created as background.
- Form is given soft shadow, blur effect and rounded design.
- Input field labels are animated (floating labels).
- Buttons are given hover animation and loading spinner.
- Alert box (success/error) is custom designed.
JavaScript code: Validation logic
This code validates the email input of the form. If the email is in the wrong format, an error message will appear, and if it is correct, a success message will appear.
function createParticles() {
const particlesContainer = document.querySelector('.particles');
const particleCount = 30;
for (let i = 0; i < particleCount; i++) {
const particle = document.createElement('div');
particle.className = 'particle';
particle.style.left = Math.random() * 100 + '%';
particle.style.top = Math.random() * 100 + '%';
particle.style.animationDelay = Math.random() * 8 + 's';
particle.style.animationDuration = (Math.random() * 4 + 4) + 's';
particlesContainer.appendChild(particle);
}
}
// Initialize particles
createParticles();
const emailInput = document.getElementById('email');
const errorRow = document.getElementById('errorRow');
const successRow = document.getElementById('successRow');
const errorDiv = document.getElementById('error');
const successDiv = document.getElementById('success');
const btnText = document.getElementById('btnText');
const submitBtn = document.querySelector('button[onclick="validation()"]');
function validation() {
const email = emailInput.value.trim();
const emailRegex = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
// Hide previous alerts
errorRow.style.display = 'none';
successRow.style.display = 'none';
btnText.innerHTML = '<div class="loading"></div>';
submitBtn.disabled = true;
setTimeout(() => {
if (email === '') {
errorDiv.textContent = 'Please enter the email.';
errorRow.style.display = 'block';
} else if (!emailRegex.test(email)) {
errorDiv.textContent = 'Please enter a valid email.';
errorRow.style.display = 'block';
} else {
successDiv.textContent = `Your ${email}! Form submitted successfully.`;
successRow.style.display = 'block';
setTimeout(() => {
emailInput.value = '';
emailInput.style.borderColor = '#e1e5e9';
successRow.style.display = 'none';
}, 3000);
}
btnText.textContent = 'SUBMIT';
submitBtn.disabled = false;
}, 1500);
}
emailInput.addEventListener('keypress', function (e) {
if (e.key === 'Enter') {
validation();
}
});
Explanation
- createParticles() function creates animated dots (particles) on the page.
- validate() function checks the email against a regex.
- Error alert on wrong email, success message on correct email.
- setTimeout() is loading animation (for real time effect).
- Form is also validated on pressing enter key.
Conclusion
What we taught in this article:
- How to do email validation with JavaScript.
- How the right combination of HTML, CSS and JavaScript makes a professional level form.
- How animations and interactivity improve user experience.
If you are a beginner, this is a perfect practice project. You can make it more advanced as well - like API integration, backend submission, multiple field validation.