Modern Sign Up Page with HTML, CSS & JavaScript

Faraz

By Faraz -

Learn how to build a modern sign-up page using HTML, CSS, and JavaScript. Step-by-step guide with smooth design, animations & validations. Easy for beginners.


modern-sign-up-page-with-html-css-and-javascript.webp

Table of Contents

  1. Project Introduction
  2. HTML Code
  3. CSS Code
  4. JavaScript Code
  5. Conclusion
  6. Preview

In today’s digital world, user-friendly and attractive sign-up pages are very important for any website or app. A well-designed form not only helps users register smoothly but also improves your brand’s image.

In this blog, you’ll learn how to create a modern sign-up page using HTML, CSS, and JavaScript with a fresh design, responsive layout, input validations, and smooth animations.

Let’s begin by checking what you need to know first.

Prerequisites

To follow this tutorial, you should have basic knowledge of:

  • HTML – Structure of the webpage
  • CSS – Styling the layout and animation
  • JavaScript – Validating user input and interaction
  • A code editor like VS Code
  • A browser like Chrome to test your page

Source Code

Step 1 (HTML Code):

To get started, we first need to create a basic HTML file. In this file, we will include the main structure for our sign up page. Let's break down the HTML code step by step:

<head> Section Breakdown

<!DOCTYPE html>
  • Declares the document type. It tells the browser that this is an HTML5 page.
<html lang="en">
  • Starts the HTML document. lang="en" means the language is English.

Metadata & External Styles

<meta charset="UTF-8">
  • Sets the character encoding (supports most languages and symbols).
<meta name="viewport" content="width=device-width, initial-scale=1.0">
  • Makes the layout responsive on mobile devices.
<title>Modern Signup Form</title>
  • Sets the title that appears on the browser tab.

External CSS & Fonts

<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
  • Imports Bootstrap 5 styles for layout and responsive design.
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
  • Loads Font Awesome for icons like moon 🌙, paper plane, etc.
<link href="https://fonts.googleapis.com/css2?family=Poppins&display=swap" rel="stylesheet">
  • Uses Google Fonts (Poppins) for clean, modern text.
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css">
  • Enables Animate.css, which adds animation classes like animate__fadeInLeft.
<link rel="stylesheet" href="styles.css">
  • Links to a custom CSS file where personal styles are written.

<body> Section Breakdown

Theme Toggle

<div class="theme-toggle animate__animated animate__fadeIn">
    <i class="fas fa-moon"></i>
</div>
  • A moon icon that could be used to toggle between dark and light modes.
  • It uses a fade-in animation on load.

Main Container: Sign-Up Layout

<div class="registration-container">
  • Wraps the entire layout, which has two main parts:
    • Left: The registration form.
    • Right: A hero section with features/benefits.

Registration Form Section (Left Side)

<div class="registration-form animate__animated animate__fadeInLeft">
  • Contains the form.
  • Uses Animate.css for a left-side entrance animation.

Form Fields

Company Name & Country

html
<input type="text" class="form-control" id="companyName" ... >
<select class="form-select" id="country">
  • Collects company name and country using a text field and a dropdown.

Contact Person

<input type="text" class="form-control" id="contactPerson" ... >
  • Collects the name of the contact person.

Email & Phone

<input type="email" id="companyEmail">  
<input type="tel" id="telephone">
  • Collects company email (required) and optional phone number.

CAPTCHA Verification

<span class="captcha-code" id="captchaDisplay">A7B9C2</span>
<button id="refreshCaptcha">🔄</button>
<input type="text" id="captchaInput" ... >
  • Displays a CAPTCHA code to prove the user is human.
  • Includes a reload button to get a new CAPTCHA.

Form Buttons

<button type="submit">Submit</button>  
<button type="reset">Reset</button>
  • Submit the form.
  • Reset clears all fields.
  • Both buttons use icons and Bootstrap button styles.

Sign-In Prompt

<p>Already registered? <a href="#">Sign in here</a></p>
  • Text for users who already have an account.

Hero Section (Right Side)

<div class="registration-hero animate__animated animate__fadeInRight">
  • Right side of the page, used for branding and marketing.

Floating Background Shapes

<div class="shape" style="width: 100px; height: 100px; top: 20%; left: 10%;"></div>
  • Decorative animated shapes in the background.
  • Positioned absolutely with inline styles.

Hero Content

<h2>Grow Your Real Estate Business</h2>
<p>Discover verified property listings...</p>
  • Catchy headline and short paragraph promoting the platform.

Badges with Icons

<span class="badge"><i class="fas fa-check-circle"></i> Verified Listings</span>
  • Uses badges to highlight features (e.g., verified listings, instant alerts).

Scripts at the Bottom

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
  • Loads Bootstrap JavaScript for components like dropdowns.
<script src="script.js"></script>
  • Loads your custom JavaScript (handles form validation and CAPTCHA logic).

Step 2 (CSS Code):

Once the basic HTML structure of the signup form is in place, the next step is to add styling to the form using CSS. Here's a section-by-section explanation:

1. CSS Variables (:root)

:root {
  --primary: #4361ee;
  --secondary: #3f37c9;
  --accent: #f72585;
  --dark: #212529;
  --light: #f8f9fa;
  --border-radius: 12px;
  --box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}
  • Defines custom properties (variables) used throughout the CSS for:
  • Colors (primary, secondary, accent, etc.)
  • Border radius for rounded corners
  • Box shadow for soft depth effects

2. Base Styles for body

body {
  font-family: 'Poppins', sans-serif;
  background-color: var(--light);
  color: var(--dark);
  min-height: 100vh;
  margin: 0;
  overflow-x: hidden;
}
  • Sets font to Google’s Poppins
  • Applies a light background and dark text
  • Ensures full viewport height and prevents horizontal scroll

3. Dark Mode Toggle

.dark-mode {
  background-color: #121212;
  color: #f5f5f5;
}
  • Applies dark background and light text when .dark-mode is added to <body> by JavaScript

4. Layout: .registration-container

.registration-container {
  display: flex;
  min-height: 100vh;
}
  • Flex container to split the page into two columns (form and hero)
  • Takes full height of the viewport

5. Left Side: .registration-form

.registration-form {
  flex: 1;
  padding: 4rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
  background-color: white;
}
  • Form section on the left
  • Padded, vertically centered content
  • White background in light mode
  • In dark mode, background becomes dark and text turns white

6. Right Side: .registration-hero

.registration-hero {
  flex: 1;
  background: linear-gradient(135deg, var(--primary), var(--secondary));
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  color: white;
}
  • Visual section with a gradient background
  • Centers content both vertically and horizontally
  • Holds the floating shapes and hero message

7. Hero Content & Animations

.floating-shapes .shape {
  position: absolute;
  background: white;
  border-radius: 50%;
  animation: float 15s infinite ease-in-out;
}

@keyframes float {
  0%, 100% {
    transform: translateY(0) rotate(0deg);
  }
  50% {
    transform: translateY(-20px) rotate(10deg);
  }
}
  • Decorative floating white circles that move up/down and rotate
  • Enhances the visual appeal of the hero section

8. Form Inputs Styling

.form-control {
  border-radius: var(--border-radius);
  padding: 0.75rem 1rem;
  border: 1px solid #e0e0e0;
  transition: all 0.3s ease;
}

.form-control:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 0.25rem rgba(67, 97, 238, 0.25);
}
  • Modern styled input fields with rounded corners and smooth focus effect
  • Dark mode versions apply darker backgrounds and lighter text

9. Buttons: Submit & Reset

.btn-primary {
  background: linear-gradient(135deg, var(--primary), var(--secondary));
  border-radius: var(--border-radius);
  padding: 0.75rem 1.5rem;
  font-weight: 600;
  transition: all 0.3s ease;
}
  • Submit button uses a gradient style
  • Reset button is bordered and changes background on hover
  • Dark mode modifies hover backgrounds

10. CAPTCHA Styling

.captcha-container {
  background-color: #f8f9fa;
  border-radius: var(--border-radius);
  padding: 1rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.captcha-code {
  font-family: 'Courier New', monospace;
  font-weight: 700;
  letter-spacing: 3px;
  color: var(--primary);
}
  • Displays CAPTCHA in a styled box
  • Uses monospace font to look like classic code/text
  • btn-reload rotates on hover and changes color in dark mode

11. Theme Toggle Button

.theme-toggle {
  position: fixed;
  top: 20px;
  right: 20px;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 50%;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
  • Floating moon/sun icon for dark mode toggle
  • Positioned top-right with slight transparency
  • Changes color based on the theme

12. Responsive Design (@media)

@media (max-width: 992px) {
  .registration-container {
    flex-direction: column;
  }
  .registration-hero {
    padding: 3rem 1rem;
  }
  .registration-form {
    padding: 2rem;
  }
}
  • On smaller screens:
    • Converts layout from two-column to stacked (top-to-bottom)
    • Reduces padding for better mobile spacing
:root {
  --primary: #4361ee;
  --secondary: #3f37c9;
  --accent: #f72585;
  --dark: #212529;
  --light: #f8f9fa;
  --border-radius: 12px;
  --box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}

body {
  font-family: 'Poppins', sans-serif;
  background-color: var(--light);
  color: var(--dark);
  min-height: 100vh;
  margin: 0;
  overflow-x: hidden;
}

.dark-mode {
  background-color: #121212;
  color: #f5f5f5;
}

.registration-container {
  display: flex;
  min-height: 100vh;
}

.registration-form {
  flex: 1;
  padding: 4rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
  background-color: white;
}

.dark-mode .registration-form {
  background-color: #1e1e1e;
  color: #fff;
}

.registration-hero {
  flex: 1;
  background: linear-gradient(135deg, var(--primary), var(--secondary));
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  color: white;
  position: relative;
  overflow: hidden;
}

.hero-content {
  z-index: 2;
  text-align: center;
}

.hero-content h1 {
  font-weight: 700;
  margin-bottom: 1rem;
  font-size: 2.5rem;
}

.hero-content p {
  opacity: 0.9;
  font-size: 1.1rem;
}

.floating-shapes {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  z-index: 1;
  opacity: 0.1;
}

.shape {
  position: absolute;
  background: white;
  border-radius: 50%;
  animation: float 15s infinite ease-in-out;
}

@keyframes float {
  0%,
  100% {
    transform: translateY(0) rotate(0deg);
  }
  50% {
    transform: translateY(-20px) rotate(10deg);
  }
}

.form-title {
  font-weight: 700;
  margin-bottom: 1.5rem;
  font-size: 2rem;
  color: var(--primary);
}

.dark-mode .form-title {
  color: var(--accent);
}

.form-control {
  border-radius: var(--border-radius);
  padding: 0.75rem 1rem;
  border: 1px solid #e0e0e0;
  transition: all 0.3s ease;
}

.dark-mode .form-control {
  background-color: #2d2d2d;
  border-color: #444;
  color: #fff;
}

.form-control:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 0.25rem rgba(67, 97, 238, 0.25);
}

.dark-mode .form-control:focus {
  box-shadow: 0 0 0 0.25rem rgba(247, 37, 133, 0.25);
}

.form-floating label {
  color: #6c757d;
}

.dark-mode .form-floating label {
  color: #aaa;
}

.btn-primary {
  background: linear-gradient(135deg, var(--primary), var(--secondary));
  border: none;
  border-radius: var(--border-radius);
  padding: 0.75rem 1.5rem;
  font-weight: 600;
  transition: all 0.3s ease;
}

.btn-primary:hover {
  transform: translateY(-2px);
  box-shadow: 0 5px 15px rgba(67, 97, 238, 0.3);
}

.btn-outline-secondary {
  border-radius: var(--border-radius);
  padding: 0.75rem 1.5rem;
  transition: all 0.3s ease;
}

.btn-outline-secondary:hover {
  background-color: #f8f9fa;
}

.dark-mode .btn-outline-secondary:hover {
  background-color: #333;
}

.captcha-container {
  background-color: #f8f9fa;
  border-radius: var(--border-radius);
  padding: 1rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.dark-mode .captcha-container {
  background-color: #2d2d2d;
}

.captcha-code {
  font-family: 'Courier New', monospace;
  font-weight: 700;
  letter-spacing: 3px;
  color: var(--primary);
}

.dark-mode .captcha-code {
  color: var(--accent);
}

.btn-reload {
  background: none;
  border: none;
  color: var(--primary);
  transition: transform 0.3s ease;
}

.dark-mode .btn-reload {
  color: var(--accent);
}

.btn-reload:hover {
  transform: rotate(90deg);
}

.theme-toggle {
  position: fixed;
  top: 20px;
  right: 20px;
  z-index: 1000;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 50%;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.3s ease;
}

.theme-toggle:hover {
  background: rgba(255, 255, 255, 0.3);
}

.dark-mode .theme-toggle {
  background: rgba(0, 0, 0, 0.2);
}

.dark-mode .theme-toggle:hover {
  background: rgba(0, 0, 0, 0.3);
}

@media (max-width: 992px) {
  .registration-container {
    flex-direction: column;
  }
  .registration-hero {
    padding: 3rem 1rem;
  }
  .registration-form {
    padding: 2rem;
  }
} 

Step 3 (JavaScript Code):

Finally, we need to create a function in JavaScript. Let's break down the JS code step by step:

1. Dark/Light Mode Toggle

const themeToggle = document.querySelector('.theme-toggle');
themeToggle.addEventListener('click', () => {
  document.body.classList.toggle('dark-mode');
  const icon = themeToggle.querySelector('i');
  if (document.body.classList.contains('dark-mode')) {
    icon.classList.replace('fa-moon', 'fa-sun');
  } else {
    icon.classList.replace('fa-sun', 'fa-moon');
  }
});
  • Adds a click event to the moon icon (.theme-toggle).
  • When clicked:
    • It toggles a dark-mode class on the <body>.
    • Changes the icon from 🌙 (fa-moon) to ☀️ (fa-sun) and vice versa.
  • You can use the dark-mode class in your CSS to define dark theme styles.

2. Generate CAPTCHA

function generateCaptcha() {
  const chars = '0123456789ABCDEFGHJKLMNPQRSTUVWXYZ';
  let captcha = '';
  for (let i = 0; i < 6; i++) {
    captcha += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  return captcha;
}
  • Creates a random 6-character CAPTCHA code using:
    • Numbers (0–9)
    • Capital letters (A–Z), excluding confusing ones like I and O.
  • Returns the generated code.

3. Initialize CAPTCHA on Page Load

let currentCaptcha = generateCaptcha();
document.getElementById('captchaDisplay').textContent = currentCaptcha;
  • Generates the first CAPTCHA when the page loads.
  • Displays it inside the <span id="captchaDisplay">.

4. Refresh CAPTCHA Button

document.getElementById('refreshCaptcha').addEventListener('click', () => {
  currentCaptcha = generateCaptcha();
  document.getElementById('captchaDisplay').textContent = currentCaptcha;
});
  • When the reload button 🔄 is clicked:
    • Generates a new CAPTCHA.
    • Updates the text inside #captchaDisplay.

5. Form Submission with CAPTCHA Validation

document.getElementById('tenderRegistrationForm').addEventListener('submit', (e) => {
  e.preventDefault();
  const enteredCaptcha = document.getElementById('captchaInput').value.trim();
  if (enteredCaptcha.toUpperCase() !== currentCaptcha) {
    alert('CAPTCHA verification failed. Please try again.');
    currentCaptcha = generateCaptcha();
    document.getElementById('captchaDisplay').textContent = currentCaptcha;
    document.getElementById('captchaInput').value = '';
    return;
  }

  alert('Registration successful! Redirecting to dashboard...');
  // window.location.href = "/dashboard"; // Uncomment for real redirection
});
  • Listens for form submission.
  • Stops the default form action (e.preventDefault()).
  • Compares the user-entered CAPTCHA (converted to uppercase) with the actual CAPTCHA.
    • If wrong → shows an error alert and regenerates CAPTCHA.
    • If correct → shows a success message (you can redirect after this).

6. Phone Number Auto Formatting

document.getElementById('telephone').addEventListener('input', (e) => {
  const x = e.target.value.replace(/\D/g, '').match(/(\d{0,3})(\d{0,3})(\d{0,4})/);
  e.target.value = !x[2] ? x[1] : '+' + x[1] + ' ' + x[2] + (x[3] ? '-' + x[3] : '');
});
  • Listens for typing inside the phone field.
  • Removes all non-numeric characters (\D).
  • Automatically formats the number like:
    • 1234567890 → +123 456-7890
// Dark/Light Mode Toggle
const themeToggle = document.querySelector('.theme-toggle');
themeToggle.addEventListener('click', () => {
  document.body.classList.toggle('dark-mode');
  const icon = themeToggle.querySelector('i');
  if (document.body.classList.contains('dark-mode')) {
    icon.classList.replace('fa-moon', 'fa-sun');
  } else {
    icon.classList.replace('fa-sun', 'fa-moon');
  }
});

// Generate CAPTCHA
function generateCaptcha() {
  const chars = '0123456789ABCDEFGHJKLMNPQRSTUVWXYZ';
  let captcha = '';
  for (let i = 0; i < 6; i++) {
    captcha += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  return captcha;
}

// Initialize CAPTCHA
let currentCaptcha = generateCaptcha();
document.getElementById('captchaDisplay').textContent = currentCaptcha;

// Refresh CAPTCHA
document.getElementById('refreshCaptcha').addEventListener('click', () => {
  currentCaptcha = generateCaptcha();
  document.getElementById('captchaDisplay').textContent = currentCaptcha;
});

// Form Submission
document
  .getElementById('tenderRegistrationForm')
  .addEventListener('submit', (e) => {
    e.preventDefault();

    // Validate CAPTCHA
    const enteredCaptcha = document.getElementById('captchaInput').value.trim();
    if (enteredCaptcha.toUpperCase() !== currentCaptcha) {
      alert('CAPTCHA verification failed. Please try again.');
      currentCaptcha = generateCaptcha();
      document.getElementById('captchaDisplay').textContent = currentCaptcha;
      document.getElementById('captchaInput').value = '';
      return;
    }

    // Success Message (Replace with AJAX submission)
    alert('Registration successful! Redirecting to dashboard...');
    // window.location.href = "/dashboard"; // Uncomment for real redirection
  });

// Phone Input Formatting
document.getElementById('telephone').addEventListener('input', (e) => {
  const x = e.target.value
    .replace(/\D/g, '')
    .match(/(\d{0,3})(\d{0,3})(\d{0,4})/);
  e.target.value = !x[2]
    ? x[1]
    : '+' + x[1] + ' ' + x[2] + (x[3] ? '-' + x[3] : '');
});

Final Output:

modern-sign-up-page-with-html-css-and-javascript.gif

Conclusion:

Building a modern sign-up page using HTML, CSS, and JavaScript is easier than you think. By following this guide, you’ve created a clean and responsive form with smooth animations and validation.

This type of form is perfect for websites, mobile-friendly designs, and user-friendly interfaces.

You can always improve it further by adding animations using GSAP or Framer Motion, or connecting it to your backend system using PHP, Node.js, or any other technology.

That’s a wrap!

I hope you enjoyed this post. Now, with these examples, you can create your own amazing page.

Did you like it? Let me know in the comments below 🔥 and you can support me by buying me a coffee

And don’t forget to sign up to our email newsletter so you can get useful content like this sent right to your inbox!

Thanks!
Faraz 😊

End of the article

Subscribe to my Newsletter

Get the latest posts delivered right to your inbox


Latest Components

Please allow ads on our site🥺