Skip to content

[A11Y] [High] Form inputs missing associated labels #4

@continue

Description

@continue

Accessibility Issue: Form Inputs Missing Associated Labels

WCAG Level: A
Severity: High
Category: Form Accessibility

Issue Description

Multiple form inputs across the application lack proper <label> associations. While some inputs have visual labels using <span> or <div> elements, they are not programmatically associated with the inputs.

User Impact

  • Affected Users: Screen reader users, users with cognitive disabilities
  • Severity: Users cannot understand what information is requested in form fields

Violations Found

File: components/calculate/parameter-panel.tsx

Lines: 194-205 (ParamInput helper)

function ParamInput({ label, value, ... }) {
  return (
    <div>
      <label className="mb-2 block font-mono text-xs text-zinc-500">
        {label}
      </label>
      <input
        type="number"
        value={displayValue}
        ...
      />
    </div>
  );
}

Issue: The <label> element is not properly associated with the <input> (missing htmlFor and id attributes)


File: components/calculate/parameter-panel.tsx

Lines: 157-177 (ParamSelect helper)

function ParamSelect({ label, value, ... }) {
  return (
    <div>
      <label className="mb-2 flex items-center gap-2 font-mono text-xs text-zinc-500">
        {label}
      </label>
      <select ...>

Issue: The <label> has no htmlFor attribute connecting it to the <select>


File: app/community/page.tsx

Lines: 163-175

<input
  type="text"
  placeholder="Search formula (e.g. Si, C2H6O)..."
  value={formulaFilter}
  onChange={(e) => setFormulaFilter(e.target.value)}
  className="..."
/>

Issue: Search input has no associated label (placeholder is not a substitute)


File: components/semiconductor/structure-library.tsx

Lines: 80-91

<input
  type="text"
  value={search}
  onChange={(e) => setSearch(e.target.value)}
  placeholder="Search materials..."
  className="..."
/>

Issue: Search input has no accessible label


Recommended Fix

<!-- Fixed Code for ParamInput -->
function ParamInput({ label, value, ... }) {
  const id = React.useId();
  return (
    <div>
      <label 
        htmlFor={id}
        className="mb-2 block font-mono text-xs text-zinc-500"
      >
        {label}
      </label>
      <input
        id={id}
        type="number"
        value={displayValue}
        ...
      />
    </div>
  );
}

<!-- Fixed search input -->
<label htmlFor="formula-search" className="sr-only">
  Search formula
</label>
<input
  id="formula-search"
  type="text"
  placeholder="Search formula (e.g. Si, C2H6O)..."
  ...
/>

Changes Made:

  1. Add unique id to all inputs using React.useId()
  2. Add corresponding htmlFor attribute to <label> elements
  3. For visually hidden labels, use sr-only utility class
  4. Keep placeholder as a hint, not primary label

Additional Instances

  • components/calculate/share-to-community.tsx (contributor, institution, notes inputs)
  • components/semiconductor/defect-generator.tsx (Miller indices inputs)
  • app/mace-freeze/page.tsx (multiple parameter inputs)

Testing Instructions

  1. Click on a label text - input should receive focus
  2. Use screen reader to navigate to input - label should be announced
  3. Verify all form fields have clear, descriptive labels

Resources

Acceptance Criteria

  • All inputs have associated labels (programmatically linked)
  • Clicking label focuses the input
  • Screen reader announces label when input is focused
  • Placeholder text supplements but does not replace labels

Metadata

Metadata

Assignees

No one assigned

    Labels

    accessibilityWeb accessibility improvements (WCAG compliance)severity-highHigh severity issuewcag-aWCAG Level A compliance

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions