📝 Form Design Principles

Forms can be particularly challenging for users with dyslexia, ADHD, and motor difficulties. Clear labels, helpful hints, and meaningful error messages are essential for accessible form design.

Design Guidelines

Principle Description Recommendation
Clear Labels Associate labels with inputs Use <label> elements with for attribute
Input Hints Provide format guidance Show examples and format hints
Real-time Validation Validate as user types Don't wait until submission
Meaningful Errors Explain the problem Describe what's wrong and how to fix it
Autocomplete Support Enable browser fill Use correct autocomplete attributes
Appropriate Input Types Trigger right keyboard Use type="email", type="tel", etc.
Required Field Marking Indicate mandatory fields Use required attribute and visual markers
Focus Management Guide user to errors Auto-focus on first error field

CSS Implementation

/* Form field styling */
.form-field {
  margin-bottom: 1.5rem;
}

.form-label {
  display: block;
  font-weight: 600;
  margin-bottom: 0.5rem;
}

.form-input {
  width: 100%;
  min-height: 44px;
  padding: 0.75rem 1rem;
  border: 2px solid #d1d5db;
  border-radius: 0.5rem;
  font-size: 1rem;
}

.form-input:focus {
  outline: none;
  border-color: #3b82f6;
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2);
}

/* Error state */
.form-input.error {
  border-color: #ef4444;
}

.form-error {
  color: #dc2626;
  font-size: 0.875rem;
  margin-top: 0.5rem;
}

/* Success state */
.form-input.success {
  border-color: #22c55e;
}

Error Message Examples

<!-- Bad: Vague error message -->
<div class="error">输入有误,请检查</div>

<!-- Good: Specific and actionable error message -->
<div class="error" role="alert">
  **手机号码格式不正确** 请输入11位手机号码,例如:13800138000
</div>

React Component

interface FormFieldProps {
  label: string;
  name: string;
  type?: "text" | "email" | "tel" | "password" | "number";
  placeholder?: string;
  hint?: string;
  required?: boolean;
  error?: string;
  success?: boolean;
  autocomplete?: string;
}

export function FormField({
  label,
  name,
  type = "text",
  placeholder,
  hint,
  required = false,
  error,
  success,
  autocomplete,
}: FormFieldProps) {
  const [value, setValue] = useState("");

  return (
    <div className="form-control w-full">
      <label className="label" htmlFor={name}>
        <span className="label-text font-semibold">
          {label}
          {required && <span className="text-error ml-1">*</span>}
        </span>
      </label>

      <div className="relative">
        <input
          id={name}
          name={name}
          type={type}
          placeholder={placeholder}
          required={required}
          autoComplete={autocomplete}
          value={value}
          onChange={(e) => setValue(e.target.value)}
          className={`
            input input-bordered w-full min-h-[44px]
            ${error ? "input-error" : success ? "input-success" : ""}
          `}
          aria-invalid={!!error}
          aria-describedby={
            error ? `${name}-error` : hint ? `${name}-hint` : undefined
          }
        />

        {(error || success) && (
          <span className="absolute right-3 top-1/2 -translate-y-1/2">
            {error && <AlertCircle className="w-5 h-5 text-error" />}
            {success && !error && (
              <CheckCircle className="w-5 h-5 text-success" />
            )}
          </span>
        )}
      </div>

      {hint && !error && (
        <p id={`${name}-hint`} className="text-sm text-neutral-500 mt-1">
          {hint}
        </p>
      )}

      {error && (
        <p
          id={`${name}-error`}
          className="text-sm text-error mt-1 flex items-center gap-1"
          role="alert"
        >
          <AlertCircle className="w-4 h-4" />
          {error}
        </p>
      )}
    </div>
  );
}

Autocomplete Attributes

Field Type Autocomplete Value
Full Name name
Email email
Phone tel
Address street-address
City address-level2
Postal Code postal-code
Country country
Credit Card cc-number

Checklist

  • All inputs have associated labels
  • Required fields are clearly marked
  • Format hints are provided
  • Real-time validation is implemented
  • Error messages are specific and actionable
  • Correct autocomplete attributes are used
  • Appropriate input types trigger correct keyboards
  • Focus moves to errors automatically

Last updated: 2026-10-20

Menu
Loading