Designing UX Forms
1) Principles
1. First the task, then the fields. Forms are a continuation of the user script, not a list of databases.
2. One screen is one goal. Remove anything that does not complete the task.
3. Never lose data. Autosave, restore draft, safe replays.
4. Show "how to." Pre-error rules and examples; validate carefully.
5. Default availability. Labels, focus, contrast, keyboard navigation.
6. Predictable speed. The first response ≤ 100 ms, sending with explicit status and progress.
2) Form information architecture
Purpose → steps → fields. Start with the result (for example, "disbursement") and select the minimum set of fields.
Grouping by meaning: "Personal data," "Payment," "Confirmation." Each group ≤ 6 fields.
Progressive disclosure: show additional fields by condition (toggle/country selection).
The order of the fields is like in the user's head: from the well-known to the complex.
3) Layout and grid
One column for mobile and most tasks is faster in look and tab order.
Two columns are appropriate for short interconnected fields (date/time, name/surname).
The height of the line is 40-48 px, the distance between the fields is 8-12 px (related )/16-24 px (groups).
Label alignment at the top of the field; on the right - do not use for narrow forms.
4) Labels, placeholders, helpers
The label is mandatory. The placeholder is an example, not a replacement.
Place the helper text under the field: rules, format, reference to an example.
Optional fields include "(optional)" instead of "" on required fields.
html
<label for = "iban"> IBAN <span class = "muted"> (optional) </span> </label>
<input id="iban" aria-describedby="iban-help">
<small id = "iban-help "> Format A-Z, 0-9; example: DE89 3704 0044 0532 0130 00 </small>
5) Steps and progress
Multi-Step Forms (ASC/Payouts): 3-5 steps, clear progress "Step 2 of 4."
Save completed steps; Allow to return without data loss.
Navigation buttons: "Back," "Next," the final "Confirm" - always in one place.
6) Input control
Keyboards and attributes: 'type', 'inputmode', 'autocomplete' for the data type.
Use input masks softly (phone, IBAN, PAN, date), store normalized values.
Do not break autocomplete: correct'autocomplete =" given-name" | "cc-number" | "one-time-code"', etc.
Amount presets/shortcuts: "+ 50/+ 100/All" next to the amount field.
7) Validation and errors
Strategy: before entering (helper), during (soft prompts), after (on blur/submit).
Asynchronous checks (uniqueness of the login, limits, risk) - with a debit of 250-400 ms.
Error text: cause → how to fix → alternative.
Summary panel above the form for several errors + focus to the first error.
Idempotency-Key for critical actions (bid/pay) and secure retrays.
8) Buttons and submission
Primary CTA is highlighted in color/size, available by Enter.
'Busy'state and click retry block; at delay> 3-5 s - "Waiting for confirmation...."
After success - explicit status (toast/ready screen) + what happens next.
9) Availability (A11y)
Correct links' label → input ', errors through' aria-describedby ', critical -' role = "alert" '.
Visible ': focus-visible', Tab order corresponds to visual.
Text/icon contrast ≥ AA; meaning is not just color.
'Prefers-reduced-motion 'support: minimum animations.
For radio button groups - 'fieldset/legend', for prompts - 'role = "status"'.
10) Localization and international formats
Dates/currencies/numbers - local at entry, storage - ISO/minor units.
Allow for different alphabets in names/addresses; do not limit hyphens/apostrophes.
Keep the phone in the E.164; country selected explicitly or from '+ CC' on insertion.
11) Performance and stability
The first visual response ≤ 100 ms; asynchronous checks - do not lock the screen.
Skeleton instead of a "hanging" spinner, fix heights, avoid CLS.
Virtualize long lists (e.g. countries/banks).
Animate only 'transform/opacity', no bulk blur/shadows.
12) Security and privacy
Do not log PAN/CVC/Passport; do not send to RUM/console.
Mask sensitive fields, do not save them in autosave.
Do not disclose whether the account exists: "If the email is registered, we will send an email."
Storage - minimum required; show why KYC is required.
13) Typical Scenario Patterns
13. 1 Payment/deposit
Amount field with presets, currency explicitly specified.
PAN with soft mask, Luhn check; CVC is hidden; date'MM/YY 'with auto- '/'.
Text about commissions/deadlines nearby, not in tooltip.
13. 2 Withdrawal
Steps Amount → Method → Confirmation
Progress and "Usually up to N minutes/hours" (no hard promises).
Method variants by country; limit warnings.
13. 3 KYC
Step-by-step file loader: format/weight requirements, preview, privacy.
Check dates and status channel (mail/notification).
13. 4 Limits and responsible play
Clear units (day/week/month), pre-settings, confirmation of changes, "Will take effect in...."
14) Antipatterns
Placeholder instead of label.
Errors "per character" without debunking.
Resets the form on error.
The critical instruction is hidden only in the tooltip.
Hard masks prohibiting valid characters/insertion.
Lock the entire page to validate a single field.
Send without explicit busy/progress.
15) Implementation snippets
Summary of errors + focus on first issue
js function focusFirstError() {
const el = document. querySelector('[aria-invalid="true"]');
if (el) el. focus({ preventScroll:false });
}
Button with instant busy and idempotency
js btn. addEventListener('click', async () => {
btn. classList. add('is-busy');
try {
const r = await fetch('/api/submit', {
method: 'POST',
headers: { 'Idempotency-Key': crypto. randomUUID() },
body: new FormData(document. querySelector('form'))
});
if (!r.ok) throw new Error();
// success UI
} catch {
// show retry
} finally {
btn. classList. remove('is-busy');
}
});
HTML framework of the available radio button group
html
<fieldset>
<legend> How to get </legend>
<label><input type="radio" name="method" value="sepa"> SEPA</label>
<label><input type="radio" name="method" value="swift"> SWIFT</label>
</fieldset>
16) Design system tokens (example)
json
{
"form": {
"gap": 12,
"groupGap": 20,
"labelSize": 14,
"fieldHeight": 44,
"radius": 10
},
"motion": {
"pressMs": 90,
"hoverMs": 160,
"overlayInMs": 240
},
"validation": {
"debounceMs": 300,
"blurFeedbackMs": 100
},
"a11y": {
"focusRing": { "width": 2, "offset": 2 },
"contrastAA": true
}
}
CSS presets
css
.form { display:grid; gap:12px; }
.form__group { display:grid; gap:20px; }
label { font-size:14px; }
.input { height:44px; padding:0 12px; border-radius:10px; }
.input:focus-visible { outline:2px solid var(--focus-ring); outline-offset:2px; }
.field-error { color: var(--role-danger); font-size:.875rem; margin-top:6px; }
17) Metrics and experiments
Completion Rate, Time-to-Complete, Error Rate by Field.
Retry Success Rate, proportion of forms thrown, step depth.
CTR of hints/examples, proportion of autocompletes.
A/B: field order, amount presets, error texts, division into steps.
18) QA checklist
Meaning and flow
- The fields correspond to the target; no extra.
- Groups are logical; maximum of 6 fields per group.
Input
- Correct 'type/inputmode/autocomplete'.
- The masks are soft, the insert does not break, caret is predictable.
Validation
- Helper before input; errors on blur/submit; debouns 250-400 ms.
- Summary panel for multiple errors; focus to the first.
Availability
- Labels are linked; contrast ≥ AA; ': focus-visible' visible.
- Keyboard navigation; radio groups with 'fieldset/legend'.
Performance
- First response ≤ 100 ms; no "hanging" spinners.
- No CLS; long lists are virtualized.
Security
- No sensitive field logs; PAN/CVC is not in autosave.
- Idempotency and safe retreats are included.
19) The specifics of iGaming
Bets: amount field + presets, instant 'busy', optimistic confirmation with the possibility of undo (if the regulations allow).
Payments/withdrawals: explicit fees and deadlines near fields, not just in tips; Check limits and KYC status
Tournaments: a form of registration with a minimum set of data, rules and agreed checkboxes without "dark patterns."
Responsible game: forms of setting limits at clear intervals and previewing the result ("Your daily limit will be 2,000 ₴ from tomorrow").
Brief Summary
A good form is a clear goal, a minimal set of fields, clear rules before an error, instant response and saved data. Design the structure from the script, respect accessibility and locales, include safe retrays and idempotence. This is how forms feel fast and trusted - especially in critical iGaming scenarios.