Comic Style Login and Signup Form with HTML, CSS & JavaScript

Faraz

By Faraz -

Learn how to create a comic style single page login and signup form using HTML, CSS, and JavaScript with step-by-step guide and easy code examples.


comic-style-login-and-signup-form-html-css-javascript.webp

Table of Contents

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

Login and signup forms are an important part of every website. Most sites use a simple design, but if you want to make something fun and different, a comic-style login and signup form is a great idea. It makes your site look creative and can keep users interested.

In this guide, we will learn how to make a single-page login and signup form using HTML, CSS, and JavaScript with a cool comic book style. This form will have animations, bold colors, and a flip effect to switch between login and signup.

Prerequisites

Before starting, make sure you know the basics of:

  • HTML → for form structure
  • CSS → for styling and comic effects
  • JavaScript → for form flip and validation

If you already know these, let’s jump into the steps!

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 form. Let's break down the HTML code step by step:

Document Setup

<!DOCTYPE html>
<html lang="en">
<head> ... </head>
<body> ... </body>
</html>
  • DOCTYPE & <html>: Declares the document type and language (en for English).
  • Meta tags:
    • <meta charset="UTF-8"> ensures proper character encoding.
    • <meta name="viewport"...> makes it responsive on mobile devices.
  • Title: "Login & Signup Form" appears in the browser tab.
  • External resources:
    • Lucide Icons via CDN (lucide.js).
    • Google Fonts (Bangers comic-style font and Inter).
    • styles.css: local stylesheet for custom design.

Background Decoration

<div class="background-shapes">
   <svg class="hero-1">...</svg>
   <svg class="hero-2">...</svg>
</div>
  • Two colorful SVG blobs (yellow and red) add playful, comic-like background shapes.
  • Positioned with CSS to give the page an energetic look.

Form Container

<div class="form-container-wrapper" id="form-container">
    <div class="form-panel-bg"></div>
    <span class="flip-sfx font-bangers">FLIP!</span>
    <div class="forms-wrapper"> ... </div>
</div>
  • form-panel-bg: decorative background behind the form.
  • flip-sfx: A comic-style “FLIP!” sound effect when switching between login & signup.
  • forms-wrapper: Holds both login and signup forms.

Login Form

<div id="login-panel" class="form-panel">
   <form id="login-form">
      <h2>Welcome Back!</h2>
      <!-- Input groups -->
      <div class="input-group"> ... </div>
      <div class="input-group"> ... </div>
      <!-- Options -->
      <div class="form-options"> ... </div>
      <!-- Submit button -->
      <button type="submit" class="submit-button login-btn">ZAP!</button>
      <!-- Social logins -->
      <div class="social-login-grid"> ... </div>
      <!-- Switch to signup -->
      <div class="form-footer">
         <p>Not a member? <button class="toggle-form" data-target="signup-panel">Join the Universe!</button></p>
      </div>
   </form>
</div>
  • Input fields for email/username + password, each with validation messages (comic-style error hints).
  • Remember Me checkbox + “Forgot Password?” link.
  • Login button with comic sound effect (“ZAP!”).
  • Social login buttons (Google & Facebook), with a little “whoosh” effect.
  • Footer: Link to switch over to the signup form.

Signup Form

<div id="signup-panel" class="form-panel">
   <form id="signup-form">
      <h2>Join the Universe!</h2>
      <!-- Input groups -->
      <div class="input-group"> ... </div>
      <div class="input-group"> ... </div>
      <div class="input-group"> ... </div>
      <!-- Submit button -->
      <button type="submit" class="submit-button signup-btn">POW! Join Now</button>
      <!-- Social logins -->
      <div class="social-login-grid"> ... </div>
      <!-- Switch to login -->
      <div class="form-footer">
         <p>Already a hero? <button class="toggle-form" data-target="login-panel">Log In!</button></p>
      </div>
   </form>
</div>
  • Fields: Hero Name, Email, Password (with validation messages).
  • Button: “POW! Join Now”.
  • Same social login grid (Google, Facebook).
  • Footer: Button to toggle back to login.

Scripts

<script src="script.js"></script>
  • script.js: This file contains logic to:
    • Handle form toggling (flip between login/signup).
    • Manage form validation.
    • Add fun effects (like the “FLIP!” animation).

Step 2 (CSS Code):

Once the basic HTML structure of the form is in place, the next step is to add styling to the form using CSS. Let's break down the CSS code step by step:

1. CSS Variables (Theme Colors & Backgrounds)

:root {
  --comic-yellow: #FFD900;
  --comic-red: #E62429;
  --comic-blue: #00AEEF;
  --comic-black: #000;
  --comic-white: #fff;
  --facebook-blue: #1877F2;
  --comic-halftone-bg: radial-gradient(circle at 2px 2px, rgba(0,0,0,0.25) 2px, transparent 0);
}
  • Stores colors & patterns for reuse across the stylesheet.
  • --comic-halftone-bg is a dotted halftone texture to mimic retro comic print.

2. Typography

.font-bangers { font-family: 'Bangers', cursive; }
input, button { font-family: inherit; }
  • Special “Bangers” comic font for headings & buttons.
  • Inputs/buttons inherit font from parent for consistency.

3. Animations

  • halftone-burst → makes a dot pattern burst outward (used when clicking buttons).
  • sfx-pop → quick scaling in/out (like “POW!” comic effects).
  • whoosh → shiny streak sweeps across buttons on hover.
  • flip-sfx-pop → scaling + fade in/out for the big “FLIP!” sound effect when switching forms.

4. Body & Background

body {
  background-color: var(--comic-blue);
  background-image: var(--comic-halftone-bg);
  background-size: 8px 8px;
  display: flex; justify-content: center; align-items: center;
}
  • Blue halftone dotted background.
  • Uses flexbox to center the form container.
  • Shapes (.background-shapes) are big, faint SVG blobs positioned in corners.

5. Form Container (3D Flip Card Setup)

.form-container-wrapper {
  perspective: 1500px;
}
.forms-wrapper {
  transform-style: preserve-3d;
  transition: transform 0.7s cubic-bezier(...);
}
  • perspective creates a 3D space.
  • .forms-wrapper holds both login & signup panels like a 3D card.
  • Adding .is-flipped rotates it with a smooth, bouncy transition.

6. Form Panels

.form-panel {
  background: var(--comic-white);
  border: 4px solid var(--comic-black);
  box-shadow: 10px 10px 0 var(--comic-black);
  transform: rotate(-1deg);
}
  • White panels with thick black outlines & shadows → comic page look.
  • #login-panel sits in front, #signup-panel rotated 180° for the flip effect.
  • .form-panel-bg adds a yellow tilted layer behind, like comic paper stacking.

7. Flip Sound Effect Text

.flip-sfx {
  font-size: 4rem;
  color: var(--comic-yellow);
  -webkit-text-stroke: 2px var(--comic-black);
}
  • Big “FLIP!” text styled like comic SFX.
  • Appears/disappears with the flip-sfx-pop animation.

8. Headings

  • Huge red comic-style with text shadows and a radial yellow burst behind.

9. Input Fields

.input-group input {
  border: 3px solid var(--comic-black);
  background-color: #f0f0f0;
}
.input-group input:focus {
  outline: 3px solid var(--comic-yellow);
  transform: scale(1.01);
}
  • Thick borders & slight scale on focus → interactive, bold.
  • Validation messages (.validation-message) appear like comic speech bubbles above the inputs.

10. Checkbox (Remember Me)

  • Hidden native checkbox → replaced with a round bubble.
  • Checked state fills it red + little pop animation.

11. Buttons

.submit-button {
  font-family: 'Bangers';
  transform: skew(-5deg);
  border: 4px solid var(--comic-black);
  text-shadow: 2px 2px 0 var(--comic-black);
}
  • Bold skewed shapes with a comic impact feel.
  • On click → halftone burst (halftone-burst animation).
  • Different colors for login (blue) and signup (red).

12. Social Buttons

  • Styled with strong background colors (Google red, Facebook blue).
  • On hover → white streak “whooshes” across (comic speedline effect).

13. Responsive Adjustments

@media(max-width: 520px) {
  body { align-items: flex-start; }
  .forms-wrapper { min-height: 700px; }
}
  • On smaller screens → taller flexible form, smaller headings/buttons.
  • Social buttons stack vertically instead of side by side.
:root {
  --comic-yellow: #FFD900;
  --comic-red: #E62429;
  --comic-blue: #00AEEF;
  --comic-black: #000;
  --comic-white: #fff;
  --facebook-blue: #1877F2;
  --comic-halftone-bg: radial-gradient(circle at 2px 2px, rgba(0,0,0,0.25) 2px, transparent 0);
}

.font-bangers{
  font-family: 'Bangers', cursive;
}

input, button{
  font-family: inherit;
}

@keyframes halftone-burst {
  0% { transform: scale(0); opacity: 1; }
  100% { transform: scale(2); opacity: 0; }
}

@keyframes sfx-pop {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.2); }
}

@keyframes whoosh {
  0% { transform: translateX(-100%) skewX(-30deg); opacity: 0.5; }
  100% { transform: translateX(100%) skewX(-30deg); opacity: 0; }
}

@keyframes flip-sfx-pop {
   0% { transform: translate(-50%, -50%) scale(0); opacity: 0; }
  50% { transform: translate(-50%, -50%) scale(1.2); opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(0); opacity: 0; }
}

body {
  margin: 0;
  font-family: 'Inter', sans-serif;
  background-color: var(--comic-blue);
  background-image: var(--comic-halftone-bg);
  background-size: 8px 8px;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 2rem;
  box-sizing: border-box;
  position: relative;
}

.background-shapes {
  position: absolute;
  top: 0; left: 0; right: 0; bottom: 0;
  overflow: hidden;
  z-index: 0;
}

.background-shapes svg {
  position: absolute;
  opacity: 0.1;
  filter: blur(1px);
}

.background-shapes .hero-1 {
  bottom: -5%;
  left: -10%;
  width: 40%;
  transform: rotate(10deg);
}
.background-shapes .hero-2 {
  top: -10%;
  right: -15%;
  width: 50%;
  transform: rotate(-15deg);
}


.form-container-wrapper {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: 480px;
  perspective: 1500px;
}

.forms-wrapper {
  position: relative;
  width: 100%;
  height: 720px;
  transition: transform 0.7s cubic-bezier(0.68, -0.55, 0.27, 1.55);
  transform-style: preserve-3d;
}

.form-panel {
  position: absolute;
  width: 100%;
  height: 100%;
  backface-visibility: hidden;
  background: var(--comic-white);
  border: 4px solid var(--comic-black);
  box-shadow: 10px 10px 0 var(--comic-black);
  border-radius: 8px;
  padding: 2rem;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  transform: rotate(-1deg);
}

.form-panel-bg {
  position: absolute;
  width: 100%;
  height: 100%;
  background-color: var(--comic-yellow);
  border: 4px solid var(--comic-black);
  border-radius: 8px;
  transform: rotate(3deg);
  z-index: -1;
}

#login-panel {
  z-index: 2;
  transform: rotateY(0deg) rotate(-1deg);
}

#signup-panel {
  transform: rotateY(180deg) rotate(-1deg);
}

.form-container-wrapper.is-flipped .forms-wrapper {
  transform: rotateY(180deg);
}

.flip-sfx {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0);
  font-size: 4rem;
  color: var(--comic-yellow);
  -webkit-text-stroke: 2px var(--comic-black);
  z-index: 100;
  opacity: 0;
  pointer-events: none;
}

.flip-sfx.visible {
  animation: flip-sfx-pop 0.6s ease-in-out;
}

.form-panel h2 {
  font-family: 'Bangers', cursive;
  font-size: 3rem;
  text-align: center;
  margin-top: 0;
  margin-bottom: 2rem;
  color: var(--comic-red);
  text-shadow: 3px 3px 0 var(--comic-black);
  position: relative;
}

.form-panel h2::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 150%;
  height: 150%;
  background: radial-gradient(circle, transparent 40%, var(--comic-yellow) 40%, var(--comic-yellow) 42%, transparent 42%);
  transform: translate(-50%, -50%);
  z-index: -1;
  opacity: 0.5;
}

.input-group {
  margin-bottom: 1.25rem;
  position: relative;
}

.input-group label {
  display: block;
  font-weight: 700;
  margin-bottom: 0.5rem;
  color: var(--comic-black);
}

.input-group input {
  width: 100%;
  padding: 0.75rem 1rem;
  font-size: 1rem;
  border: 3px solid var(--comic-black);
  border-radius: 4px;
  box-sizing: border-box;
  transition: all 0.2s ease-out;
  background-color: #f0f0f0;
}

.input-group input:focus {
  outline: 3px solid var(--comic-yellow);
  background-color: var(--comic-white);
  transform: scale(1.01);
}

.form-options {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1.5rem;
  font-size: 0.9rem;
}

.checkbox-container {
  display: flex;
  align-items: center;
  cursor: pointer;
}
.checkbox-container input { display: none; }
.checkbox-bubble {
  width: 22px;
  height: 22px;
  border: 3px solid var(--comic-black);
  border-radius: 50%;
  margin-right: 8px;
  position: relative;
  transition: all 0.2s;
}
.checkbox-container input:checked + .checkbox-bubble {
  background-color: var(--comic-red);
  animation: sfx-pop 0.3s;
}

.forgot-password a {
  font-weight: bold;
  color: var(--comic-blue);
  text-decoration: underline;
}

.submit-button {
  width: 100%;
  padding: 1rem;
  font-family: 'Bangers', cursive;
  font-size: 2rem;
  letter-spacing: 0.1em;
  cursor: pointer;
  border: 4px solid var(--comic-black);
  color: var(--comic-white);
  text-shadow: 2px 2px 0 var(--comic-black);
  border-radius: 5px;
  position: relative;
  overflow: hidden;
  transition: all 0.2s ease;
  transform: skew(-5deg);
}
.login-btn { background-color: var(--comic-blue); }
.signup-btn { background-color: var(--comic-red); }

.submit-button:hover {
  transform: skew(-5deg) scale(1.05);
  box-shadow: 6px 6px 0 var(--comic-black);
}

.submit-button::after {
  content: ''; position: absolute; top: 50%; left: 50%;
  width: 10px; height: 10px;
  background-image: var(--comic-halftone-bg);
  background-size: 8px 8px;
  border-radius: 50%;
  transform: scale(0); opacity: 0;
}
.submit-button:active::after {
  animation: halftone-burst 0.4s ease-out;
}

.divider {
  text-align: center;
  margin: 1.25rem 0;
  font-weight: bold;
  color: #888;
  font-family: 'Bangers', cursive;
  letter-spacing: 0.1em;
  font-size: 1.2rem;
}

.social-login-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}

.social-login-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.75rem;
  font-size: 1rem;
  font-weight: 700;
  color: var(--comic-white);
  border: 3px solid var(--comic-black);
  border-radius: 4px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: all 0.2s ease-out;
}
.social-login-btn svg {
  width: 24px;
  height: 24px;
}

.social-login-btn .whoosh-effect {
  position: absolute;
  top: 0; left: 0;
  width: 50px;
  height: 100%;
  background: rgba(255,255,255,0.5);
  transform: translateX(-100%) skewX(-30deg);
}
.social-login-btn:hover .whoosh-effect {
  animation: whoosh 0.75s ease-in-out;
}

.google-btn { background-color: var(--comic-red); }
.facebook-btn { background-color: var(--facebook-blue); }

.form-footer {
  margin-top: auto;
  text-align: center;
  padding-top: 1rem;
}
.form-footer p {
  margin: 0;
}
.form-footer .toggle-form {
  font-family: 'Bangers', cursive;
  font-size: 1.25rem;
  color: var(--comic-blue);
  cursor: pointer;
  letter-spacing: 0.05em;
  background: none;
  border: none;
  padding: 0;
  text-decoration: underline;
}

.validation-message {
  background: var(--comic-red);
  color: var(--comic-white);
  padding: 0.25rem 0.75rem;
  border-radius: 15px 15px 15px 0;
  position: absolute;
  bottom: 100%;
  right: 0;
  margin-bottom: 5px;
  font-family: 'Bangers', cursive;
  font-size: 0.9rem;
  letter-spacing: 0.05em;
  opacity: 0;
  visibility: hidden;
  transition: all 0.3s;
  z-index: 10;
}
.validation-message.visible {
  opacity: 1;
  visibility: visible;
  animation: sfx-pop 0.3s ease-out;
}

@media(max-width: 520px) {
   body {
      padding: 1rem;
      align-items: flex-start;
      padding-top: 2rem;
  }
   .forms-wrapper {
      height: auto;
      min-height: 700px;
   }
   .form-panel {
      padding: 1.5rem;
   }
   .form-panel h2 {
      font-size: 2.25rem;
   }
   .submit-button {
      font-size: 1.5rem;
   }
   .social-login-grid {
       grid-template-columns: 1fr;
   }
   .social-login-btn {
      font-size: 1rem;
   }
} 

Step 3 (JavaScript Code):

The final step in creating a comic style single page login and signup form using HTML, CSS, and JavaScript is to add interactivity to the form using JavaScript. Let's break down the JavaScript code step by step:

1. DOM Ready

document.addEventListener('DOMContentLoaded', () => {
  • Waits until the HTML page is fully loaded before running the code.
  • Ensures all elements (form-container, buttons, etc.) exist before being used.

2. Grab Elements

const formContainer = document.getElementById('form-container');
const toggleButtons = document.querySelectorAll('.toggle-form');
const flipSfx = document.querySelector('.flip-sfx');
  • formContainer → the wrapper that flips between login and signup.
  • toggleButtons → all buttons/links that switch between the two forms.
  • flipSfx → the comic “FLIP!” text effect.

3. Flip Card Logic

toggleButtons.forEach((button) => {
  button.addEventListener('click', () => {
    formContainer.classList.toggle('is-flipped');
    flipSfx.classList.add('visible');
    setTimeout(() => {
      flipSfx.classList.remove('visible');
    }, 600);
  });
});
  • Each toggle button, when clicked:
    1. Toggles is-flipped class → triggers 3D CSS flip animation.
    2. Shows the big comic “FLIP!” text by adding visibility.
    3. Removes visible after 600ms, so it disappears with animation.

4. Form Validation

document.querySelectorAll('form').forEach((form) => {
  form.addEventListener('submit', (e) => {
    e.preventDefault();
    let isValid = true;
    const inputs = form.querySelectorAll('input[required]');
  • For each form (login & signup):
    • Blocks the default browser submit (e.preventDefault()).
    • Loops through all required inputs.

5. Validation Rules

inputs.forEach((input) => {
  const message = input.nextElementSibling;
  let hasError = false;

  // Clear old errors
  if (message && message.classList.contains('validation-message')) {
    message.classList.remove('visible');
  }

  if (input.value.trim() === '') {
    hasError = true;
  } else if (
    input.type === 'email' &&
    !/^\S+@\S+\.\S+$/.test(input.value)
  ) {
    hasError = true;
  } else if (
    input.type === 'password' &&
    input.hasAttribute('minlength') &&
    input.value.length < input.minLength
  ) {
    hasError = true;
  }

  if (hasError) {
    isValid = false;
    if (message && message.classList.contains('validation-message')) {
      message.classList.add('visible');
    }
  }
});
  • Clears old errors (so messages don’t stack up).
  • Checks 3 things:
    1. Empty field ❌
    2. Invalid email ❌ (regex /^\S+@\S+\.\S+$/)
    3. Password too short ❌ (minlength attribute check)
  • If an error → mark the input invalid and show the .validation-message next to it.

6. Successful Submit

if (isValid) {
  console.log('Form submitted successfully!');
}
  • If everything passes, logs a success message.
  • (In a real app, here’s where you’d send the data to a backend API).

7. Lucide Icons

lucide.createIcons();
  • Initializes Lucide (an icon library, like Heroicons/Feather).
  • Makes sure any <i data-lucide="icon-name"> gets converted to SVG icons.
document.addEventListener('DOMContentLoaded', () => {
  const formContainer = document.getElementById('form-container');
  const toggleButtons = document.querySelectorAll('.toggle-form');
  const flipSfx = document.querySelector('.flip-sfx');

  toggleButtons.forEach((button) => {
    button.addEventListener('click', () => {
      formContainer.classList.toggle('is-flipped');
      flipSfx.classList.add('visible');
      setTimeout(() => {
        flipSfx.classList.remove('visible');
      }, 600);
    });
  });

  // Form Validation
  document.querySelectorAll('form').forEach((form) => {
    form.addEventListener('submit', (e) => {
      e.preventDefault();
      let isValid = true;
      const inputs = form.querySelectorAll('input[required]');

      inputs.forEach((input) => {
        const message = input.nextElementSibling;
        let hasError = false;

        // Clear previous errors
        if (message && message.classList.contains('validation-message')) {
          message.classList.remove('visible');
        }

        if (input.value.trim() === '') {
          hasError = true;
        } else if (
          input.type === 'email' &&
          !/^\S+@\S+\.\S+$/.test(input.value)
        ) {
          hasError = true;
        } else if (
          input.type === 'password' &&
          input.hasAttribute('minlength') &&
          input.value.length < input.minLength
        ) {
          hasError = true;
        }

        if (hasError) {
          isValid = false;
          if (message && message.classList.contains('validation-message')) {
            message.classList.add('visible');
          }
        }
      });

      if (isValid) {
        console.log('Form submitted successfully!');
      }
    });
  });

  lucide.createIcons();
});

Final Output:

comic-style-login-and-signup-form-html-css-javascript.gif

Conclusion:

Creating a comic-style single-page login and signup form with HTML, CSS, and JavaScript is not only useful but also fun. With a bold comic look and flip animations, your form will stand out from regular designs.

This step-by-step method showed how to build it with simple code, making it perfect for learning and improving your web design skills. Add your own colors, effects, or sound animations to make it even more unique.

Now your website has a creative login and signup form that users will enjoy using.

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🥺