Welcome to this comprehensive guide on implementing accessibility in web and mobile design. Accessibility isn't just a nice-to-have feature-it's about ensuring that everyone, regardless of their abilities, can access and use digital products effectively. Think of accessibility like building ramps alongside staircases: both get people to their destination, but different people need different paths.
In this document, we'll explore practical, hands-on techniques for making your designs accessible. You'll learn not just what to do, but how to do it and why it matters.
Before diving into implementation, let's establish what accessibility means in practical terms. When we talk about accessible design, we're considering people with various disabilities:
Think of your website or app as a public building. Just as a physical space needs multiple ways to navigate-elevators, ramps, stairs, clear signage-digital spaces need multiple ways to perceive and interact with content.
Semantic HTML is like using the proper ingredients in a recipe. You could technically make a cake using only flour and water, but it wouldn't be very good. Similarly, you could build a website using only div and span elements, but it wouldn't be accessible.
Screen readers-software that reads web content aloud to people with visual impairments-rely heavily on HTML structure to understand and navigate pages. When you use semantic HTML, you're providing a roadmap that assistive technologies can follow.

Headings (h1 through h6) create an outline of your page. Think of them like a book's table of contents-each level represents a different depth of organization.
Correct Heading Structure:
<h1>Main Page Title</h1>
<h2>First Major Section</h2>
<h3>Subsection</h3>
<h3>Another Subsection</h3>
<h2>Second Major Section</h2>
<h3>Subsection</h3>
Important rules for headings:
ARIA (Accessible Rich Internet Applications) is like adding translation notes to your HTML. When semantic HTML alone can't fully describe what something does, ARIA fills in the gaps.
The most important rule is: Don't use ARIA if you can use native HTML instead. ARIA should supplement HTML, not replace it. For example:
Bad approach:
<div role="button" tabindex="0">Click me</div>
Good approach:
<button>Click me</button>
aria-label provides an accessible name when visible text isn't sufficient:
<button aria-label="Close navigation menu">
<svg>...X icon...</svg>
</button>
aria-labelledby references another element to provide a label:
<h2 id="shipping-heading">Shipping Information</h2>
<div aria-labelledby="shipping-heading">
Address fields...
</div>
aria-describedby provides additional descriptive information:
<input type="password" aria-describedby="password-requirements">
<p id="password-requirements">Must be at least 8 characters</p>
aria-live announces dynamic content changes:
<div aria-live="polite">
Item added to cart
</div>
The aria-live attribute has three values:
Roles define what an element is or does. Modern semantic HTML often makes roles unnecessary, but they're useful for custom components:
These communicate the current state of interactive elements:
<button aria-expanded="false" aria-controls="menu-list">
Menu
</button>
<ul id="menu-list" aria-hidden="true">
<li>Home</li>
<li>About</li>
</ul>
Common state attributes include:
Imagine trying to use a computer with your mouse unplugged. Many users navigate this way every day-whether due to motor impairments, preference, or efficiency. Your interface must be fully usable with just a keyboard.
Focus is like a spotlight that highlights which element is currently active. Users navigate using specific keys:
Interactive elements should naturally receive keyboard focus. Some elements are focusable by default (buttons, links, form inputs), while others need help.
The tabindex attribute controls focus behavior:

Example of custom interactive element:
<div role="button" tabindex="0" onkeypress="handleKey(event)">
Custom Button
</div>
Focus indicators are the visual outline that appears around focused elements. Never remove focus indicators without providing an alternative! Think of them as the cursor of keyboard navigation-removing them is like making the mouse cursor invisible.
If the default browser focus outline doesn't match your design, create a custom one that's at least as visible:
Good practice: Enhance the default focus style
Never: Remove it entirely with outline: none without a replacement
Skip links are like express elevators in a tall building. They let keyboard users jump past repetitive content (like navigation menus) straight to the main content.
<body>
<a href="#main-content" class="skip-link">Skip to main content</a>
<header>...navigation...</header>
<main id="main-content">...</main>
</body>
Skip links are often visually hidden until focused, appearing only when a keyboard user tabs to them.
When a modal dialog opens, focus should be trapped inside it-users shouldn't be able to tab to content behind the modal. Think of it like a conversational detour: you finish the current topic before moving on.
When implementing modal dialogs:
Color accessibility is about more than just making things "look nice"-it's about ensuring information is perceivable by everyone, including people with color blindness or low vision.
Contrast ratio measures the difference in brightness between text and its background. It's expressed as a ratio like 4.5:1, where higher numbers mean more contrast.
Minimum contrast requirements:
Think of contrast like the volume on a speaker. If the volume (contrast) is too low, some people won't be able to hear (see) the content clearly.
Never use color as the only way to convey information. About 8% of men and 0.5% of women have some form of color blindness.
Bad: "Required fields are shown in red"
Good: "Required fields are marked with an asterisk (*) and shown in red"
Examples of combining color with other indicators:
Readable text is accessible text. Follow these guidelines:
Images are invisible to screen readers unless you provide alternative text. Think of alt text as a verbal description you'd give someone over the phone.
The alt attribute serves different purposes depending on the image's function:
Describe the content and function:
<img src="https://cn.edurev.in/hart.png" alt="Bar chart showing sales increased 25% from 2022 to 2023">
Use empty alt text (but include the attribute!):
<img src="https://cn.edurev.in/ecorative-border.png" alt="">
Describe the action, not the image:
<img src="https://cn.edurev.in/agnifying-glass.png" alt="Search">
Not: <img src="https://cn.edurev.in/agnifying-glass.png" alt="Magnifying glass icon">
For complex images like detailed charts or infographics, provide a short alt text and a longer description elsewhere:
<img src="https://cn.edurev.in/rg-chart.png" alt="Company organizational chart" aria-describedby="org-description">
<div id="org-description">
Detailed description of organizational structure...
</div>
Forms are the primary way users interact with web applications. An inaccessible form is like a door with no handle-you can see it, but you can't use it.
Every form input must have an associated label. The label element creates a programmatic relationship that assistive technologies can understand:
Method 1: Explicit association (recommended)
<label for="email-address">Email Address</label>
<input type="email" id="email-address" name="email">
Method 2: Implicit association
<label>
Email Address
<input type="email" name="email">
</label>
Placeholder text is not a substitute for labels. Placeholders disappear when you start typing, have low contrast, and aren't reliably read by screen readers.
Bad:
<input type="text" placeholder="Enter your name">
Good:
<label for="name">Name</label>
<input type="text" id="name" placeholder="e.g., John Smith">
Use fieldset and legend to group related form controls:
<fieldset>
<legend>Shipping Address</legend>
<label for="street">Street</label>
<input type="text" id="street">
<label for="city">City</label>
<input type="text" id="city">
</fieldset>
This is especially important for radio button groups:
<fieldset>
<legend>How would you like to receive updates?</legend>
<label><input type="radio" name="updates" value="email"> Email</label>
<label><input type="radio" name="updates" value="sms"> Text message</label>
<label><input type="radio" name="updates" value="none"> No updates</label>
</fieldset>
Indicate required fields in multiple ways:
<label for="username">
Username <span aria-label="required">*</span>
</label>
<input type="text" id="username" required aria-required="true">
Include a note at the form's beginning explaining your notation:
<p>Fields marked with an asterisk (*) are required.</p>
When validation fails, provide clear, helpful error messages:
<label for="phone">Phone Number</label>
<input type="tel" id="phone" aria-invalid="true" aria-describedby="phone-error">
<span id="phone-error" role="alert">
Please enter a valid phone number in the format: (555) 555-5555
</span>
The aria-invalid attribute tells assistive technologies the field has an error, while aria-describedby connects the error message to the field.
The autocomplete attribute helps users fill forms faster and reduces errors. It's especially helpful for users with cognitive disabilities:
<input type="text" id="fname" autocomplete="given-name">
<input type="text" id="lname" autocomplete="family-name">
<input type="email" id="email" autocomplete="email">
<input type="tel" id="phone" autocomplete="tel">
Video and audio content need text alternatives, just like images. Think of it like providing subtitles at a movie theater-some people need them to understand the content.
These terms are often confused but have distinct meanings:
Accessible video content should include:
Use the track element within a video tag:
<video controls>
<source src="https://cn.edurev.in/ideo.mp4" type="video/mp4">
<track kind="captions" src="https://cn.edurev.in/aptions-en.vtt" srclang="en" label="English" default>
<track kind="captions" src="https://cn.edurev.in/aptions-es.vtt" srclang="es" label="Spanish">
<track kind="descriptions" src="https://cn.edurev.in/escriptions.vtt" srclang="en" label="English Descriptions">
</video>
The kind attribute specifies the track type:
Podcasts and audio files need transcripts. A transcript should include:
Mobile accessibility adds unique challenges because of smaller screens, touch interfaces, and varied usage contexts (like using a phone in bright sunlight or while walking).
Touch targets should be large enough for fingers, not just mouse pointers. Think of it like designing buttons for someone wearing mittens.
Recommended touch target sizes:
If visual design requires smaller elements, increase the touch area invisibly:
A small icon might be 24 × 24 pixels visually,
but the tappable area should extend to 48 × 48 pixels
Don't lock orientation to portrait or landscape only-allow both unless it's essential to functionality (like a camera app). Never disable zoom or restrict scaling:
Bad:
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
Good:
<meta name="viewport" content="width=device-width, initial-scale=1">
Mobile screen readers use gestures different from desktop navigation:
Test your mobile designs with VoiceOver (iOS) or TalkBack (Android) enabled to ensure proper navigation flow.
Responsive design supports accessibility by adapting to different screen sizes and user preferences. Key principles:
Good navigation is like clear signage in a building-it helps everyone find their way, but it's essential for people who can't see the big picture at once.
Keep navigation patterns consistent across your site or app:
Provide several ways to find content:
Breadcrumbs show users where they are in the site structure:
<nav aria-label="Breadcrumb">
<ol>
<li><a href="/">Home</a></li>
<li><a href="/products">Products</a></li>
<li><a href="/products/laptops">Laptops</a></li>
<li aria-current="page">MacBook Pro</li>
</ol>
</nav>
The aria-current="page" attribute marks the current location.
Link text should make sense out of context. Screen reader users often navigate by jumping from link to link, hearing only the link text.
Bad: "Click here for more information"
Good: "Learn more about accessibility testing"
Bad: "Read more"
Good: "Read more about semantic HTML"
Tables organize related information into rows and columns. When properly marked up, screen readers can navigate tables cell-by-cell while announcing row and column headers.
Use th elements for header cells and td for data cells:
<table>
<caption>Monthly Sales Report</caption>
<thead>
<tr>
<th>Month</th>
<th>Sales</th>
<th>Target</th>
</tr>
</thead>
<tbody>
<tr>
<td>January</td>
<td>$45,000</td>
<td>$50,000</td>
</tr>
</tbody>
</table>
The caption element provides a title for the table, giving context before users navigate the data.
For tables with multiple header levels or irregular structures, use scope or headers attributes:
<th scope="col">Column Header</th> - applies to entire column
<th scope="row">Row Header</th> - applies to entire row
<th scope="colgroup">Header for Column Group</th>
<th scope="rowgroup">Header for Row Group</th>
Never use tables for page layout-that's what CSS is for. Tables should only contain tabular data. Screen readers announce tables as data tables, which creates confusion when they're used for layout.
Testing is crucial because you can't fix what you don't know is broken. Comprehensive accessibility testing combines automated tools, manual testing, and real user feedback.
Automated tools catch many common issues quickly:
However, automated tools only catch about 30-40% of accessibility issues. They can't evaluate whether alt text is meaningful or if the keyboard navigation order makes sense.
Test these aspects manually:
Nothing replaces testing with actual users who have disabilities. They'll discover issues and usage patterns you'd never anticipate. Include people with various disabilities in your user testing:
Let's explore frequent accessibility errors and how to fix them:
Wrong: <img src="https://cn.edurev.in/hoto123.jpg"> - no alt attribute
Wrong: <img src="https://cn.edurev.in/og.jpg" alt="image"> - meaningless alt text
Right: <img src="https://cn.edurev.in/og.jpg" alt="Golden retriever puppy playing with a ball">
Wrong: <a href="/search"><svg>...</svg></a>
Right: <a href="/search" aria-label="Search"><svg>...</svg></a>
Wrong: Light gray text (#999) on white background - 2.8:1 ratio
Right: Dark gray text (#595959) on white background - 7:1 ratio
Wrong: Download the report <a href="report.pdf">here</a>
Right: <a href="report.pdf">Download the annual sales report (PDF, 2MB)</a>
Wrong: <div onclick="toggleMenu()">Menu</div>
Right: <button onclick="toggleMenu()" aria-expanded="false">Menu</button>
Wrong: <input type="text" placeholder="Email">
Right: <label for="email">Email</label><input type="text" id="email">
Progressive enhancement is a strategy that starts with a solid, accessible foundation and adds enhanced features for capable browsers. Think of it like building a house: start with a strong foundation, then add improvements.
Each layer should work independently. If JavaScript fails to load or is disabled, the core functionality should still work through HTML forms and links.
Consider a filtering interface for products:
Base layer (HTML):
Traditional form with checkboxes and a submit button
Enhanced layer (JavaScript):
Live filtering without page reload
Result:
Everyone can filter products, but modern browsers get a smoother experience
Single-page applications and complex interactive interfaces present unique accessibility challenges because content changes without page reloads.
When content changes dynamically, users need to know what happened and where to go next:
Use ARIA live regions to announce content changes:
<div role="status" aria-live="polite" aria-atomic="true">
3 items added to cart
</div>
The aria-atomic attribute tells screen readers whether to announce just the changed part (false) or the entire region (true).
When routes change without page reloads, screen reader users don't get the automatic announcement of a new page. Handle this by:
Designers and developers must communicate accessibility requirements clearly. When handing off designs, include:
Think of accessibility annotations like assembly instructions for furniture-without them, something important might get built incorrectly.
Accessibility isn't a one-time checkbox-it's an ongoing commitment. As you add features and update content, maintain accessibility through:
Beyond the moral and legal imperatives, accessibility makes business sense:
Remember: accessibility is not about perfect compliance with every guideline-it's about removing barriers and creating inclusive experiences. Start where you are, test with real users, iterate based on feedback, and continuously improve. Every step toward better accessibility makes your product more usable for everyone.