-
Notifications
You must be signed in to change notification settings - Fork 0
a11y.input cramped padding
Rule ID:
a11y.input-cramped-paddingSeverity:WARNCategory:a11yTarget Standards: WCAG 2.2 Success Criterion 2.5.8 (Target Size - Minimum), Apple Human Interface Guidelines (Form Controls & Hit Targets: 44pt minimum), Material Design 3 (Text Fields: 48dp baseline, 40-42dp dense minimum)
Flags input controls with cramped vertical padding or height under 42px that clip text and impede touch targeting
"Form input controls (, , <textarea>) must maintain an effective height of at least 42px with adequate vertical padding ('py-2.5' or 'h-11') to ensure touch comfort and prevent text clipping."
Text inputs require sufficient spatial breathing room for cursor positioning, focus states, and internationalized typography ascenders and descenders (e.g. g, j, y, and diacritics).
When form controls specify undersized fixed heights like h-7 (28px) or h-8 (32px), or cramped vertical padding such as py-1 (4px) or p-1:
- Motor Targeting Errors: Users frequently miss the input tap area, accidentally tapping adjacent elements or the form background.
- Glyph Clipping: Font descenders collide with or are cut off by the field's bottom border.
- Inconsistent Visual Hierarchy: The input appears visually shrunk and uninviting compared to system controls.
Charites checks for undersized explicit heights (< 42px) and cramped padding without minimum height compensation.
| Risk Vector | Severity | Impact |
|---|---|---|
| Touch Targeting Failure | HIGH | Users experience difficulty tapping inputs on mobile touchscreens due to cramped hit targets. |
| Text & Glyph Clipping | MEDIUM | Letters with descenders or accents are visually truncated by field borders. |
<input className="h-8 px-2 text-sm border rounded" placeholder="Nama lengkap" /><input class="py-1 px-2 text-xs border rounded" placeholder="Kode pos" /><input className="h-11 px-3.5 py-2.5 text-base sm:text-sm border rounded-lg" placeholder="Nama lengkap" /><input class="py-2.5 px-3.5 text-base border rounded-md" placeholder="Kode pos" />This a11y rule evaluates template markup and cross-references resolved design tokens for accessibility:
flowchart TD
Node["AST Node (Astro / TSX element)"] --> Inspect["1. Inspect Interactive & Semantic Attributes"]
Inspect --> BindCheck["2. Cross-Reference Form IDs / Labels / ARIA"]
Inspect --> ContrastCheck["3. Query Token Graph for Foreground & Background Color"]
ContrastCheck --> Luminance["4. Compute WCAG 2.2 Contrast Ratio"]
BindCheck --> Invariant{"5. Validate Accessibility Invariant"}
Luminance --> Invariant
Invariant -- "Compliant" --> Safe["Pass"]
Invariant -- "Violation" --> IgnoreCheck{"6. Check charites:ignore directive"}
IgnoreCheck -- "Ignored" --> Safe
IgnoreCheck -- "Not Ignored" --> Diag["7. Emit Diagnostic: a11y.input-cramped-padding"]
- AST Traversal: Inspects semantic elements, form controls, images, and landmark containers.
- Structural & Attribute Invariant Check: Verifies accessible names, heading hierarchies, label/input bindings, and positive tabindex avoidance.
-
Token-Aware Contrast Verification: If analyzing color classes, queries
token.Contextto resolve foreground and background values, calculating relative luminance ratios. -
Directive Suppression Check: Inspects preceding comments for
charites:ignore a11y.input-cramped-padding. - Diagnostic Emission: Emits WCAG-grounded diagnostics for non-compliant patterns.
This rule is rigorously tested and validated across the canonical 1-SSOT Tri-Corpus in tests/correctness/a11y.input-cramped-padding/:
flowchart TD
subgraph GoldenCorpus ["1-SSOT Tri-Corpus Test Matrix for a11y.input-cramped-padding"]
subgraph P ["Positive Corpus (tests/correctness/a11y.input-cramped-padding/positive/)"]
P1["P1: Obvious Direct Violation"]
P2["P2: Indirect / Variant Concatenation"]
P3["P3: Helper / clsx / cn Wrapper"]
P4["P4: Deeply Nested Elements"]
P5["P5: Aliased Imports / Re-exports"]
end
subgraph N ["Negative Corpus (tests/correctness/a11y.input-cramped-padding/negative/)"]
N1["N1: Valid Design Tokens"]
N2["N2: Explicit charites:ignore Directive"]
N3["N3: Third-Party / Vendor Components"]
N4["N4: Clean Semantic HTML"]
N5["N5: Untokenized Custom Values (Banana Test)"]
end
subgraph A ["Adversarial Corpus (tests/correctness/a11y.input-cramped-padding/adversarial/)"]
A1["A1: Template Literal Interpolations"]
A2["A2: Ternary Conditional Expressions"]
A3["A3: Spread Properties & Dynamic Overrides"]
A4["A4: Dynamic Object Class Syntax"]
A5["A5: Shadowed Variable Identifiers"]
A6["A6: Nested Closures & HOC Wrappers"]
A7["A7: Obfuscated Classes & Cyclic Tokens"]
end
end
P --> TestRunner["Automated Runner (rule_test.go)"]
N --> TestRunner
A --> TestRunner
TestRunner --> Gates["Quality Gates: Zero Panic, Zero False-Positive, Zero Bypass"]
- Positive Fixtures (P1-P5): Verified to trigger diagnostics at exact lines and column spans.
- Negative Fixtures (N1-N5): Verified to produce zero diagnostics on valid tokens and legitimate exemptions.
- Adversarial Fixtures (A1-A7): Verified to prevent evasion across dynamic expressions, string interpolations, and cyclic references.
If this pattern is required for an intentional exception, suppress the diagnostic using the canonical Charites Rule ID:
<!-- charites:ignore a11y.input-cramped-padding intentional exception -->// charites:ignore a11y.input-cramped-padding intentional exceptionrules:
a11y.input-cramped-padding:
severity: warn # error | warn | info | offA11y (16 rules)
- A11y Overview
a11y.button-type-missinga11y.dialog-missing-ariaa11y.empty-interactivea11y.error-not-announceda11y.form-input-missing-namea11y.form-label-composite-controla11y.form-label-missing-controla11y.img-missing-alta11y.input-cramped-paddinga11y.input-ios-zoom-hazarda11y.keyboard-trap-missing-escapea11y.label-missing-controla11y.missing-focus-ringa11y.placeholder-as-labela11y.touch-target-sizea11y.touch-target-spacing
Browser (12 rules)
- Browser Overview
browser.appearance-native-overridebrowser.chrome-only-apibrowser.date-input-format-assumptionbrowser.experimental-api-no-featuredetectbrowser.firefox-only-apibrowser.hover-only-interactionbrowser.non-passive-scroll-listenerbrowser.obsolete-vendor-prefixbrowser.safari-only-apibrowser.scrollbar-vendor-incompletebrowser.user-agent-sniffingbrowser.webkit-only-api
Cls (16 rules)
- Cls Overview
cls.client-only-hydration-popcls.collapsible-height-jumpcls.dynamic-content-without-reserved-spacecls.dynamic-table-reflowcls.font-display-missingcls.font-import-late-discoverycls.layout-trigger-animationcls.layout-trigger-transitioncls.text-icon-late-reflowcls.unadjusted-font-metriccls.unconstrained-carouselcls.unreserved-ad-containercls.unreserved-fixed-headercls.unsized-embed-framecls.unsized-imagecls.unstable-scrollbar-gutter
Design (1 rules)
Ergonomy (5 rules)
Inp (16 rules)
- Inp Overview
inp.context-re-render-cascadeinp.expensive-render-computationinp.expensive-style-mutationinp.heavy-event-handlerinp.hydration-contentioninp.hydration-heavy-islandinp.large-interaction-layout-scopeinp.layout-thrashinginp.missing-start-transitioninp.missing-touch-actioninp.render-blocking-scriptinp.repeated-state-updateinp.sync-layout-effectinp.unbounded-collection-renderinp.unbounded-effect-depsinp.unyielded-long-task
Lcp (16 rules)
- Lcp Overview
lcp.blocked-critical-fontlcp.client-only-lcp-contentlcp.critical-head-style-bloatlcp.external-font-discovery-delaylcp.heavy-raster-lcp-assetlcp.image-source-density-mismatchlcp.lazy-loaded-lcp-imagelcp.lcp-content-visibility-suppressionlcp.legacy-critical-font-resourcelcp.missing-critical-origin-hintlcp.missing-lcp-image-preloadlcp.oversized-lcp-resource-selectionlcp.preload-font-cors-mismatchlcp.render-blocking-head-scriptlcp.undiscoverable-lcp-imagelcp.unhinted-lcp-image-priority
Mobile (5 rules)
Performance (16 rules)
- Performance Overview
performance.astro-island-boundary-overlapperformance.astro-over-prefetchingperformance.astro-unnecessary-client-directiveperformance.astro-unoptimized-local-imageperformance.react-context-domain-couplingperformance.react-derived-state-in-effectperformance.react-effect-missing-cleanupperformance.react-index-as-keyperformance.react-inline-prop-memoperformance.react-redundant-function-memoizationperformance.react-static-heavy-importperformance.react-unstable-hook-referenceperformance.tailwind-duplicate-arbitrary-rulesperformance.tailwind-duplicate-utility-definitionperformance.tailwind-dynamic-class-concatenationperformance.tailwind-untracked-package-source
Pwa (10 rules)
- Pwa Overview
pwa.apple-meta-missingpwa.icon-maskable-missingpwa.insecure-context-resourcepwa.manifest-missingpwa.manifest-required-fields-missingpwa.pwa-cache-runtime-api-riskpwa.service-worker-missingpwa.service-worker-no-offline-fallbackpwa.service-worker-registrationpwa.start-url-inconsistency
Responsive (18 rules)
- Responsive Overview
responsive.aspect-ratio-overflowresponsive.container-overconstraintresponsive.desktop-only-contentresponsive.dynamic-viewport-inconsistencyresponsive.fixed-width-overflowresponsive.flex-child-overflowresponsive.fractional-width-gap-driftresponsive.grid-min-columnresponsive.horizontal-overflowresponsive.image-overflowresponsive.keyboard-obstructionresponsive.missing-breakpointresponsive.mobile-density-overloadresponsive.mobile-text-overflowresponsive.safe-area-missingresponsive.unwrapped-table-overflowresponsive.viewport-meta-missingresponsive.viewport-unit-leak
Semantic (1 rules)
Theme (32 rules)
- Theme Overview
theme.apply-bloattheme.backdrop-blur-hardcodetheme.chart-color-hardcodetheme.dual-strategy-collisiontheme.dynamic-classtheme.focus-ring-hardcodetheme.gradient-hardcodetheme.hardcode-border-colortheme.hardcode-border-radiustheme.hardcode-colortheme.hardcode-monochrometheme.hardcode-opacity-colortheme.hardcode-shadow-colortheme.hardcode-sizetheme.hardcode-z-indextheme.hydration-theme-mismatchtheme.image-theme-hardcodetheme.important-overridetheme.inline-style-hardcodetheme.meta-theme-color-mismatchtheme.missing-color-schemetheme.missing-token-fallbacktheme.nested-opacity-contrasttheme.no-reduced-motiontheme.primitive-in-componenttheme.pseudo-hardcode-colortheme.shadow-without-border-darktheme.split-theme-statetheme.svg-hardcode-filltheme.token-source-drifttheme.unlayered-token-definitiontheme.unpaired-dark-variant
Ux (20 rules)
- Ux Overview
ux.camouflaged-linkux.competing-primary-ctaux.destructive-action-unconfirmedux.disabled-control-no-explanationux.empty-collection-unhandledux.missing-autofillux.monolithic-form-bloatux.multiline-input-misuseux.nav-overflow-chunkingux.number-input-identity-misuseux.number-input-missing-boundsux.orphaned-error-stateux.radio-overchoiceux.silent-catch-swallowux.spacing-inversionux.spacing-rhythm-driftux.submit-feedback-missingux.unbounded-async-flagux.unconventional-home-linkux.unthrottled-input-handler