Source Code

<section class="ssf-hero">
  <div class="ssf-left">
    <span class="ssf-eyebrow">Free 14-day trial</span>
    <h1 class="ssf-h1">Run your whole team from one dashboard</h1>
    <p class="ssf-sub">Plan sprints, track time, and ship releases without switching tabs. No credit card required to start.</p>
    <ul class="ssf-benefits">
      <li><span class="ssf-check">✓</span>Unlimited projects on every plan</li>
      <li><span class="ssf-check">✓</span>Real-time collaboration, built in</li>
      <li><span class="ssf-check">✓</span>Cancel anytime, no lock-in contracts</li>
    </ul>
    <div class="ssf-avatars">
      <div class="ssf-av" style="background:linear-gradient(135deg,#f472b6,#fb7185)">K</div>
      <div class="ssf-av" style="background:linear-gradient(135deg,#818cf8,#6366f1)">R</div>
      <div class="ssf-av" style="background:linear-gradient(135deg,#34d399,#10b981)">T</div>
      <span class="ssf-av-text">Joined by 8,400+ teams this year</span>
    </div>
  </div>

  <div class="ssf-right">
    <form class="ssf-form" id="ssfForm" novalidate>
      <h2 class="ssf-form-title">Create your account</h2>
      <p class="ssf-form-sub">Start your free trial in under a minute.</p>

      <label class="ssf-field">
        <span>Full name</span>
        <input type="text" id="ssfName" name="name" placeholder="Alex Rivera" autocomplete="name">
        <small class="ssf-error" id="ssfNameErr"></small>
      </label>

      <label class="ssf-field">
        <span>Work email</span>
        <input type="email" id="ssfEmail" name="email" placeholder="alex@company.com" autocomplete="email">
        <small class="ssf-error" id="ssfEmailErr"></small>
      </label>

      <label class="ssf-field">
        <span>Password</span>
        <input type="password" id="ssfPassword" name="password" placeholder="At least 8 characters" autocomplete="new-password">
        <small class="ssf-error" id="ssfPasswordErr"></small>
        <div class="ssf-strength" id="ssfStrength"><i></i><i></i><i></i></div>
      </label>

      <button type="submit" class="ssf-submit">Create free account</button>
      <p class="ssf-legal">By continuing you agree to our Terms and Privacy Policy.</p>
      <p class="ssf-success" id="ssfSuccess" role="status"></p>
    </form>
  </div>
</section>

Split-Screen Hero with Signup Form — Free HTML CSS JS Snippet

Split-Screen Hero with Embedded Signup Form · Heroes · Plain HTML, CSS & JS · Live preview

What's included

Features

Real multi-field form
Name, email, and password — not just an email teaser.
Live validation
Per-field errors computed on actual submit, not decorative.
Password strength meter
Recomputed on every keystroke from real input.
Benefit checklist
Scannable bullets instead of a long paragraph.
Social proof row
Overlapping avatars plus a joined-teams count.
Split-screen layout
Pitch on the left, conversion surface on the right.
Responsive collapse
Single column with form still prioritized on mobile.
No dependencies
Vanilla JS validation, no form library required.

About this UI Snippet

Split-Screen Hero with Embedded Signup Form — Real Multi-Field Validation

Screenshot of the Split-Screen Hero with Embedded Signup Form snippet rendered live

Most hero sections that claim to have a "signup form" actually have a single email input — this snippet builds a genuine multi-field account creation form (name, email, password) directly into a split-screen hero, with real client-side validation and a live password-strength meter, not just an email-capture teaser.

Why split-screen, and why a real form

The left column carries the pitch: eyebrow label, headline, subheading, a short benefit list, and a social-proof avatar row. The right column is the conversion surface — a bordered card containing the actual form a visitor fills in to create an account. Putting the form directly in the hero, rather than behind a "Sign up" button that navigates away, removes a click and lets a visitor complete the whole action without ever leaving the page.

Real validation, not a fake success state

The JavaScript listens for the form's submit event, calls preventDefault(), and runs three checks: name length, an email-shape regex, and an 8-character minimum on the password. Each field gets its own inline error message and an .ssf-invalid border state — nothing submits, and no success message appears, until all three checks pass. This is deliberately not a decorative form; wire the same submit handler to a real fetch() call against your signup endpoint and the validation logic stays exactly as-is.

Live password strength meter

As the visitor types into the password field, an input listener recomputes a 0–3 score from length, mixed case, and digit/symbol presence, then toggles a weak/medium/strong class on a three-segment bar — genuine feedback computed from the current value on every keystroke, not a static illustration.

Benefit bullets over generic copy

Rather than one long paragraph, the left column uses a short checklist of concrete benefits ("Unlimited projects on every plan") with a circular checkmark icon — scannable in under two seconds, which matters because a visitor filling out a form on the right needs quick reassurance on the left, not another paragraph to read.

Responsive collapse

At 860px the grid collapses from two columns to one, with the form card stacking beneath the pitch copy and a top border replacing the left border — so the form remains the clear focal point on mobile rather than being squeezed into a narrow sidebar.

Customizing it

Swap the field set for your own signup requirements (add a company field, a plan selector), replace the regex-based email check with your backend's validation rules, and wire the submit handler to a real endpoint. Pair it with hero email capture for a lighter-weight variant, or startup hero for a single-column alternative.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Rather than reverse-engineering the validation flow by hand, paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to walk through exactly how the submit handler blocks submission until all three fields pass, and how the password strength meter's scorePassword function turns length, case, and character-type checks into a 0-3 score. The same assistant is useful for hardening it further — ask whether the email regex is permissive enough for real-world addresses, or whether the password rule should also block common weak passwords via a denylist. It's also a good way to extend the form: ask it to wire the submit handler to a real fetch() call with loading and error states, add a confirm-password field with a match check, or convert the whole thing into a controlled React form with the same validation rules preserved. Treat the code less like a finished artifact and more like a starting point for a conversation.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a split-screen SaaS hero section in plain HTML, CSS, and vanilla JavaScript (no framework, no form library).

Requirements:
- A two-column layout: the left column has an eyebrow label, a large headline, a subheading, a short checklist of 3 benefit bullets each with a small checkmark icon, and a row of overlapping circular avatars next to a "joined by X teams" line; the right column contains a bordered card with a real signup form.
- The form must have three real fields — full name, email, and password — each with its own label, input, and an empty inline error element below it, plus a submit button.
- Add a password strength indicator below the password field made of three small segments that are unfilled by default and fill in with a weak/medium/strong color scheme as the user types, computed live from the actual password value (length, mixed case, and digit-or-symbol presence) via an input event listener — not a static decoration.
- On form submit, prevent the default page navigation, validate all three fields (name at least 2 characters, email matching a standard email-shape regex, password at least 8 characters), and for each field independently show or clear its own inline error message and a red invalid border state on the input.
- Only when every field passes should a green success message appear and the form reset; if any field fails, submission must be blocked and no success message shown.
- Make the two-column grid collapse to a single stacked column below roughly 860px, with the form card remaining the visually prioritized element even when stacked below the pitch copy.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSThe split-screen hero and form render; validation is wired to the form's submit event.
  2. 2
    Try submitting emptyEach field shows its own inline error and a red border.
  3. 3
    Type a passwordWatch the three-segment strength bar update live as you type.
  4. 4
    Submit valid valuesA green success message replaces the form's placeholder state.
  5. 5
    Edit the benefit bulletsUpdate the ssf-benefits list items to your own value props.
  6. 6
    Wire a real endpointReplace the success-message branch with a fetch() call to your signup API.

Real-world uses

Common Use Cases

SaaS signup landing pages
Capture a full account in the hero, no extra page.
Product-led growth funnels
Reduce clicks between ad landing and activated account.
Waitlist-to-account conversion
Pair with coming soon hero copy.
B2B trial signup pages
Benefit bullets speak to buyer, form speaks to user.
Course or membership signup
Swap benefits for curriculum highlights.
Internal tool onboarding
Reuse the validated form pattern for account creation.
Related: Hero with Live Ticking User Counter
See the Hero with Live Ticking User Counter for a related heroes pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

Not by default — the submit handler calls preventDefault(), runs validation, and shows a success message locally so you can see the full interaction. Replace the success-message block with a fetch() POST to your real signup endpoint; the validation logic that gates the submission stays unchanged.

An input listener on the password field runs scorePassword(), which checks three conditions — length of at least 8, presence of both upper and lower case letters, and presence of a digit or symbol — awarding one point each for a 0-3 score. That score maps to a weak/medium/strong class on a three-segment bar, so the meter reflects the password actually typed, recalculated on every keystroke.

On submit, the name field requires at least 2 characters, the email field is tested against a standard email-shape regex (something@something.something), and the password field requires at least 8 characters. Each check independently sets or clears an inline error message and a red .ssf-invalid border on its own input — submission is blocked until all three pass.

Every extra click between a visitor deciding to sign up and completing the form is a chance to lose them. Embedding real fields directly in the hero removes that navigation step entirely — the visitor can go from reading the pitch on the left to a validated account on the right without a page load in between.

Copy an existing .ssf-field label block, give the input a new id, and add a matching small.ssf-error element with its own id. In the JS, add the same setError() pattern inside the submit handler for your new field's validation rule before the final valid check.