POUR Principles in Web Design: Perceivable, Operable, Understandable, Robust
The Web Content Accessibility Guidelines (WCAG) organize all accessibility requirements under four foundational principles: Perceivable, Operable, Understandable, and Robust—collectively known as POUR. These principles provide a framework for understanding accessibility, guiding design decisions, and evaluating digital experiences.
This guide explains each POUR principle, what it requires, and how to implement it effectively in web design and development.
The Foundation of Web Accessibility
Why POUR Matters
POUR isn't arbitrary—each principle addresses fundamental ways people interact with digital content:
Perceivable: Can users sense the content? People need to receive information through at least one sense—sight, hearing, or touch.
Operable: Can users interact with the interface? People need to navigate, click, type, and control all functionality.
Understandable: Can users comprehend the content and interface? People need to understand both information content and how to use the interface.
Robust: Does content work across technologies? People need content that functions reliably with various assistive technologies.
POUR and WCAG Structure
WCAG 2.2 organizes 87 success criteria under these four principles:
| Principle | Guidelines | Success Criteria |
|----------------|------------|------------------|
| Perceivable | 4 | 29 |
| Operable | 5 | 29 |
| Understandable | 3 | 17 |
| Robust | 1 | 3 |Each principle contains guidelines, and each guideline contains testable success criteria at Levels A, AA, and AAA.
Perceivable: Making Content Detectable
The Principle
Information and user interface components must be presentable to users in ways they can perceive. This doesn't require perception through any specific sense—content must be available to at least one sense.
What Perceivable Covers
Guideline 1.1: Text Alternatives Provide text alternatives for non-text content.
Guideline 1.2: Time-Based Media Provide alternatives for audio and video content.
Guideline 1.3: Adaptable Create content that can be presented in different ways.
Guideline 1.4: Distinguishable Make content easier to see and hear.
Implementing Perceivable Design
Text alternatives for images:
<!-- Informative image -->
<img src="chart.png" alt="Q4 sales increased 32% compared to Q3">
<!-- Decorative image -->
<img src="decorative-border.png" alt="" role="presentation">
<!-- Functional image (button) -->
<button>
<img src="search-icon.svg" alt="Search">
</button>
<!-- Complex image with extended description -->
<figure>
<img src="org-chart.png" alt="Company organizational structure"
aria-describedby="org-desc">
<figcaption id="org-desc">
The CEO reports to the board. Four VPs report to the CEO:
Engineering, Product, Sales, and Operations...
</figcaption>
</figure>Color contrast requirements:
/* WCAG AA requires 4.5:1 for normal text */
.body-text {
color: #333333; /* Dark gray */
background: #ffffff; /* White */
/* Contrast ratio: 12.6:1 - passes AA and AAA */
}
/* Large text (18pt+) requires 3:1 */
.heading {
font-size: 24px;
color: #595959; /* Medium gray */
background: #ffffff;
/* Contrast ratio: 7:1 - passes AA and AAA */
}
/* Non-text elements require 3:1 */
.button {
border: 2px solid #0066cc;
/* Border contrast against background: 4.5:1 */
}Audio alternatives:
<!-- Video with captions -->
<video controls>
<source src="product-demo.mp4" type="video/mp4">
<track kind="captions" src="captions.vtt" srclang="en" label="English">
<track kind="descriptions" src="descriptions.vtt" srclang="en" label="Audio Descriptions">
</video>
<!-- Podcast with transcript -->
<audio controls src="podcast-episode-42.mp3"></audio>
<a href="transcript-ep42.html">Read full transcript</a>Common Perceivable Failures
- Images without alt text
- Videos without captions
- Color as only indicator of meaning
- Insufficient color contrast
- Content only available through hover states
- Audio without transcripts
Operable: Enabling Interaction
The Principle
User interface components and navigation must be operable. Users must be able to interact with all functionality, regardless of input method.
What Operable Covers
Guideline 2.1: Keyboard Accessible All functionality available from keyboard.
Guideline 2.2: Enough Time Users can control time limits.
Guideline 2.3: Seizures and Physical Reactions No content that causes seizures.
Guideline 2.4: Navigable Help users navigate and find content.
Guideline 2.5: Input Modalities Support various input methods beyond keyboard.
Implementing Operable Design
Full keyboard accessibility:
// Custom interactive component with keyboard support
class CustomDropdown {
constructor(element) {
this.dropdown = element;
this.trigger = element.querySelector('.trigger');
this.menu = element.querySelector('.menu');
this.options = element.querySelectorAll('[role="option"]');
this.trigger.addEventListener('keydown', this.handleTriggerKeys.bind(this));
this.menu.addEventListener('keydown', this.handleMenuKeys.bind(this));
}
handleTriggerKeys(e) {
switch(e.key) {
case 'Enter':
case ' ':
case 'ArrowDown':
e.preventDefault();
this.openMenu();
break;
case 'Escape':
this.closeMenu();
break;
}
}
handleMenuKeys(e) {
switch(e.key) {
case 'ArrowDown':
e.preventDefault();
this.focusNext();
break;
case 'ArrowUp':
e.preventDefault();
this.focusPrevious();
break;
case 'Enter':
this.selectOption();
break;
case 'Escape':
this.closeMenu();
this.trigger.focus();
break;
}
}
}Visible focus indicators:
/* Never remove focus without replacement */
:focus-visible {
outline: 2px solid #0066cc;
outline-offset: 2px;
}
/* Custom focus styles for specific elements */
.button:focus-visible {
outline: none;
box-shadow: 0 0 0 3px #ffffff, 0 0 0 5px #0066cc;
}
/* Ensure focus is visible against all backgrounds */
.dark-section :focus-visible {
outline-color: #ffffff;
}Skip navigation links:
<body>
<a href="#main" class="skip-link">Skip to main content</a>
<a href="#nav" class="skip-link">Skip to navigation</a>
<header>
<nav id="nav">...</nav>
</header>
<main id="main" tabindex="-1">
<!-- Main content -->
</main>
</body>.skip-link {
position: absolute;
top: -40px;
left: 0;
padding: 8px;
background: #000;
color: #fff;
z-index: 100;
}
.skip-link:focus {
top: 0;
}Target size requirements (WCAG 2.2):
/* Minimum 24x24 CSS pixels */
button,
a,
input[type="checkbox"],
input[type="radio"] {
min-width: 24px;
min-height: 24px;
}
/* Touch targets should be larger - 44x44 recommended */
.touch-target {
min-width: 44px;
min-height: 44px;
padding: 10px;
}Common Operable Failures
- Keyboard traps (focus can't escape)
- Mouse-only interactions
- No visible focus indicator
- Time limits without controls
- Flashing content over 3 times per second
- Missing skip links on complex pages
Understandable: Clarity in Design
The Principle
Information and operation of user interface must be understandable. Users must be able to comprehend content and figure out how to use the interface.
What Understandable Covers
Guideline 3.1: Readable Make text content readable and understandable.
Guideline 3.2: Predictable Make pages appear and operate predictably.
Guideline 3.3: Input Assistance Help users avoid and correct mistakes.
Implementing Understandable Design
Language declaration:
<!-- Primary language -->
<html lang="en">
<!-- Language changes within content -->
<p>The French phrase <span lang="fr">je ne sais quoi</span>
means a quality that cannot be described.</p>Predictable navigation:
<!-- Consistent navigation across pages -->
<nav aria-label="Main navigation">
<ul>
<li><a href="/products">Products</a></li>
<li><a href="/services">Services</a></li>
<li><a href="/about">About</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>
<!-- Navigation remains in same order on all pages -->Form error handling:
<form novalidate>
<div class="form-group" aria-live="polite">
<label for="email">Email address (required)</label>
<input type="email" id="email"
aria-required="true"
aria-invalid="true"
aria-describedby="email-error">
<p id="email-error" class="error" role="alert">
Please enter a valid email address (example: name@domain.com)
</p>
</div>
<div class="form-group">
<label for="password">
Password (required)
<span class="hint">Must be at least 8 characters with one number</span>
</label>
<input type="password" id="password"
aria-required="true"
aria-describedby="password-hint">
<p id="password-hint" class="hint">
Strong passwords include uppercase, lowercase, numbers, and symbols.
</p>
</div>
</form>Consistent identification:
<!-- Same functionality labeled consistently across site -->
<!-- On product page -->
<button class="add-to-cart">Add to Cart</button>
<!-- On category page -->
<button class="add-to-cart">Add to Cart</button>
<!-- NOT inconsistent like: "Add to Cart" vs "Buy Now" vs "Purchase"
for the same action -->Clear instructions:
<form>
<p class="form-instructions">
Fields marked with <span aria-hidden="true">*</span>
<span class="visually-hidden">asterisk</span> are required.
</p>
<label for="phone">
Phone number *
<span class="format-hint">Format: (555) 555-5555</span>
</label>
<input type="tel" id="phone"
aria-required="true"
placeholder="(555) 555-5555"
pattern="\([0-9]{3}\) [0-9]{3}-[0-9]{4}">
</form>Common Understandable Failures
- Missing page language
- Unexpected context changes on focus
- Inconsistent navigation between pages
- Error messages without clear solutions
- Required fields not clearly identified
- No confirmation for significant actions
Robust: Technology Compatibility
The Principle
Content must be robust enough to be interpreted reliably by a wide variety of user agents, including assistive technologies. This ensures content works now and remains accessible as technologies evolve.
What Robust Covers
Guideline 4.1: Compatible Maximize compatibility with current and future user agents.
Implementing Robust Design
Valid HTML structure:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Page Title</title>
</head>
<body>
<!-- Proper nesting -->
<header>
<nav>
<ul>
<li><a href="/">Home</a></li>
</ul>
</nav>
</header>
<!-- Unique IDs -->
<main id="main-content">
<h1>Unique Page Heading</h1>
</main>
<!-- Proper closing tags -->
<footer>
<p>Copyright 2024</p>
</footer>
</body>
</html>Proper ARIA usage:
<!-- Custom widget with complete ARIA -->
<div role="tablist" aria-label="Product information">
<button role="tab"
id="tab-1"
aria-selected="true"
aria-controls="panel-1">
Description
</button>
<button role="tab"
id="tab-2"
aria-selected="false"
aria-controls="panel-2"
tabindex="-1">
Specifications
</button>
</div>
<div role="tabpanel"
id="panel-1"
aria-labelledby="tab-1">
Description content...
</div>
<div role="tabpanel"
id="panel-2"
aria-labelledby="tab-2"
hidden>
Specifications content...
</div>Status messages:
<!-- Announce dynamic updates -->
<div role="status" aria-live="polite" aria-atomic="true">
<!-- Updated content announced to screen readers -->
3 items added to cart
</div>
<!-- Alert for important messages -->
<div role="alert">
Your session will expire in 5 minutes.
</div>
<!-- Progress updates -->
<div role="progressbar"
aria-valuenow="75"
aria-valuemin="0"
aria-valuemax="100"
aria-label="Upload progress">
75% complete
</div>Name, Role, Value compliance:
<!-- Interactive elements must expose name, role, and value -->
<!-- Native elements handle this automatically -->
<button>Submit Order</button>
<!-- Name: "Submit Order", Role: button -->
<input type="checkbox" id="terms" checked>
<label for="terms">I agree to terms</label>
<!-- Name: "I agree to terms", Role: checkbox, Value: checked -->
<!-- Custom elements need explicit ARIA -->
<div role="checkbox"
tabindex="0"
aria-checked="true"
aria-labelledby="custom-label">
<span id="custom-label">I agree to terms</span>
</div>Common Robust Failures
- Duplicate ID attributes
- Invalid HTML nesting
- Missing ARIA states on custom widgets
- Broken ARIA references (aria-describedby pointing to non-existent ID)
- Inappropriate ARIA roles
POUR in Practice
Design Phase
Apply POUR during design:
Perceivable:
- Specify color contrast ratios
- Plan for text alternatives
- Design without color as sole indicator
Operable:
- Design obvious focus states
- Include keyboard shortcuts in specs
- Plan touch target sizes
Understandable:
- Write clear labels and instructions
- Design consistent patterns
- Plan error states
Robust:
- Specify semantic structure
- Document component behaviors
- Plan ARIA requirements
Development Phase
Validate POUR during development:
// Automated POUR checks
const pourChecklist = {
perceivable: [
'All images have alt attributes',
'Color contrast meets 4.5:1',
'Information not conveyed by color alone',
'Audio has transcripts'
],
operable: [
'All interactive elements keyboard accessible',
'Focus visible on all elements',
'No keyboard traps',
'Skip links present'
],
understandable: [
'Page language declared',
'Form errors clearly described',
'Consistent navigation',
'Clear instructions provided'
],
robust: [
'Valid HTML structure',
'ARIA used correctly',
'Status messages announced',
'Unique IDs throughout'
]
};Testing Phase
Test each POUR principle:
| Principle | Testing Method |
|----------------|---------------------------------------------------------|
| Perceivable | Screen reader, color blindness simulators, zoom to 200% |
| Operable | Keyboard-only navigation, switch device, voice control |
| Understandable | Plain language check, user testing, consistency review |
| Robust | HTML validation, ARIA testing, cross-browser testing |Taking Action
POUR principles provide the conceptual framework for all accessibility work. Understanding why each principle exists—and what user needs it addresses—enables better design decisions and more effective implementation. Use POUR as a mental model when building features and evaluating accessibility.
TestParty provides continuous monitoring across all POUR principles, catching issues before they impact users.
Schedule a TestParty demo and get a 14-day compliance implementation plan.
Related Resources


Automate the software work for accessibility compliance, end-to-end.
Empowering businesses with seamless digital accessibility solutions—simple, inclusive, effective.
Book a Demo