Skip to content

a11y.placeholder as label

github-actions[bot] edited this page Sep 6, 2026 · 2 revisions

a11y.placeholder-as-label

Rule ID: a11y.placeholder-as-label Severity: ERROR Category: a11y Target Standards: WCAG 2.2 Success Criterion 3.3.2 (Labels or Instructions - Level A), WCAG 2.2 Success Criterion 1.3.1 (Info and Relationships - Level A), Nielsen Norman Group (Placeholders in Form Fields Are Harmful)


1. Overview & Core Invariant

Flags form inputs relying solely on placeholder attributes without a persistent label or accessible name (WCAG 3.3.2)

Core Invariant:

"Form text inputs (, , <textarea>) declaring a 'placeholder' must provide a persistent label (, , aria-label, or aria-labelledby)."


2. Technical Grounding & Engine Realities

Placeholder text is intended solely as an example of expected input format (e.g. 'e.g. user@example.com'), never as a replacement for a field label.

When developers omit and rely exclusively on placeholder:

  1. Vanishing Context: The moment a user types even one character, the placeholder vanishes. Users cannot review or verify what the field originally asked for.
  2. Cognitive and Memory Strain: Users with memory impairments, cognitive disabilities, or mobile users distracted by notifications lose track of field meaning.
  3. Screen Reader Gaps: Assistive technologies handle unlabelled placeholders inconsistently, frequently omitting them in forms-mode navigation.

Charites verifies that any input with a placeholder has an associated or direct accessible name attribute.


3. Vulnerability & Risk Taxonomy

Risk Vector Severity Impact
Vanishing Form Context HIGH Users lose track of input requirements after typing begins, increasing submission errors.
WCAG 3.3.2 Non-Compliance HIGH Flagged as a major Level A accessibility violation in public and enterprise audits.

4. Non-Compliant Code Patterns (Bad Examples)

TSX (Input relying solely on placeholder without label or aria-label):

<input type="email" placeholder="Masukkan email Anda" className="border px-3 py-2" />

ASTRO (Textarea with placeholder but no associated label):

<textarea placeholder="Ketik pesan Anda di sini" class="border p-2"></textarea>

5. Compliant Implementation Patterns (Good Examples)

TSX (Persistent label associated with input ID plus descriptive placeholder):

<label htmlFor="user-email">Email</label><input id="user-email" type="email" placeholder="nama@domain.com" className="border px-3 py-2" />

ASTRO (Enclosing label wrapping input and descriptive prompt):

<label class="flex flex-col">Pesan <textarea placeholder="Ketik pesan..." class="border p-2"></textarea></label>

6. How to Suppress (Ignore Directives)

If this pattern is required for an intentional exception, suppress the diagnostic using the canonical Charites Rule ID:

<!-- charites:ignore a11y.placeholder-as-label intentional exception -->
// charites:ignore a11y.placeholder-as-label intentional exception

7. Configuration Reference (charites.yaml)

rules:
  a11y.placeholder-as-label:
    severity: error # error | warn | info | off

8. Architectural Domain & Verification Reference


Rule Categories

A11y (16 rules)
Browser (12 rules)
Cls (16 rules)
Design (1 rules)
Ergonomy (5 rules)
Inp (16 rules)
Lcp (16 rules)
Mobile (5 rules)
Performance (16 rules)
Pwa (10 rules)
Responsive (18 rules)
Semantic (1 rules)
Theme (32 rules)
Ux (20 rules)

Clone this wiki locally