AiTechWorlds
AiTechWorlds
POUR principles, semantic HTML, ARIA attributes, keyboard navigation, color contrast, forms, and screen reader testing.

WCAG 2.1 Levels: A (minimum), AA (industry standard), AAA (enhanced)
| Principle | Meaning |
|---|---|
| Perceivable | Users can perceive all content (alt text, captions) |
| Operable | Users can navigate and interact (keyboard, no seizures) |
| Understandable | Content and UI are clear (plain language, consistent nav) |
| Robust | Works with assistive technologies (valid HTML, ARIA) |
<!-- BAD: divs for everything -->
<div class="nav">
<div class="nav-item" onclick="...">Home</div>
</div>
<div class="main">
<div class="title">Welcome</div>
</div>
<!-- GOOD: semantic elements -->
<nav aria-label="Main navigation">
<a href="/">Home</a>
</nav>
<main>
<h1>Welcome</h1>
</main>| Element | Purpose |
|---|---|
<header> | Page/section header |
<nav> | Navigation links |
<main> | Primary content (one per page) |
<article> | Self contained content |
<section> | Thematic grouping with heading |
<aside> | Sidebar, supplementary |
<footer> | Page/section footer |
<figure> / <figcaption> | Image with caption |
<time datetime="2026-01-15"> | Machine readable date |
<address> | Contact information |
<!-- Informative image โ describe what it conveys -->
<img src="chart.png" alt="Bar chart showing 40% increase in Q1 sales">
<!-- Decorative image โ empty alt (screen reader skips it) -->
<img src="divider.png" alt="">
<!-- Background image โ use CSS, not <img> -->
<div style="background-image: url(bg.jpg)" role="img" aria-label="Office building exterior"></div>
<!-- Complex image โ link to description -->
<img src="infographic.png" alt="AI adoption trends 2026" aria-describedby="infographic-desc">
<p id="infographic-desc" class="sr-only">Detailed description: ...</p>All interactive elements must be operable via keyboard:
<!-- Use native elements (already keyboard accessible) -->
<button onclick="submit()">Submit</button> โ
<a href="/page">Go</a> โ
<!-- Custom interactive element โ must have tabindex and keyboard handler -->
<div
role="button"
tabindex="0"
onclick="handleClick()"
onkeydown="e.key === 'Enter' || e.key === ' ' ? handleClick() : null"
>
Custom Button
</div>/* Never remove focus outline โ restyle it instead */
:focus-visible {
outline: 3px solid #4f46e5;
outline-offset: 2px;
border-radius: 4px;
}
/* Remove only for mouse users, keep for keyboard */
:focus:not(:focus-visible) {
outline: none;
}| Attribute | Use |
|---|---|
aria label | Accessible name when no visible label exists |
aria labelledby | Points to element that labels this one |
aria describedby | Points to element with additional description |
aria hidden="true" | Hide from screen readers (decorative icons) |
aria expanded | State of collapsible (true/false) |
aria current="page" | Current item in nav |
aria live="polite" | Announce dynamic content updates |
aria busy="true" | Element is loading |
role="alert" | Important announcement (reads immediately) |
role="dialog" | Modal dialog |
role="tablist" / "tab" | Tab component |
1. Use semantic HTML first ARIA is a last resort
2. Don't use ARIA to override semantics unnecessarily
3. All ARIA widgets must be keyboard operable
4. Don't hide visible content from screen readers
<!-- Politely announce changes (waits for user idle) -->
<div aria-live="polite" aria-atomic="true" id="status">
<!-- Inject messages here dynamically -->
</div>
<!-- Assertive โ interrupt immediately (errors, alerts) -->
<div role="alert">Your session expires in 5 minutes</div><!-- Always associate labels -->
<label for="email">Email address</label>
<input
type="email"
id="email"
name="email"
autocomplete="email"
required
aria-describedby="email-error"
aria-invalid="true"
>
<span id="email-error" role="alert">Please enter a valid email</span>
<!-- Fieldset for grouped inputs -->
<fieldset>
<legend>Notification preferences</legend>
<input type="checkbox" id="email-notif" name="notify" value="email">
<label for="email-notif">Email</label>
<input type="checkbox" id="sms-notif" name="notify" value="sms">
<label for="sms-notif">SMS</label>
</fieldset>| Text Type | Minimum Ratio |
|---|---|
| Normal text (< 18px / not bold) | 4.5:1 |
| Large text (โฅ 18px or โฅ 14px bold) | 3:1 |
| UI components, icons | 3:1 |
| Decorative elements | No requirement |
Test tools: WebAIM Contrast Checker, browser DevTools accessibility panel, axe browser extension.
| Screen Reader | Platform | Cost |
|---|---|---|
| NVDA | Windows | Free |
| JAWS | Windows | Paid |
| VoiceOver | macOS / iOS | Built in (free) |
| TalkBack | Android | Built in (free) |
Quick VoiceOver test: Cmd+F5 on Mac, then navigate with Tab and arrow keys.
<!-- First element in <body> -->
<a href="#main-content" class="skip-link">Skip to main content</a>
<style>
.skip-link {
position: absolute;
transform: translateY(-100%);
transition: transform 0.2s;
}
.skip-link:focus {
transform: translateY(0); /* visible when focused */
}
</style>
<main id="main-content">...</main>aria label on every element only needed when there's no visible label; overuse clutters screen reader outputGet more notes like this daily on Telegram!
Free study notes, cheat sheets & AI tips
Last reviewed on June 13, 2026 by the AiTechWorlds Notes Team. Free cheat sheet no signup required.
Join AiTechWorlds on Telegram and get daily AI tips, prompt engineering templates, coding resources, and exclusive content 100% free!
No spam. Leave anytime.