|$ curl https://forge-ai.dev/api/markdown?path=docs/components/forms
$cat docs/forms.md
updated Recently·22 min read·published

Forms

CSSHTMLTailwindBootstrapUIIntermediate🎯Free Tools
Introduction

Forms are the primary way users submit data. This guide covers production-ready form patterns in plain HTML/CSS, Tailwind CSS, and Bootstrap — including labels, selects, checkboxes, radios, validation states, floating labels, file uploads, and accessibility.

info

Every form control must have an accessible label. Use <label htmlFor="id"> in React or <label for="id"> in HTML, or nest the input inside the label.
Input with Label

Every input must have an associated label for accessibility. Use the for attribute matching the input id to connect them.

form-inputs
Live
untitled.html
HTML
1<div class="form">
2 <div class="field">
3 <label class="label" for="name2">
4 Full Name
5 </label>
6 <input class="input" id="name2" type="text" placeholder="Enter your name" />
7 </div>
8 <div class="field">
9 <label class="label" for="email2">
10 Email Address
11 </label>
12 <input class="input" id="email2" type="email" placeholder="your@email.com" />
13 <span class="error-msg" id="email-error">
14 <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
15 <circle cx="12" cy="12" r="10"/>
16 <line x1="15" y1="9" x2="9" y2="15"/>
17 <line x1="9" y1="9" x2="15" y2="15"/>
18 </svg>
19 Please enter a valid email
20 </span>
21 </div>
22 <div class="field">
23 <label class="label" for="msg2">
24 Message
25 <span id="msg-count" style="color:#525252;font-weight:400">
26 (0)
27 </span>
28 </label>
29 <textarea class="input" id="msg2" rows="3" placeholder="Write your message..." maxlength="200">
30 </textarea>
31 </div>
32 <button class="btn" style="width:100%" id="submit-btn">
33 Submit
34 </button>
35</div>
preview
Select, Checkbox & Radio

Styled select dropdowns, checkbox inputs, and radio groups using clean CSS. The select uses appearance: none with a custom SVG arrow for consistent cross-browser styling.

form-select
Live
untitled.html
HTML
1<div class="form">
2 <div class="field">
3 <label class="label" for="country">
4 Country
5 </label>
6 <select class="select" id="country">
7 <option>
8 United States
9 </option>
10 <option>
11 Canada
12 </option>
13 <option>
14 United Kingdom
15 </option>
16 <option>
17 Germany
18 </option>
19 <option>
20 Japan
21 </option>
22 </select>
23 </div>
24 <div class="field">
25 <span class="label">
26 Preferences
27 <span id="cb-count" style="color:#525252;font-weight:400">
28 (1 selected)
29 </span>
30 </span>
31 <div class="checkbox-group">
32 <label class="checkbox-label">
33 <input type="checkbox" checked />
34 Email notifications
35 </label>
36 <label class="checkbox-label">
37 <input type="checkbox" />
38 SMS updates
39 </label>
40 <label class="checkbox-label">
41 <input type="checkbox" />
42 Weekly digest
43 </label>
44 </div>
45 </div>
46 <div class="field">
47 <span class="label">
48 Plan
49 </span>
50 <div class="radio-group">
51 <label class="radio-label">
52 <input type="radio" name="plan" checked />
53 Starter
54 </label>
55 <label class="radio-label">
56 <input type="radio" name="plan" />
57 Pro
58 </label>
59 <label class="radio-label">
60 <input type="radio" name="plan" />
61 Enterprise
62 </label>
63 </div>
64 </div>
65</div>
preview
Validation States

Communicate errors, success, and help text clearly. Pair visual indicators with aria-describedby and aria-invalid for screen readers.

validation
Live
untitled.html
HTML
1<div class="form">
2 <div class="field">
3 <label class="label" for="u2">
4 Username
5 </label>
6 <input class="input valid" id="u2" type="text" value="johndoe" aria-invalid="false" aria-describedby="u2-help" />
7 <span class="help ok" id="u2-help">
8 <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
9 <polyline points="20 6 9 17 4 12"/>
10 </svg>
11 Username available
12 </span>
13 </div>
14 <div class="field">
15 <label class="label" for="p2">
16 Password
17 </label>
18 <input class="input input-error" id="p2" type="password" value="123" aria-invalid="true" aria-describedby="p2-err" />
19 <span class="help err" id="p2-err">
20 <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
21 <circle cx="12" cy="12" r="10"/>
22 <line x1="12" y1="8" x2="12" y2="12"/>
23 <line x1="12" y1="16" x2="12.01" y2="16"/>
24 </svg>
25 Must be at least 8 characters
26 </span>
27 </div>
28 <div class="field">
29 <label class="label" for="d2">
30 Bio
31 </label>
32 <textarea class="input" id="d2" rows="2" placeholder="Optional">
33 </textarea>
34 <span class="help" id="d2-help">
35 Max 160 characters
36 </span>
37 </div>
38</div>
preview
Floating Labels

Compact fields where the label floats above the value on focus or when the input is not empty. Great for dense forms.

floating-labels
Live
untitled.html
HTML
1<div class="form">
2 <div class="field floating">
3 <input class="input" id="fl-email" type="email" placeholder=" " />
4 <label class="label" for="fl-email">
5 Email address
6 </label>
7 </div>
8 <div class="field floating">
9 <input class="input" id="fl-password" type="password" placeholder=" " />
10 <label class="label" for="fl-password">
11 Password
12 </label>
13 </div>
14 <button class="btn" style="width:100%">
15 Continue
16 </button>
17</div>
preview
Sign-up Form Layout

A complete sign-up form with grid layout, inline fields, and validation-ready styling. This is a production-ready form card you can drop into any project.

signup-form
Live
untitled.html
HTML
1<div class="form-card">
2 <h2 class="form-title">
3 Create Account
4 </h2>
5 <p class="form-sub">
6 Get started with a free account
7 </p>
8 <div class="row">
9 <div class="field">
10 <label class="label">
11 First Name
12 </label>
13 <input class="input" placeholder="John" />
14 </div>
15 <div class="field">
16 <label class="label">
17 Last Name
18 </label>
19 <input class="input" placeholder="Doe" />
20 </div>
21 </div>
22 <div class="field">
23 <label class="label">
24 Email
25 </label>
26 <input class="input" type="email" placeholder="john@example.com" />
27 </div>
28 <div class="row">
29 <div class="field">
30 <label class="label">
31 Password
32 </label>
33 <div class="pw-wrap">
34 <input class="input" id="pw1" type="password" placeholder="••••••••" />
35 <button class="pw-toggle" data-for="pw1" aria-label="Toggle password">
36 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16">
37 <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/>
38 <circle cx="12" cy="12" r="3"/>
39 </svg>
40 </button>
41 </div>
42 </div>
43 <div class="field">
44 <label class="label">
45 Confirm
46 </label>
47 <div class="pw-wrap">
48 <input class="input" id="pw2" type="password" placeholder="••••••••" />
49 <button class="pw-toggle" data-for="pw2" aria-label="Toggle password">
50 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16">
51 <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/>
52 <circle cx="12" cy="12" r="3"/>
53 </svg>
54 </button>
55 </div>
56 </div>
57 </div>
58 <div class="field">
59 <label class="checkbox-label" style="margin-top:4px">
60 <input type="checkbox" checked />
61 I agree to the
62 <a href="#" style="color:#00FF41">
63 Terms
64 </a>
65 </label>
66 </div>
67 <button class="btn">
68 Create Account
69 </button>
70 <hr class="divider" />
71 <p class="terms">
72 By signing up you agree to our
73 <a href="#">
74 Terms of Service
75 </a>
76 </p>
77</div>
preview
Login Form

A focused login card with email, password, remember-me toggle, and a forgot-password link. Keep it simple and scannable.

login-form
Live
untitled.html
HTML
1<div class="form-card" style="max-width:380px">
2 <h2 class="form-title">
3 Welcome back
4 </h2>
5 <p class="form-sub">
6 Sign in to your account
7 </p>
8 <div class="field">
9 <label class="label" for="lg-email">
10 Email
11 </label>
12 <input class="input" id="lg-email" type="email" placeholder="you@example.com" />
13 </div>
14 <div class="field">
15 <label class="label" for="lg-password">
16 Password
17 </label>
18 <input class="input" id="lg-password" type="password" placeholder="••••••••" />
19 </div>
20 <div class="row-between">
21 <label class="checkbox-label">
22 <input type="checkbox" />
23 Remember me
24 </label>
25 <a href="#" class="link">
26 Forgot password?
27 </a>
28 </div>
29 <button class="btn">
30 Sign In
31 </button>
32 <p class="footer-text">
33 Don't have an account?
34 <a href="#" class="link">
35 Sign up
36 </a>
37 </p>
38</div>
preview
Inline Newsletter Form

A compact single-row form ideal for newsletter signups, search bars, or command inputs. Uses flexbox to keep the button attached to the input.

inline-form
Live
untitled.html
HTML
1<div class="inline-wrap">
2 <input class="inline-input" type="email" placeholder="Enter your email" aria-label="Email" />
3 <button class="inline-btn">
4 Subscribe
5 </button>
6</div>
preview
File Upload

A drag-and-drop style file input using a hidden native input and a styled label. The native control remains accessible and keyboard focusable.

file-upload
Live
untitled.html
HTML
1<div class="upload-wrap">
2 <input class="upload-input" id="file" type="file" />
3 <label class="upload-label" for="file">
4 <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
5 <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
6 <polyline points="17 8 12 3 7 8"/>
7 <line x1="12" y1="3" x2="12" y2="15"/>
8 </svg>
9 <span class="upload-title">
10 Click or drag file to upload
11 </span>
12 <span class="upload-hint">
13 SVG, PNG, JPG up to 2MB
14 </span>
15 </label>
16</div>
preview
Accessibility

Accessible forms are usable forms. Labels, focus states, error announcements, and logical tab order reduce friction for keyboard and screen-reader users.

  • Associate every input with a <label> using htmlFor / for or by nesting the input inside the label.
  • Use aria-invalid and aria-describedby to link inputs to their error messages.
  • Ensure focus indicators are visible — never remove outline without replacing it with a ring or border change.
  • Mark required fields visually and programmatically with the required attribute.
  • Group related controls like radios and checkboxes with <fieldset> and <legend>.
  • Keep error messages specific and actionable; announce them with role="alert" when they appear dynamically.

Community

Get help on Slack, Discord or VIP

Stuck on a guide? Join the community and ask.