Project preview
Folder Structure:
- First we will need to create main folder for our project
- Then inside it we will create html css and js files
- At last we will link css and js files with html file
Introduction:
In this project we will create a login form with form validation using HTML CSS JavaScript. It provides a user-friendly interface that includes input fields for email and password, alongside real-time validation to ensure the data entered is correct. The form checks if the email and password fields are left blank and validates the email format. It also adds visual feedback like error messages and a shake animation for invalid inputs. The form is styled with modern CSS techniques, including gradient buttons and animated borders on focus, enhancing the overall user experience.
HTML Code:
.... <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Form Validation in Html CSS JavaScript</title> <link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css"> </head> <body> <div class="wrapper"> <h2>Login</h2> <form action=""> <div class="field email"> <div class="input-area"> <input type="text" placeholder="Email Address" class="input-form"> <i class="icon fas fa-envelope"></i> <i class="error error-icon fas fa-circle-exclamation"></i> </div> <p class="error error-txt">Email can't be blank</p> </div> <div class="field password"> <div class="input-area"> <input type="password" placeholder="Password" class="input-form"> <i class="icon fas fa-lock"></i> <i class="error error-icon fas fa-circle-exclamation"></i> </div> <p class="error error-txt">Password can't be blank</p> </div> <div class="pass-link"><a href="">Forgot Password</a></div> <input type="submit" value="Login"> </form> <div class="signup-link">Don't have an account? <a href="">Signup Now</a></div> </div> <script src="script.js"></script> </body> </html> ...
Explanation:
The body of the document is wrapped inside a <div>
with the class wrapper
, which acts as a container for the form elements. The heading <h2>
displays the title “Login”.
The <form>
tag is used to define the login form itself, although no action or method is specified, meaning the form doesn’t submit data to the server. Inside the form, there are two main fields: one for the email and one for the password, both structured similarly using a <div>
with class field
.
Each field contains an input field, placeholder text, Font Awesome icons for visual feedback, and a hidden error message (<p>
tags with the class error-txt
) that will display validation messages when triggered.
For each field, the user sees an input box where they can type their email and password. If the fields are left blank or the email format is incorrect, error messages like “Email can’t be blank” or “Enter a valid email address” will appear. Additionally, a “Forgot Password” link is provided under the password field.
Finally, the form includes a submit button, styled as a colorful gradient, which users click to attempt to log in. Below the form, there’s also a link encouraging users to sign up if they don’t already have an account.
Lastly, the script for the form validation is linked at the bottom with <script src="script.js"></script>
, which ensures client-side validation functionality.
CSS Code:
... @import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap'); /* Base styles */ * { padding: 0; margin: 0; box-sizing: border-box; font-family: "Poppins", sans-serif; font-style: normal; } html, body { display: grid; height: 100%; place-items: center; background: #121125; } .wrapper { width: 380px; background: #121125; border-radius: 17px; text-align: center; padding: 20px 30px; box-shadow: 0px 5px 20px 10px rgba(0, 0, 0, 0.2); color: #fff; } .wrapper h2 { font-size: 35px; font-weight: 600; } .wrapper form { margin: 20px 0; } form .field.shake { animation: shake 0.3s ease-in-out; } @keyframes shake { 0%, 100% { margin-left: 0; } 20%, 80% { margin-left: -12px; } 40%, 60% { margin-left: 12px; } } form .field { width: 100%; margin-bottom: 20px; } form .field .input-area { position: relative; } form input { position: relative; width: 100%; outline: none; border: 0; color: #fff; padding: 12px 15px; font-size: 16px; background-color: transparent; border-radius: 5px; border: 1px solid #34495e; border-bottom-width: 2px; overflow: hidden; } form .input-form { padding-left: 45px; font-size: 15px; } form input::placeholder { color: #bfbfbf; font-size: 12px; letter-spacing: 1px; } form .field i { position: absolute; top: 50%; font-size: 16px; pointer-events: none; transform: translateY(-50%); } form .field .icon { left: 15px; color: #bfbfbf; } input:is(:focus) { border: 2px solid transparent; background: linear-gradient(#121125, #121125) padding-box, linear-gradient(45deg, blue, red) border-box; border-radius: 5px; transition: all 0.1s ease; } form .field .error-icon { right: 15px; color: #dc3545; } form .field .error-txt { color: #dc3545; font-size: 12px; text-align: left; margin-top: 10px; } form .field .error { display: none; } form .field.error .error { display: block; } form .pass-link { text-align: right; margin-top: -10px; font-size: 12px; } .wrapper a { color: #a4a6a8; text-decoration: none; font-weight: 600; } .wrapper a:hover { text-decoration: underline; } form input[type="submit"] { border: 0; outline: none; margin-top: 30px; background: linear-gradient(45deg, blue, red); color: #fff; font-size: 14px; cursor: pointer; text-transform: uppercase; transition: all 0.2s ease; } form input[type="submit"]:hover { background: linear-gradient(65deg, blue, red); } .signup-link { font-size: 12px; font-weight: 300; color: #bfbfbf; } .signup-link a { color: rgb(166, 0, 255); } ...
Explanation:
It starts by importing the Poppins font from Google Fonts, ensuring a clean and modern typeface throughout the form. The universal selector *
resets the margin, padding, and box-sizing of all elements, providing a consistent starting point across different browsers.
The html and body are set to display as a grid, using place-items: center
to vertically and horizontally center the form on the page. The background color of the entire page is set to a dark shade #121125
, which provides contrast with the white text and form elements.
The .wrapper
class, which contains the form, has a fixed width of 380px and a dark background to match the overall page theme. It is styled with rounded corners (border-radius: 17px
) and a subtle shadow effect (box-shadow
), which gives the form a slight elevation, making it stand out.
The text inside the wrapper is centered, and the white color (#fff
) ensures readability against the dark background. The h2
tag inside the wrapper is styled to have a large font size (35px
) and a bold weight (600
), drawing attention to the “Login” heading.
The form fields are styled using the .field
class. Each field contains an input box, which is set to be 100% wide, making it responsive and filling the available space.
The input fields have no border by default but are given a transparent background and white text to maintain consistency with the overall design. The bottom border is slightly thicker to create a visual distinction.
A :focus
state is added to the input fields to apply a border gradient effect when a user clicks on a field, transitioning from a dark color to a vibrant gradient of blue and red. This gives the form an interactive and dynamic feel.
Error handling is also styled effectively. The error messages are hidden by default using .error { display: none; }
but are revealed when a field contains invalid input.
The error icon and message text are colored in red (#dc3545
), ensuring they stand out against the dark background, and the error message text is slightly smaller to fit well within the layout. Additionally, a shake animation is applied to fields with invalid inputs, giving visual feedback that the user needs to correct something. The animation moves the field left and right, making the form more responsive to user actions.
The submit button has a vibrant gradient background of blue and red, making it eye-catching. When hovered, it changes slightly (background: linear-gradient(65deg, blue, red)
), adding an interactive element to the button.
The links (for forgotten passwords and signup) use a light gray color and hover effects to encourage interaction. Overall, the CSS styles are clean, modern, and responsive, ensuring that the form is functional and visually appealing across different devices and screen sizes.
JavaScript Code:
... const form = document.querySelector("form"), eField = form.querySelector(".email"), eInput = eField.querySelector("input"), pField = form.querySelector(".password"), pInput = pField.querySelector("input"); form.onsubmit = (e) => { e.preventDefault(); if (eInput.value === "") { setError(eField, "Email can't be blank"); } else { checkEmail(); } if (pInput.value === "") { setError(pField, "Password can't be blank"); } setTimeout(() => { eField.classList.remove("shake"); pField.classList.remove("shake"); }, 500); function checkEmail() { let pattern = /^[^ ]+@[^ ]+\.[a-z]{2,3}$/; if (!eInput.value.match(pattern)) { setError(eField, "Enter a valid email address"); } else { removeError(eField); } } pInput.onkeyup = () => { if (pInput.value === "") { setError(pField, "Password can't be blank"); } else { removeError(pField); } }; if ( !eField.classList.contains("error") && !pField.classList.contains("error") ) { window.location.href = "#"; } }; function setError(field, message) { field.classList.add("shake", "error"); let errorTxt = field.querySelector(".error-txt"); errorTxt.innerText = message; } function removeError(field) { field.classList.remove("shake", "error"); let errorTxt = field.querySelector(".error-txt"); errorTxt.innerText = ""; } ...
Explanation:
The JavaScript code is responsible for validating the login form in real-time, ensuring the user inputs valid data before submission. The code begins by selecting the necessary elements from the DOM using document.querySelector()
.
Specifically, it targets the form, email field, and password field, along with their respective input elements. These selections are stored in variables (form
, eField
, eInput
, pField
, pInput
), making it easy to access and manipulate them later.
When the form is submitted, an onsubmit
event listener is triggered, which first calls e.preventDefault()
to prevent the form from actually submitting and reloading the page. Inside this event listener, the code checks whether the email and password fields are empty.
If the email input (eInput.value
) is blank, the setError
function is called, passing the email field and an error message (“Email can’t be blank”). This function adds the shake
and error
classes to the email field, causing both the shake animation and the error message to display. The same logic is applied to the password field to show an error if it is blank.
Next, the script checks whether the email entered follows a valid format. This is done using a regular expression (pattern = /^[^ ]+@[^ ]+\.[a-z]{2,3}$/
) inside the checkEmail
function.
If the email does not match the pattern, an error message (“Enter a valid email address”) is displayed. If the email is valid, the removeError
function is called to remove any existing error states and hide the error message.
For real-time validation, the script listens for a keyup
event on the password input field. As soon as the user starts typing, the script checks if the field is still empty, and if not, it removes any error state.
Finally, the script checks if both the email and password fields are valid (i.e., neither has the error
class). If both fields are valid, the form will redirect the user to a new page or trigger some action (window.location.href = "#";
), simulating a successful form submission.
The helper functions setError
and removeError
manage the visual feedback for errors. The setError
function adds the error message and triggers the shake animation, while the removeError
function clears these styles once the user corrects the input.
Together, these functions ensure the form provides interactive, real-time feedback to the user, making the login experience more intuitive and error-free.
Source Code:
Download “Login-Form-Validation.zip” Login-Form-Validation.zip – Downloaded 0 times – 2.93 KB
Conclusions:
In conclusion, this login form project effectively demonstrates how to combine HTML, CSS, and JavaScript to create a user-friendly, visually appealing, and functional form with real-time validation. The use of Font Awesome icons and animations enhances the form’s interactivity, while the gradient effects and modern design provide a professional look. The JavaScript code ensures that users receive instant feedback on their input, preventing errors and improving usability. With the combination of a dynamic interface and robust client-side validation, this project is a great example of enhancing user experience in web forms. It also serves as a solid foundation for more complex form validation processes.