Muhammad Rafi Arsya
Back to All Projects
HCI · Accessibility · WCAG 2.1 · 2025

NASE Accessibility

A full accessibility audit and redesign of the NASE platform for visually impaired users. 23 issues found, categorised by WCAG 2.1 severity, with redesigned components and an AI-powered contrast analysis pipeline.

Accessibility WCAG 2.1 AA HCI Course Python + OpenCV Figma Screen Reader
Status
Completed
Year
2025
Context
HCI Course · UM
Standard
WCAG 2.1 AA
01 Project Overview

NASE Accessibility started as an HCI course project, but quickly became something more personal. I audited the NASE platform — a digital tool used by visually impaired students in Malaysia.

The goal: find every barrier that prevents a visually impaired user from navigating the platform independently, categorise each issue by WCAG 2.1 severity, and produce a redesigned prototype that passes AA compliance.

What I realised doing this: Accessibility failures aren't abstract. A missing ARIA label means a screen reader says "button" with no context. Low contrast means the text literally disappears. This project was about making a real platform actually usable.
02 Accessibility Audit — Issues Found

23 issues identified across 5 pages of the NASE platform, categorised by WCAG 2.1 severity:

● High Severity
Missing ARIA labels on interactive controls — screen readers announce "button" with no context. Affected: 6 buttons across 3 pages.
● High Severity
No keyboard focus indicators. Keyboard-only users cannot see which element is focused. Tab order undefined on form pages.
● Medium Severity
Contrast ratio of 2.4:1 on primary text (WCAG requires 4.5:1 for AA). Body text on light backgrounds fails on Contact and About pages.
● Medium Severity
Images missing alt attributes. 14 decorative images and 3 informational images lack alt text — screen readers skip or misread them.
● Low Severity
Form inputs missing associated <label> elements — screen readers read placeholder text only, which disappears on input focus.
● Low Severity
Heading hierarchy skips levels (H1 → H4). Screen reader navigation by headings produces a confusing jump in structure.
03 WCAG 2.1 Criteria Addressed
1.1.1
Non-text Content — all images given descriptive alt text or marked role="presentation"
PASS
1.3.1
Info and Relationships — semantic HTML5 elements used throughout, ARIA landmark roles added
PASS
1.4.3
Contrast (Minimum) — text contrast raised to ≥4.5:1 everywhere via AI contrast pipeline
PASS
2.1.1
Keyboard — all controls reachable and operable via keyboard only, focus order logical
PASS
2.4.3
Focus Order — tab order follows visual reading flow left→right top→bottom
PASS
4.1.2
Name, Role, Value — all interactive elements have accessible names via aria-label or visible text
PASS
04 AI-Powered Contrast Analysis Pipeline

Manual contrast checking is slow. I built a Python pipeline using OpenCV and TensorFlow to automatically detect text regions, extract foreground/background colours, and calculate contrast ratios across every page screenshot.

01WCAG Contrast Ratio Formula
L = 0.2126 × R + 0.7152 × G + 0.0722 × B
    (where R, G, B are linearised sRGB channels in [0, 1])

contrast_ratio = (L1 + 0.05) / (L2 + 0.05)
                  (L1 = lighter color, L2 = darker color)

WCAG AA  requires ratio ≥ 4.5:1   (normal text)
WCAG AAA requires ratio ≥ 7:1     (normal text)
scroll for full derivation

The 0.2126 / 0.7152 / 0.0722 weights aren't arbitrary — they come from the relative luminance the human eye perceives per channel, with green contributing far more to perceived brightness than blue. The "+0.05" offset in the ratio formula accounts for ambient screen glow so the formula never divides by something close to zero on a true black background. Run against every text/background pair on the site, this is what decided which color combinations were usable before a single line of the design was finalised.

# Body text #374151 on background #FFFFFF

R,G,B (linearised) for #374151 ≈ 0.035, 0.054, 0.075
L1 = 0.2126(0.035) + 0.7152(0.054) + 0.0722(0.075)
   ≈ 0.052

R,G,B (linearised) for #FFFFFF = 1, 1, 1
L2 = 1.0

contrast_ratio = (1.0 + 0.05) / (0.052 + 0.05)
               ≈ 10.3 : 1

→ passes WCAG AAA (≥ 7:1) for normal text
scroll to see full computation
05 Design Principles Applied
Perceivable — Every element has a text alternative
All images use descriptive alt text. Decorative images use empty alt or role="presentation". Colour is never the only means of conveying information.
Operable — Full keyboard navigability
Every interactive element is keyboard reachable. Visible focus outlines on all controls. Tab order follows the visual reading flow. No keyboard traps.
Understandable — Consistent, labeled UI
All form inputs have visible labels. Error messages explain what is wrong and how to fix it. Navigation is consistent across all redesigned pages.
Robust — Semantic HTML + ARIA
All redesigned pages use semantic HTML5. Interactive elements have explicit ARIA roles. Tested with NVDA screen reader and keyboard-only navigation.
06 Use Cases & Impact
Screen Reader Users
NVDA/VoiceOver can now navigate the platform with meaningful announcements at every interactive element.
Keyboard-Only Navigation
Users who cannot use a mouse can tab through every control with visible focus and logical ordering.
Low Vision Users
4.5:1+ contrast on all text means content is readable even with visual impairments or in bright environments.
Mobile Accessibility
Redesigned components tested with iOS VoiceOver — touch targets meet minimum 44×44px requirements.
By the Numbers
23
Issues Found
AA
WCAG Level
5
Pages Audited
4.5+
Min Contrast
Completion
Accessibility Audit100%
AI Contrast Pipeline100%
Figma Redesign100%
HTML Prototype100%
Tech Stack
HTML5 CSS3 JavaScript ARIA Python OpenCV TensorFlow Figma NVDA WCAG 2.1
Accessibility isn't optional.
Accessibility work is often invisible — people only notice when it's wrong. This project was about making the invisible visible, then fixing it.
View Live Prototype