<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ aria - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ aria - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Mon, 25 May 2026 15:48:11 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/aria/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Build Responsive and Accessible UI Designs with React and Semantic HTML ]]>
                </title>
                <description>
                    <![CDATA[ Building modern React applications requires more than just functionality. It also demands responsive layouts and accessible user experiences. By combining semantic HTML, responsive design techniques,  ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-responsive-accessible-ui-with-react-and-semantic-html/</link>
                <guid isPermaLink="false">69d539975da14bc70e76871d</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Accessibility ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Responsive Web Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ semantichtml ]]>
                    </category>
                
                    <category>
                        <![CDATA[ aria ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UI ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Gopinath Karunanithi ]]>
                </dc:creator>
                <pubDate>Tue, 07 Apr 2026 17:06:31 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/d2651d02-040d-4c4f-bbfe-ef92097edab4.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Building modern React applications requires more than just functionality. It also demands responsive layouts and accessible user experiences.</p>
<p>By combining semantic HTML, responsive design techniques, and accessibility best practices (like ARIA roles and keyboard navigation), developers can create interfaces that work across devices and for all users, including those with disabilities.</p>
<p>This article shows how to design scalable, inclusive React UIs using real-world patterns and code examples.</p>
<h2 id="heading-table-of-contents"><strong>Table of Contents</strong></h2>
<ul>
<li><p><a href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a href="#heading-overview">Overview</a></p>
</li>
<li><p><a href="#heading-why-accessibility-and-responsiveness-matter">Why Accessibility and Responsiveness Matter</a></p>
</li>
<li><p><a href="#heading-core-principles-of-accessible-and-responsive-design">Core Principles of Accessible and Responsive Design</a></p>
</li>
<li><p><a href="#heading-using-semantic-html-in-react">Using Semantic HTML in React</a></p>
</li>
<li><p><a href="#heading-structuring-a-page-with-semantic-elements">Structuring a Page with Semantic Elements</a></p>
</li>
<li><p><a href="#heading-building-responsive-layouts">Building Responsive Layouts</a></p>
</li>
<li><p><a href="#heading-accessibility-with-aria">Accessibility with ARIA</a></p>
</li>
<li><p><a href="#heading-keyboard-navigation">Keyboard Navigation</a></p>
</li>
<li><p><a href="#heading-focus-management">Focus Management</a></p>
</li>
<li><p><a href="#heading-forms-and-accessibility">Forms and Accessibility</a></p>
</li>
<li><p><a href="#heading-responsive-typography-and-images">Responsive Typography and Images</a></p>
</li>
<li><p><a href="#heading-building-a-fully-accessible-responsive-component-end-to-end-example">Building a Fully Accessible Responsive Component (End-to-End Example)</a></p>
</li>
<li><p><a href="#heading-testing-accessibility">Testing Accessibility</a></p>
</li>
<li><p><a href="#heading-best-practices">Best Practices</a></p>
</li>
<li><p><a href="#heading-when-not-to-overuse-accessibility-features">When NOT to Overuse Accessibility Features</a></p>
</li>
<li><p><a href="#heading-future-enhancements">Future Enhancements</a></p>
</li>
<li><p><a href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before following along, you should be familiar with:</p>
<ul>
<li><p>React fundamentals (components, hooks, JSX)</p>
</li>
<li><p>Basic HTML and CSS</p>
</li>
<li><p>JavaScript ES6 features</p>
</li>
<li><p>Basic understanding of accessibility concepts (helpful but not required)</p>
</li>
</ul>
<h2 id="heading-overview">Overview</h2>
<p>Modern web applications must serve a diverse audience across a wide range of devices, screen sizes, and accessibility needs. Users today expect seamless experiences whether they are browsing on a desktop, tablet, or mobile device – and they also expect interfaces that are usable regardless of physical or cognitive limitations.</p>
<p>Two essential principles help achieve this:</p>
<ul>
<li><p>Responsive design, which ensures layouts adapt to different screen sizes</p>
</li>
<li><p>Accessibility, which ensures applications are usable by people with disabilities</p>
</li>
</ul>
<p>In React applications, these principles are often implemented incorrectly or treated as afterthoughts. Developers may rely heavily on div-based layouts, ignore semantic HTML, or overlook accessibility features such as keyboard navigation and screen reader support.</p>
<p>This article will show you how to build responsive and accessible UI designs in React using semantic HTML. You'll learn how to:</p>
<ul>
<li><p>Structure components using semantic HTML elements</p>
</li>
<li><p>Build responsive layouts using modern CSS techniques</p>
</li>
<li><p>Improve accessibility with ARIA attributes and proper roles</p>
</li>
<li><p>Ensure keyboard navigation and screen reader compatibility</p>
</li>
<li><p>Apply best practices for scalable and inclusive UI design</p>
</li>
</ul>
<p>By the end of this guide, you'll be able to create React interfaces that are not only visually responsive but also accessible to all users.</p>
<h2 id="heading-why-accessibility-and-responsiveness-matter">Why Accessibility and Responsiveness Matter</h2>
<p>Responsive and accessible design isn't just about compliance. It directly impacts usability, performance, and reach.</p>
<p><strong>Accessibility benefits:</strong></p>
<ul>
<li><p>Supports users with visual, motor, or cognitive impairments</p>
</li>
<li><p>Improves SEO and content discoverability</p>
</li>
<li><p>Enhances usability for all users</p>
</li>
</ul>
<p><strong>Responsiveness benefits:</strong></p>
<ul>
<li><p>Ensures consistent UX across devices</p>
</li>
<li><p>Reduces bounce rates on mobile</p>
</li>
<li><p>Improves performance and scalability</p>
</li>
</ul>
<p>Ignoring these principles can result in broken layouts on smaller screens, poor screen reader compatibility, and limited reach and usability.</p>
<h2 id="heading-core-principles-of-accessible-and-responsive-design">Core Principles of Accessible and Responsive Design</h2>
<p>Before diving into the code, it’s important to understand the foundational principles.</p>
<h3 id="heading-1-semantic-html-first">1. Semantic HTML First</h3>
<p>Semantic HTML refers to using HTML elements that clearly describe their meaning and role in the interface, rather than relying on generic containers like <code>&lt;div&gt; or &lt;span&gt;.</code>These elements provide built-in accessibility, improve SEO, and make code more readable.</p>
<p>For example:</p>
<p><strong>Non-semantic:</strong></p>
<pre><code class="language-html">&lt;div onClick={handleClick}&gt;Submit&lt;/div&gt;
</code></pre>
<p><strong>Semantic:</strong></p>
<pre><code class="language-html">&lt;button type="button" onClick={handleClick}&gt;Submit&lt;/button&gt;
</code></pre>
<p>Another example:</p>
<p><strong>Non-semantic:</strong></p>
<pre><code class="language-html">&lt;div className="header"&gt;My App&lt;/div&gt;
</code></pre>
<p><strong>Semantic:</strong></p>
<pre><code class="language-html">&lt;header&gt;My App&lt;/header&gt;
</code></pre>
<p>Using semantic elements such as <code>&lt;header&gt;</code>, <code>&lt;nav&gt;</code>, <code>&lt;main&gt;</code>, <code>&lt;section&gt;</code>, <code>&lt;article&gt;</code>, and <code>&lt;button&gt;</code> helps browsers and assistive technologies (like screen readers) understand the structure and purpose of your UI without additional configuration.</p>
<p>Why this matters:</p>
<ul>
<li><p>Screen readers understand semantic elements automatically</p>
</li>
<li><p>It supports built-in accessibility (keyboard, focus, roles)</p>
</li>
<li><p>There's less need for ARIA attributes</p>
</li>
<li><p>It gives you better SEO and maintainability</p>
</li>
</ul>
<h3 id="heading-2-mobile-first-design">2. Mobile-First Design</h3>
<p>Mobile-first design means starting your UI design with the smallest screen sizes (typically mobile devices) and progressively enhancing the layout for larger screens such as tablets and desktops.</p>
<p>This approach makes sure that core content and functionality are prioritized, layouts remain simple and performant, and users on mobile devices get a fully usable experience.</p>
<p>In practice, mobile-first design involves:</p>
<ul>
<li><p>Using a single-column layout initially</p>
</li>
<li><p>Applying minimal styling and spacing</p>
</li>
<li><p>Avoiding complex UI patterns on small screens</p>
</li>
</ul>
<p>Then, you scale up using CSS media queries:</p>
<pre><code class="language-css">.container {
  display: flex;
  flex-direction: column;
}
@media (min-width: 768px) {
  .container {
    flex-direction: row;
  }
}
</code></pre>
<p>Here, the default layout is optimized for mobile, and enhancements are applied only when the screen size increases.</p>
<p><strong>Why this approach works:</strong></p>
<ul>
<li><p>Prioritizes essential content</p>
</li>
<li><p>Improves performance on mobile devices</p>
</li>
<li><p>Reduces layout bugs when scaling up</p>
</li>
<li><p>Aligns with how most users access web apps today</p>
</li>
</ul>
<h3 id="heading-3-progressive-enhancement">3. Progressive Enhancement</h3>
<p>Progressive enhancement is the practice of building a baseline user experience that works for all users (regardless of their device, browser capabilities, or network conditions) and then layering on advanced features for more capable environments.</p>
<p>This approach ensures that core functionality is always accessible, users on older devices or slow networks aren't blocked, and accessibility is preserved even when advanced features fail.</p>
<p>In practice, this means:</p>
<ul>
<li><p>Start with semantic HTML that delivers content and functionality</p>
</li>
<li><p>Add basic styling with CSS for layout and readability</p>
</li>
<li><p>Enhance interactivity using JavaScript (React) only where needed</p>
</li>
</ul>
<p>For example, a form should still be usable with plain HTML:</p>
<pre><code class="language-html">&lt;form&gt;
  &lt;label htmlFor="email"&gt;Email&lt;/label&gt;
  &lt;input id="email" type="email" /&gt;
  &lt;button type="submit"&gt;Submit&lt;/button&gt;
&lt;/form&gt;
</code></pre>
<p>Then, React can enhance it with validation, dynamic feedback, or animations.</p>
<p>By prioritizing functionality first and enhancements later, you ensure your application remains usable in a wide range of real-world scenarios.</p>
<h3 id="heading-4-keyboard-accessibility">4. Keyboard Accessibility</h3>
<p>Keyboard accessibility ensures that users can navigate and interact with your application using only a keyboard. This is critical for users with motor disabilities and also improves usability for power users.</p>
<p>Key aspects of keyboard accessibility include:</p>
<ul>
<li><p>Ensuring all interactive elements (buttons, links, inputs) are focusable</p>
</li>
<li><p>Maintaining a logical tab order across the page</p>
</li>
<li><p>Providing visible focus indicators (for example, outline styles)</p>
</li>
<li><p>Supporting keyboard events such as Enter and Space</p>
</li>
</ul>
<p><strong>Bad Example (Not Accessible)</strong></p>
<pre><code class="language-html">&lt;div onClick={handleClick}&gt;Submit&lt;/div&gt;
</code></pre>
<p>This element:</p>
<ul>
<li><p>Cannot be focused with a keyboard</p>
</li>
<li><p>Does not respond to Enter/Space</p>
</li>
<li><p>Is invisible to screen readers</p>
</li>
</ul>
<p><strong>Good Example</strong></p>
<pre><code class="language-html">&lt;button type="button" onClick={handleClick}&gt;Submit&lt;/button&gt;
</code></pre>
<p>This automatically supports:</p>
<ul>
<li><p>Keyboard interaction</p>
</li>
<li><p>Focus management</p>
</li>
<li><p>Screen reader announcements</p>
</li>
</ul>
<p><strong>Custom Component Example (if needed)</strong></p>
<pre><code class="language-html">&lt;div
  role="button"
  tabIndex={0}
  onClick={handleClick}
  onKeyDown={(e) =&gt; {
    if (e.key === 'Enter' || e.key === ' ') {
      e.preventDefault();
      handleClick();
    }
  }}
&gt;
  Submit
&lt;/div&gt;
</code></pre>
<p>But only use this when native elements aren't sufficient.</p>
<p>These principles form the foundation of accessible and responsive design:</p>
<ul>
<li><p>Use semantic HTML to communicate intent</p>
</li>
<li><p>Design for mobile first, then scale up</p>
</li>
<li><p>Enhance progressively for better compatibility</p>
</li>
<li><p>Ensure full keyboard accessibility</p>
</li>
</ul>
<p>Applying these early prevents major usability and accessibility issues later in development.</p>
<h2 id="heading-using-semantic-html-in-react">Using Semantic HTML in React</h2>
<p>As we briefly discussed above, semantic HTML plays a critical role in both accessibility (a11y) and code readability. Semantic elements clearly describe their purpose to both developers and browsers, which allows assistive technologies like screen readers to interpret and navigate the UI correctly.</p>
<p>For example, when you use a <code>&lt;button&gt;</code> element, browsers automatically provide keyboard support, focus behavior, and accessibility roles. In contrast, non-semantic elements like <code>&lt;div&gt;</code>require additional attributes and manual handling to achieve the same functionality.</p>
<p>From a readability perspective, semantic HTML makes your code easier to understand and maintain. Developers can quickly identify the structure and intent of a component without relying on class names or external documentation.</p>
<p><strong>Bad Example (Non-semantic)</strong></p>
<pre><code class="language-html">&lt;div onClick={handleClick}&gt;Submit&lt;/div&gt;
</code></pre>
<p>Why this is problematic:</p>
<ul>
<li><p>The <code>&lt;div&gt;</code>element has no inherent meaning or role</p>
</li>
<li><p>It is not focusable by default, so keyboard users can't access it</p>
</li>
<li><p>It does not respond to keyboard events like Enter or Space unless explicitly coded</p>
</li>
<li><p>Screen readers do not recognize it as an interactive element</p>
</li>
</ul>
<p>To make this accessible, you would need to add:</p>
<p><code>role="button"</code></p>
<p><code>tabIndex="0"</code></p>
<p><code>Keyboard event handlers</code></p>
<p><strong>Good Example (Semantic)</strong></p>
<pre><code class="language-html">&lt;button type="button" onClick={handleClick}&gt;Submit&lt;/button&gt;
</code></pre>
<p>Why this is better:</p>
<ul>
<li><p>The <code>&lt;button&gt;</code> element is inherently interactive</p>
</li>
<li><p>It is automatically focusable and keyboard accessible</p>
</li>
<li><p>It supports Enter and Space key activation by default</p>
</li>
<li><p>Screen readers correctly announce it as a button</p>
</li>
</ul>
<p>This reduces complexity while improving accessibility and usability.</p>
<h3 id="heading-why-all-this-matters">Why all this matters:</h3>
<p>There are many reasons to use semantic HTML.</p>
<p>First, semantic elements like <code>&lt;button&gt;, &lt;a&gt;,</code> and <code>&lt;form&gt;</code> come with default accessibility behaviors such as focus management and keyboard interaction</p>
<p>It also reduces complexity: you don’t need to manually implement roles, keyboard handlers, or tab navigation</p>
<p>They provide better screen reader support as well. Assistive technologies can correctly interpret the purpose of elements and announce them appropriately</p>
<p>Semantic HTML also improves maintainability and helps other developers quickly understand the intent of your code without reverse-engineering behavior from event handlers</p>
<p>Finally, you'll generally have fewer bugs in your code. Relying on native browser behavior reduces the risk of missing critical accessibility features</p>
<p>Here's another example:</p>
<p><strong>Non-semantic:</strong></p>
<pre><code class="language-html">&lt;div className="nav"&gt;
  &lt;div onClick={goHome}&gt;Home&lt;/div&gt;
&lt;/div&gt;
</code></pre>
<p><strong>Semantic:</strong></p>
<pre><code class="language-html">&lt;nav&gt;
  &lt;a href="/"&gt;Home&lt;/a&gt;
&lt;/nav&gt;
</code></pre>
<p>Here, <code>&lt;nav&gt;</code> clearly defines a navigation region, and <code>&lt;a&gt;</code> provides built-in link behavior, including keyboard navigation and proper screen reader announcements.</p>
<h2 id="heading-structuring-a-page-with-semantic-elements">Structuring a Page with Semantic Elements</h2>
<p>When building a React application, structuring your layout with semantic HTML elements helps define clear regions of your interface. Instead of relying on generic containers like <code>&lt;div&gt;</code>, semantic elements communicate the purpose of each section to both developers and assistive technologies.</p>
<p>In the example below, we're creating a basic page layout using commonly used semantic elements such as <code>&lt;header&gt;</code>, <code>&lt;nav&gt;</code>, <code>&lt;main&gt;</code>, <code>&lt;section&gt;</code>, and <code>&lt;footer&gt;</code>. Each of these elements represents a specific part of the UI and contributes to better accessibility and maintainability.</p>
<pre><code class="language-javascript">function Layout() {
  return (
    &lt;&gt;
      {/* Skip link for keyboard and screen reader users */}
      &lt;a href="#main-content" className="skip-link"&gt;
        Skip to main content
      &lt;/a&gt;

      &lt;header&gt;
        &lt;h1&gt;My App&lt;/h1&gt;
      &lt;/header&gt;

      &lt;nav&gt;
        &lt;ul&gt;
          &lt;li&gt;&lt;a href="/"&gt;Home&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/nav&gt;

      &lt;main id="main-content"&gt;
        &lt;section&gt;
          &lt;h2&gt;Dashboard&lt;/h2&gt;
        &lt;/section&gt;
      &lt;/main&gt;

      &lt;footer&gt;
        &lt;p&gt;© 2026&lt;/p&gt;
      &lt;/footer&gt;
    &lt;/&gt;
  );
}
</code></pre>
<p>Each element in this layout has a specific role:</p>
<ul>
<li><p>The skip link allows screen reader users to skip to the main content</p>
</li>
<li><p><code>&lt;header&gt;</code>: Represents introductory content or branding</p>
</li>
<li><p><code>&lt;nav&gt;</code>: Contains navigation links</p>
</li>
<li><p><code>&lt;main&gt;</code>: Holds the primary content of the page</p>
</li>
<li><p><code>&lt;section&gt;</code>: Groups related content within the page</p>
</li>
<li><p><code>&lt;footer&gt;</code>: Contains closing or supplementary information</p>
</li>
</ul>
<p>Using these elements correctly ensures your UI is both logically structured and accessible by default.</p>
<h3 id="heading-why-this-structure-is-important">Why this structure is important:</h3>
<p>Properly structuring a page like this brings with it many benefits.</p>
<p>For example, it gives you Improved screen reader navigation. This is because semantic elements allow screen readers to identify different regions of the page (for example, navigation, main content, footer). Users can quickly jump between these sections instead of reading the page linearly</p>
<p>It also gives you better document structure. Elements like <code>&lt;main&gt;</code> and <code>&lt;section&gt;</code> define a logical hierarchy, making content easier to parse for both browsers and assistive technologies</p>
<p>Search engines also use semantic structure to better understand page content and prioritize important sections, resulting in better SEO.</p>
<p>It also makes your code more readable, so other devs can immediately understand the layout and purpose of each section without relying on class names or comments</p>
<p>And it provides built-in accessibility landmarks using elements like <code>&lt;nav&gt;</code> and <code>&lt;main&gt;</code>, allowing assistive technologies to provide shortcuts for users.</p>
<h2 id="heading-building-responsive-layouts">Building Responsive Layouts</h2>
<p>Responsive layouts ensure that your UI adapts smoothly across different screen sizes, from mobile devices to large desktop displays. Instead of building separate layouts for each device, modern CSS techniques like Flexbox, Grid, and media queries allow you to create flexible, fluid designs.</p>
<p>In this section, we’ll look at how layout behavior changes based on screen size, starting with a mobile-first approach and progressively enhancing the layout for larger screens.</p>
<p><strong>Using CSS Flexbox:</strong></p>
<pre><code class="language-css">.container {
  display: flex;
  flex-direction: column;
}

@media (min-width: 768px) {
  .container {
    flex-direction: row;
  }
}
</code></pre>
<p>On smaller screens (mobile), elements are stacked vertically using <code>flex-direction: column</code>, making content easier to read and scroll.</p>
<p>On larger screens (768px and above), the layout switches to a horizontal row, utilizing available screen space more efficiently.</p>
<p><strong>Why this helps:</strong></p>
<ul>
<li><p>Ensures content is readable on small devices without horizontal scrolling</p>
</li>
<li><p>Improves layout efficiency on larger screens</p>
</li>
<li><p>Supports a mobile-first design strategy by defining the default layout for smaller screens first and enhancing it progressively</p>
</li>
</ul>
<p><strong>Using CSS Grid:</strong></p>
<pre><code class="language-css">.grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
}

@media (min-width: 768px) {
  .grid {
    grid-template-columns: repeat(3, 1fr);
  }
}
</code></pre>
<p>On mobile devices, content is displayed in a single-column layout (<code>1fr</code>), ensuring each item takes full width.</p>
<p>On larger screens, the layout shifts to three equal columns using <code>repeat(3, 1fr)</code>, creating a grid structure.</p>
<p><strong>Why this helps:</strong></p>
<ul>
<li><p>Provides a clean and consistent way to manage complex layouts</p>
</li>
<li><p>Makes it easy to scale from simple to multi-column designs</p>
</li>
<li><p>Improves visual balance and spacing across different screen sizes</p>
</li>
</ul>
<p><strong>React Example:</strong></p>
<pre><code class="language-javascript">function CardGrid() {
  return (
    &lt;div className="grid"&gt;
      &lt;div className="card"&gt;Item 1&lt;/div&gt;
      &lt;div className="card"&gt;Item 2&lt;/div&gt;
      &lt;div className="card"&gt;Item 3&lt;/div&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p>The React component uses the .grid class to apply responsive Grid behavior. Each card automatically adjusts its position based on screen size.</p>
<p><strong>Why this is effective:</strong></p>
<ul>
<li><p>Separates structure (React JSX) from layout (CSS)</p>
</li>
<li><p>Allows you to reuse the same component across different screen sizes without modification</p>
</li>
<li><p>Ensures consistent responsiveness across your application with minimal code</p>
</li>
</ul>
<p>By combining Flexbox for one-dimensional layouts and Grid for two-dimensional layouts, you can build highly adaptable interfaces that respond efficiently to different devices and screen sizes.</p>
<h2 id="heading-accessibility-with-aria">Accessibility with ARIA</h2>
<p>ARIA (Accessible Rich Internet Applications) is a set of attributes that enhance the accessibility of web content, especially when building custom UI components that cannot be fully implemented using native HTML elements.</p>
<p>ARIA works by providing additional semantic information to assistive technologies such as screen readers. It does this through:</p>
<ul>
<li><p>Roles, which define what an element is (for example, button, dialog, menu)</p>
</li>
<li><p>States and properties, which describe the current condition or behavior of an element (for example, expanded, hidden, live updates)</p>
</li>
</ul>
<p>For example, when you create a custom dropdown using <code>&lt;div&gt;</code> elements, browsers don't inherently understand its purpose. By applying ARIA roles and attributes, you can communicate that this structure behaves like a menu and ensure it is interpreted correctly.</p>
<p>Just make sure you use ARIA carefully. Incorrect or unnecessary usage can reduce accessibility. Here's a key rule to follow: use native HTML first. Only use ARIA when necessary.</p>
<p>ARIA is especially useful for:</p>
<ul>
<li><p>Custom UI components (modals, tabs, dropdowns)</p>
</li>
<li><p>Dynamic content updates</p>
</li>
<li><p>Complex interactions not covered by standard HTML</p>
</li>
</ul>
<p>Something to note before we get into the examples here: real-world accessibility is complex. For production apps, you should typically prefer well-tested libraries like react-aria, Radix UI, or Headless UI. These examples are primarily for educational purposes and aren't production-ready.</p>
<p><strong>Example: Accessible Modal</strong></p>
<pre><code class="language-javascript">function Modal({ isOpen, onClose }) {
  const dialogRef = React.useRef();

  React.useEffect(() =&gt; {
    if (isOpen) {
      dialogRef.current?.focus();
    }
  }, [isOpen]);

  if (!isOpen) return null;

  return (
    &lt;div
      role="dialog"
      aria-modal="true"
      aria-labelledby="modal-title"
      tabIndex={-1}
      ref={dialogRef}
      onKeyDown={(e) =&gt; {
        if (e.key === 'Escape') onClose();
      }}
    &gt;
      &lt;h2 id="modal-title"&gt;Modal Title&lt;/h2&gt;
      &lt;button type="button" onClick={onClose}&gt;Close&lt;/button&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p><strong>How this works:</strong></p>
<ul>
<li><p><code>role="dialog"</code> identifies the element as a modal dialog</p>
</li>
<li><p><code>aria-modal="true"</code> indicates that background content is inactive</p>
</li>
<li><p><code>aria-labelledby</code> connects the dialog to its visible title for screen readers</p>
</li>
<li><p><code>tabIndex={-1}</code> allows the dialog container to receive focus programmatically</p>
</li>
<li><p>Focus is moved to the dialog when it opens</p>
</li>
<li><p>Pressing Escape closes the modal, which is a standard accessibility expectation</p>
</li>
</ul>
<p>This ensures that users can understand, navigate, and exit the modal using both keyboard and assistive technologies.</p>
<h3 id="heading-key-aria-attributes">Key ARIA Attributes</h3>
<h4 id="heading-1-role">1. role</h4>
<p>Defines the type of element and its purpose. For example, <code>role="dialog"</code> tells assistive technologies that the element behaves like a modal dialog.</p>
<h4 id="heading-2-aria-label">2. aria-label</h4>
<p>Provides an accessible name for an element when visible text is not sufficient. Screen readers use this label to describe the element to users.</p>
<h4 id="heading-3-aria-hidden">3. aria-hidden</h4>
<p>Indicates whether an element should be ignored by assistive technologies. For example, <code>aria-hidden="true"</code> hides decorative elements from screen readers.</p>
<h4 id="heading-4-aria-live">4. aria-live</h4>
<p>Used for dynamic content updates. It tells screen readers to announce changes automatically without requiring user interaction (for example, form validation messages or notifications).</p>
<p><strong>Example: Accessible Dropdown (Custom Component)</strong></p>
<pre><code class="language-javascript">function Dropdown({ isOpen, toggle }) {
  return (
    &lt;div&gt;
      &lt;button
        type="button"
        aria-expanded={isOpen}
        aria-controls="dropdown-menu"
        onClick={toggle}
      &gt;
        Menu
      &lt;/button&gt;

      {isOpen &amp;&amp; (
        &lt;ul id="dropdown-menu"&gt;
          &lt;li&gt;
            &lt;button type="button" onClick={() =&gt; console.log('Item 1')}&gt;
              Item 1
            &lt;/button&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;button type="button" onClick={() =&gt; console.log('Item 2')}&gt;
              Item 2
            &lt;/button&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      )}
    &lt;/div&gt;
  );
}
</code></pre>
<p><strong>How this works:</strong></p>
<ul>
<li><p><code>aria-expanded</code> indicates whether the dropdown is open or closed</p>
</li>
<li><p><code>aria-controls</code> links the button to the dropdown content via its id</p>
</li>
<li><p>The <code>&lt;button&gt;</code> element acts as the trigger and is fully keyboard accessible</p>
</li>
<li><p>The <code>&lt;ul&gt;</code> and <code>&lt;li&gt;</code> elements provide a natural list structure</p>
</li>
<li><p>Using <code>&lt;a&gt;</code> elements ensures proper navigation behavior and accessibility</p>
</li>
</ul>
<p>Why this approach is correct:</p>
<ul>
<li><p>It follows standard web patterns instead of application-style menus</p>
</li>
<li><p>It avoids misusing ARIA roles like role="menu", which require complex keyboard handling</p>
</li>
<li><p>Screen readers can correctly interpret the structure without additional roles</p>
</li>
<li><p>It keeps the implementation simple, accessible, and maintainable</p>
</li>
</ul>
<p>If you need advanced menu behavior (like arrow key navigation), then ARIA menu roles may be appropriate –&nbsp;but only when fully implemented according to the ARIA Authoring Practices.</p>
<p>Note: Most dropdowns in web applications are not true "menus" in the ARIA sense. Avoid using role="menu" unless you are implementing full keyboard navigation (arrow keys, focus management, and so on).</p>
<h2 id="heading-keyboard-navigation">Keyboard Navigation</h2>
<p>Keyboard navigation ensures that users can fully interact with your application using only a keyboard, without relying on a mouse. This is essential for users with motor disabilities, but it also benefits power users and developers who prefer keyboard-based workflows.</p>
<p>In a well-designed interface, users should be able to:</p>
<ul>
<li><p>Navigate through interactive elements using the Tab key</p>
</li>
<li><p>Activate buttons and links using Enter or Space</p>
</li>
<li><p>Clearly see which element is currently focused</p>
</li>
</ul>
<p>In the example below, we’ll look at common mistakes in keyboard handling and why relying on native HTML elements is usually the better approach.</p>
<p><strong>Example:</strong></p>
<p>Avoid adding custom keyboard handlers to native elements like <code>&lt;button&gt;</code>, as they already support keyboard interaction by default.</p>
<p>For example, this is all you need:</p>
<pre><code class="language-html">&lt;button type="button" onClick={handleClick}&gt;Submit&lt;/button&gt;
</code></pre>
<p>This automatically supports:</p>
<ul>
<li><p>Enter and Space key activation</p>
</li>
<li><p>Focus management</p>
</li>
<li><p>Screen reader announcements</p>
</li>
</ul>
<p>Adding manual keyboard event handlers here is unnecessary and can introduce bugs or inconsistent behavior.</p>
<p><strong>What this example shows:</strong></p>
<p>Avoid manually handling keyboard events for native interactive elements like <code>&lt;button&gt;</code>. These elements already provide built-in keyboard support and accessibility features.</p>
<p>For example:</p>
<pre><code class="language-html">&lt;button type="button" onClick={handleClick}&gt;Submit&lt;/button&gt;
</code></pre>
<p>Why this works:</p>
<ul>
<li><p>Supports both Enter and Space key activation by default</p>
</li>
<li><p>Is focusable and participates in natural tab order</p>
</li>
<li><p>Provides built-in accessibility roles and screen reader announcements</p>
</li>
<li><p>Reduces the need for additional logic or ARIA attributes</p>
</li>
</ul>
<p>Adding custom keyboard handlers (like onKeyDown) to native elements is unnecessary and can introduce bugs or inconsistent behavior. Always prefer native HTML elements for interactivity whenever possible.</p>
<h3 id="heading-avoiding-common-keyboard-traps">Avoiding Common Keyboard Traps</h3>
<p>One of the most common keyboard accessibility issues is “trapping users inside interactive components”, such as modals or custom dropdowns. This happens when focus is moved into a component but can't escape using Tab, Shift+Tab, or other keyboard controls. Users relying on keyboards may become stuck, unable to navigate to other parts of the page.</p>
<p>In the example below, you'll see a simple modal that tries to set focus, but doesn’t manage Tab behavior properly.</p>
<pre><code class="language-javascript">function Modal({ isOpen }) {
  const ref = React.useRef();

  React.useEffect(() =&gt; {
    if (isOpen) ref.current?.focus();
  }, [isOpen]);

  return (
    &lt;div role="dialog"&gt;
      &lt;button type="button" ref={ref}&gt;Close&lt;/button&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p>What this code shows:</p>
<ul>
<li><p>When the modal opens, focus is moved to the Close button using <code>ref.current.focus()</code></p>
</li>
<li><p>The modal uses <code>role="dialog"</code> to communicate its purpose</p>
</li>
</ul>
<p>There are some issues with this code that you should be aware of. First, tabbing inside the modal may allow focus to move outside the modal if additional focusable elements exist.</p>
<p>Users may also become trapped if no mechanism returns focus to the triggering element when the modal closes.</p>
<p>There's also no handling of Shift+Tab or cycling focus is present.</p>
<p>This demonstrates a <strong>partial focus management</strong>, but it’s not fully accessible yet.</p>
<p>To improve focus management, you can trap focus within the modal by ensuring that Tab and Shift+Tab cycle only through elements inside the modal.</p>
<p>You can also return focus to the trigger: when the modal closes, return focus to the element that opened it.</p>
<p><strong>Example improvement (conceptual):</strong></p>
<pre><code class="language-javascript">function Modal({ isOpen, onClose, triggerRef }) {
  const modalRef = React.useRef();

  React.useEffect(() =&gt; {
    if (isOpen) {
      modalref.current?.focus();
      // Add focus trap logic here
    } else {
      triggerref.current?.focus();
    }
  }, [isOpen]);

  return (
    &lt;div role="dialog" ref={modalRef} tabIndex={-1}&gt;
      &lt;button type="button" onClick={onClose}&gt;Close&lt;/button&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p>Remember that this modal is not fully accessible without focus trapping. In production, use a library like <code>focus-trap-react</code>, <code>react-aria</code>, or Radix UI.</p>
<p><strong>Key points:</strong></p>
<ul>
<li><p><code>tabIndex={-1}</code> allows the div to receive programmatic focus</p>
</li>
<li><p>Focus trap ensures users cannot tab out unintentionally</p>
</li>
<li><p>Returning focus preserves context, so users can continue where they left off</p>
</li>
</ul>
<p><strong>Best practices:</strong></p>
<ul>
<li><p>Always move focus into modals</p>
</li>
<li><p>Return focus to the trigger element when closed</p>
</li>
<li><p>Ensure Tab cycles correctly</p>
</li>
</ul>
<p>As a general rule, always prefer native HTML elements for interactivity. Only implement custom keyboard handling when building advanced components that cannot be achieved with standard elements.</p>
<h2 id="heading-focus-management">Focus Management</h2>
<p>Focus management is the practice of controlling where keyboard focus goes when users interact with components such as modals, forms, or interactive widgets. Proper focus management ensures that:</p>
<ul>
<li><p>Users relying on keyboards or assistive technologies can navigate seamlessly</p>
</li>
<li><p>Focus does not get lost or trapped in unexpected places</p>
</li>
<li><p>Users maintain context when content updates dynamically</p>
</li>
</ul>
<p>The example below shows a common approach that only partially handles focus:</p>
<p><strong>Bad Example:</strong></p>
<pre><code class="language-javascript">// Bad Example: Automatically focusing input without context
const ref = React.useRef();
React.useEffect(() =&gt; {
  ref.current?.focus();
}, []);
&lt;input ref={ref} placeholder="Name" /&gt;
</code></pre>
<p>In the above code, the input receives focus as soon as the component mounts, but there’s no handling for returning focus when the user navigates away.</p>
<p>If this input is inside a modal or dynamic content, users may get lost or trapped. There aren't any focus indicators or context for assistive technologies.</p>
<p>This is a minimal solution that can cause confusion in real applications.</p>
<p><strong>Improved Example:</strong></p>
<pre><code class="language-javascript">// Improved Example: Managing focus in a modal context
function Modal({ isOpen, onClose, triggerRef }) {  
const dialogRef = React.useRef();

  React.useEffect(() =&gt; {
    if (isOpen) {
      dialogRef.current?.focus();
    } else if (triggerRef?.current) {
      triggerref.current?.focus();
    }
  }, [isOpen]);

  React.useEffect(() =&gt; {
    function handleKeyDown(e) {
      if (e.key === 'Escape') {
        onClose();
      }
    }

    if (isOpen) {
      document.addEventListener('keydown', handleKeyDown);
    }

    return () =&gt; {
      document.removeEventListener('keydown', handleKeyDown);
    };
  }, [isOpen, onClose]);

  if (!isOpen) return null;

  return (
    &lt;div
      role="dialog"
      aria-modal="true"
      aria-labelledby="modal-title"
      tabIndex={-1}
      ref={dialogRef}
    &gt;
      &lt;h2 id="modal-title"&gt;Modal Title&lt;/h2&gt;
      &lt;button type="button" onClick={onClose}&gt;Close&lt;/button&gt;
      &lt;input type="text" placeholder="Name" /&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p><strong>Explanation:</strong></p>
<ul>
<li><p><code>tabIndex={-1}</code> enables the dialog container to receive focus</p>
</li>
<li><p>Focus is moved to the modal when it opens, ensuring keyboard users start in the correct context</p>
</li>
<li><p>Focus is returned to the trigger element when the modal closes, preserving user flow</p>
</li>
<li><p><code>aria-labelledby</code> provides an accessible name for the dialog</p>
</li>
<li><p>Escape key handling allows users to close the modal without a mouse</p>
</li>
</ul>
<p>Note: For full accessibility, you should also implement focus trapping so users cannot tab outside the modal while it is open.</p>
<p>Tip: In production applications, use libraries like react-aria, focus-trap-react, or Radix UI to handle focus trapping and accessibility edge cases reliably.</p>
<p>Also, keep in mind here that the document-level keydown listener is global, which affects the entire page and can conflict with other components.</p>
<pre><code class="language-javascript">document.addEventListener('keydown', handleKeyDown);
</code></pre>
<p>A safer alternative is to scope it to the modal:</p>
<pre><code class="language-javascript">&lt;div
  onKeyDown={(e) =&gt; {
    if (e.key === 'Escape') onClose();
  }}
&gt;
</code></pre>
<p>For simple cases, attach <code>onKeyDown</code> to the dialog instead of the document.</p>
<h4 id="heading-best-practice">Best Practice:</h4>
<p>For complex components, use libraries like <code>focus-trap-react</code> or <code>react-aria</code> to manage focus reliably, especially for modals, dropdowns, and popovers.</p>
<h2 id="heading-forms-and-accessibility">Forms and Accessibility</h2>
<p>Forms are critical points of interaction in web applications, and proper accessibility ensures that all users – including those using screen readers or other assistive technologies – can understand and interact with them effectively.</p>
<p>Proper labeling means that every input field, checkbox, radio button, or select element has an associated label that clearly describes its purpose. This allows screen readers to announce the input meaningfully and helps keyboard-only users understand what information is expected.</p>
<p>In addition to labeling, form accessibility includes:</p>
<ul>
<li><p>Providing clear error messages when input is invalid</p>
</li>
<li><p>Ensuring error messages are announced to assistive technologies</p>
</li>
<li><p>Maintaining logical focus order so users can navigate inputs easily</p>
</li>
</ul>
<p><strong>Bad Example:</strong></p>
<pre><code class="language-html">&lt;input type="text" placeholder="Name" /&gt;
</code></pre>
<p>Why this isn't good:</p>
<ul>
<li><p>This input relies only on a placeholder for context</p>
</li>
<li><p>Screen readers may not announce the purpose of the field clearly</p>
</li>
<li><p>Once a user starts typing, the placeholder disappears, leaving no guidance</p>
</li>
<li><p>Keyboard-only users may not have enough context to know what to enter</p>
</li>
</ul>
<p><strong>Good Example:</strong></p>
<pre><code class="language-html">&lt;label htmlFor="name"&gt;Name&lt;/label&gt;
&lt;input id="name" type="text" /&gt;
</code></pre>
<p>Why this is better:</p>
<ul>
<li><p>The <code>&lt;label&gt;</code> is explicitly associated with the input via <code>htmlFor / id</code></p>
</li>
<li><p>Screen readers announce "Name" before the input, providing clear context</p>
</li>
<li><p>Users navigating with Tab understand the field’s purpose</p>
</li>
<li><p>The label persists even when the user types, unlike a placeholder</p>
</li>
</ul>
<p><strong>Error Handling:</strong></p>
<pre><code class="language-html">&lt;label htmlFor="name"&gt;Name&lt;/label&gt;
&lt;input
  id="name"
  type="text"
  aria-describedby="name-error"
  aria-invalid="true"
/&gt;

&lt;p id="name-error" role="alert"&gt;
  Name is required
&lt;/p&gt;
</code></pre>
<p><strong>Explanation</strong></p>
<ul>
<li><p><code>aria-describedby</code> links the input to the error message using the element’s id</p>
</li>
<li><p>Screen readers announce the error message when the input is focused</p>
</li>
<li><p><code>aria-invalid="true"</code> indicates that the field currently contains an error</p>
</li>
<li><p><code>role="alert"</code> ensures the error message is announced immediately when it appears</p>
</li>
</ul>
<p>This creates a clear relationship between the input and its validation message, improving usability for screen reader users.</p>
<p>Tip: Only apply aria-invalid and error messages when validation fails. Avoid marking fields as invalid before user interaction.</p>
<h2 id="heading-responsive-typography-and-images">Responsive Typography and Images</h2>
<p>Responsive typography and images ensure that your content remains readable and visually appealing across a wide range of devices, from small smartphones to large desktop monitors.</p>
<p>This is important, because text should scale naturally so it remains legible on all screens, and images should adjust to container sizes to avoid layout issues or overflow. Both contribute to a better user experience and accessibility</p>
<p>In this section, we’ll cover practical ways to implement responsive typography and images in React and CSS.</p>
<pre><code class="language-css">h1 {
  font-size: clamp(1.5rem, 2vw, 3rem);
}
</code></pre>
<p>In this code:</p>
<ul>
<li><p>The <code>clamp()</code> function allows text to scale fluidly:</p>
</li>
<li><p>The first value (1.5rem) is the “minimum font size”</p>
</li>
<li><p>The second value (2vw) is the “preferred size based on viewport width”</p>
</li>
<li><p>The third value (3rem) is the “maximum font size”</p>
</li>
<li><p>This ensures headings are “readable on small screens” without becoming too large on desktops</p>
</li>
</ul>
<p>Alternative methods include using <code>media queries</code> to adjust font sizes at different breakpoints</p>
<p><strong>Responsive Images:</strong></p>
<pre><code class="language-html">&lt;img src="image.jpg" alt="Description" loading="lazy" /&gt;
</code></pre>
<p>In this code, responsive images adapt to different screen sizes and resolutions to prevent layout issues or slow loading times. Key techniques include:</p>
<h3 id="heading-1-fluid-images-using-css">1. Fluid images using CSS:</h3>
<pre><code class="language-css">img {
     max-width: 100%;
     height: auto;
   }
</code></pre>
<p>This makes sure that images never overflow their container and maintains aspect ratio automatically.</p>
<h3 id="heading-2-using-srcset-for-multiple-resolutions">2. Using <code>srcset</code> for multiple resolutions:</h3>
<pre><code class="language-html">&lt;img src="image-small.jpg"
     srcset="image-small.jpg 480w,
             image-medium.jpg 1024w,
             image-large.jpg 1920w"
     sizes="(max-width: 600px) 480px,
            (max-width: 1200px) 1024px,
            1920px"
     alt="Description"&gt;
</code></pre>
<p>This provides different image files depending on screen size or resolution and reduces loading times and improves performance on smaller devices.</p>
<h3 id="heading-3-always-include-descriptive-alt-text">3. Always include descriptive alt text</h3>
<p>This is critical for screen readers and accessibility. It also helps users understand the image if it cannot be loaded.</p>
<p>Tip: Combine responsive typography, images, and flexible layout containers (like CSS Grid or Flexbox) to create interfaces that scale gracefully across all devices and maintain accessibility.</p>
<h3 id="heading-4-ensure-sufficient-color-contrast">4. Ensure Sufficient Color Contrast</h3>
<p>Low contrast text can make content unreadable for many users.</p>
<pre><code class="language-css">.bad-text {
  color: #aaa;
}

.good-text {
  color: #222;
}
</code></pre>
<p>Use tools like WebAIM Contrast Checker and Chrome DevTools Accessibility panel to check your color contrasts. Also note that WCAG AA requires 4.5:1 contrast ratio for normal text.</p>
<h2 id="heading-building-a-fully-accessible-responsive-component-end-to-end-example">Building a Fully Accessible Responsive Component (End-to-End Example)</h2>
<p>To understand how responsiveness and accessibility work together in practice, let’s build a reusable accessible card component that adapts to screen size and supports keyboard and screen reader users.</p>
<h3 id="heading-step-1-component-structure-semantic-html">Step 1: Component Structure (Semantic HTML)</h3>
<pre><code class="language-javascript">function ProductCard({ title, description, onAction }) {
  return (
    &lt;article className="card"&gt;
      &lt;h3&gt;{title}&lt;/h3&gt;
      &lt;p&gt;{description}&lt;/p&gt;
      &lt;button type="button" onClick={onAction}&gt;
        View Details
      &lt;/button&gt;
    &lt;/article&gt;
  );
}
</code></pre>
<p><strong>Why This Works</strong></p>
<ul>
<li><p><code>&lt;article&gt;</code> provides semantic meaning for standalone content</p>
</li>
<li><p><code>&lt;h3&gt;</code> establishes a proper heading hierarchy</p>
</li>
<li><p><code>&lt;button&gt;</code> ensures built-in keyboard and accessibility support</p>
</li>
</ul>
<h3 id="heading-step-2-responsive-styling">Step 2: Responsive Styling</h3>
<pre><code class="language-css">.card {
  padding: 16px;
  border: 1px solid #ddd;
  border-radius: 8px;
}

@media (min-width: 768px) {
  .card {
    padding: 24px;
  }
}
</code></pre>
<p>This ensures comfortable spacing on mobile and improved readability on larger screens.</p>
<h3 id="heading-step-3-accessibility-enhancements">Step 3: Accessibility Enhancements</h3>
<pre><code class="language-html">&lt;button type="button" onClick={onAction}&gt;
  View Details
&lt;/button&gt;
</code></pre>
<p>The visible button text provides a clear and accessible label, so no additional ARIA attributes are needed.</p>
<h3 id="heading-step-4-keyboard-focus-styling">Step 4: Keyboard Focus Styling</h3>
<pre><code class="language-css">button:focus {
  outline: 2px solid blue;
  outline-offset: 2px;
}
</code></pre>
<p>Focus indicators are essential for keyboard users.</p>
<h3 id="heading-step-5-using-the-component">Step 5: Using the Component</h3>
<pre><code class="language-javascript">function App() {
  return (
    &lt;div className="grid"&gt;
      &lt;ProductCard
        title="Product 1"
        description="Accessible and responsive"
        onAction={() =&gt; alert('Clicked')}
      /&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p><strong>Key Takeaways</strong></p>
<p>This simple component demonstrates:</p>
<ul>
<li><p>Semantic HTML structure</p>
</li>
<li><p>Responsive design</p>
</li>
<li><p>Built-in accessibility via native elements</p>
</li>
<li><p>Minimal ARIA usage</p>
</li>
</ul>
<p>In real-world applications, this pattern scales into entire design systems.</p>
<h2 id="heading-testing-accessibility">Testing Accessibility</h2>
<p>Accessibility should be validated continuously, not just at the end of development. There are various automated tools you can use to help you with this process:</p>
<ul>
<li><p>Lighthouse (built into Chrome DevTools)</p>
</li>
<li><p>axe DevTools for detailed audits</p>
</li>
<li><p>ESLint plugins for accessibility rules</p>
</li>
</ul>
<h3 id="heading-manual-testing">Manual Testing</h3>
<p>But automated tools cannot catch everything. Manual testing is essential to make sure users can navigate using only the keyboard and use a screen reader (NVDA or VoiceOver. You should also test zoom levels (up to 200%) and check the color contrast manually.</p>
<p><strong>Example: ESLint Accessibility Plugin</strong></p>
<pre><code class="language-shell">npm install eslint-plugin-jsx-a11y --save-dev
</code></pre>
<p>This helps catch accessibility issues during development.</p>
<h2 id="heading-best-practices">Best Practices</h2>
<ul>
<li><p>Use semantic HTML first</p>
</li>
<li><p>Avoid unnecessary ARIA</p>
</li>
<li><p>Test keyboard navigation</p>
</li>
<li><p>Design mobile-first</p>
</li>
<li><p>Ensure color contrast</p>
</li>
<li><p>Use consistent spacing</p>
</li>
</ul>
<h2 id="heading-when-not-to-overuse-accessibility-features">When NOT to Overuse Accessibility Features</h2>
<ul>
<li><p>Avoid adding ARIA when native HTML works</p>
</li>
<li><p>Do not override browser defaults unnecessarily</p>
</li>
<li><p>Avoid complex custom components without accessibility support</p>
</li>
</ul>
<h2 id="heading-future-enhancements">Future Enhancements</h2>
<ul>
<li><p>Design systems with accessibility built-in</p>
</li>
<li><p>Automated accessibility testing in CI/CD</p>
</li>
<li><p>Advanced focus management libraries</p>
</li>
<li><p>Accessibility-first component libraries</p>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Building responsive and accessible React applications is not a one-time effort—it is a continuous design and engineering practice. Instead of treating accessibility as a checklist, developers should integrate it into the core of their component design process.</p>
<p>If you are starting out, focus on using semantic HTML and mobile-first layouts. These two practices alone solve a large percentage of accessibility and responsiveness issues. As your application grows, introduce ARIA enhancements, keyboard navigation, and automated accessibility testing.</p>
<p>The key is to build interfaces that work for everyone by default. When responsiveness and accessibility are treated as first-class concerns, your React applications become more usable, scalable, and future-proof.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use HTML Attributes to Make Your Websites and Apps More Accessible ]]>
                </title>
                <description>
                    <![CDATA[ Have you ever used an attribute in HTML without fully understanding its purpose? You're not alone! Over time, I've dug into the meaning behind many HTML attributes, especially those that are crucial for accessibility. In this in-depth tutorial, I'll ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-html-attributes-to-make-your-websites-and-apps-more-accessible/</link>
                <guid isPermaLink="false">66db603bf7f8b7688af503af</guid>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ a11y ]]>
                    </category>
                
                    <category>
                        <![CDATA[ aria ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Accessibility ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Elizabeth Lola ]]>
                </dc:creator>
                <pubDate>Fri, 06 Sep 2024 20:04:11 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1725281991044/7edb0d70-c31e-4a41-bc24-232c75d0fae3.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Have you ever used an attribute in HTML without fully understanding its purpose? You're not alone! Over time, I've dug into the meaning behind many HTML attributes, especially those that are crucial for accessibility.</p>
<p>In this in-depth tutorial, I'll break down some key HTML attributes that enhance accessibility, explaining what they do, and when to use them effectively.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>To follow along with this tutorial, you should have a basic understanding of HTML and a little bit of Javascript knowledge as well.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-what-are-aria-attributes">What are ARIA Attributes?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-alt-attribute">The <code>alt</code> Attribute</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-aria-label-attribute">The <code>aria-label</code> Attribute</a></p>
<ul>
<li><a class="post-section-overview" href="#heading-best-practices-for-using-aria-label">Best practices for Using <code>aria-label</code></a></li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-the-aria-labelledby-attribute">The <code>aria-labelledby</code> Attribute</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-how-is-aria-label-different-from-aria-labelledby">How is <code>aria-label</code> Different from <code>aria-labelledby</code>?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-best-practices-for-using-aria-labelledby">Best Practices for Using <code>aria-labelledby</code></a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-the-aria-describedby-attribute">The <code>aria-describedby</code> Attribute</a></p>
<ul>
<li><a class="post-section-overview" href="#heading-best-practices-for-using-aria-describedby">Best Pracices for Using <code>aria-describedby</code></a></li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-the-role-attribute">The <code>role</code> Attribute</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-common-role-values">Common <code>role</code> Values</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-best-practices-for-using-the-role-attribute">Best Practices for Using the <code>role</code> Attribute</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-the-aria-controls-attribute">The <code>aria-controls</code> Attribute</a></p>
<ul>
<li><a class="post-section-overview" href="#heading-best-practices-for-using-aria-controls">Best Practices for Using <code>aria-controls</code></a></li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-the-aria-selected-attribute">The <code>aria-selected</code> Attribute</a></p>
<ul>
<li><a class="post-section-overview" href="#heading-best-practices-for-using-aria-selected">Best Practices for Using <code>aria-selected</code></a></li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-the-tabindex-attribute">The <code>tabindex</code> Attribute</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-possible-tabindex-values">Possible <code>tabindex</code> Values</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-best-practices-for-using-tabindex">Best Practices for Using <code>tabindex</code></a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-the-title-attribute">The <code>title</code> Attribute</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-accessibility-concerns-with-the-title-attribute">Accessibility Concerns with <code>title</code></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-best-practices-for-using-the-title-attribute">Best Practices for Using the <code>title</code> Attribute</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-using-the-for-attribute-in-label">Using the <code>for</code> Attribute in <code>label</code></a></p>
<ul>
<li><a class="post-section-overview" href="#heading-best-practices-for-using-the-for-attribute">Best Practices for Using the <code>for</code> Attribute</a></li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-the-scope-attribute">The <code>scope</code> Attribute</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-possible-scope-values">Possible <code>scope</code> Values</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-best-practices-for-using-the-scope-attribute">Best Practices for Using <code>scope</code></a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-the-aria-hidden-attribute">The <code>aria-hidden</code> Attribute</a></p>
<ul>
<li><a class="post-section-overview" href="#heading-best-practices-for-using-aria-hidden">Best Practices for Using <code>aria-hidden</code></a></li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-the-inert-attribute">The <code>inert</code> Attribute</a></p>
<ul>
<li><a class="post-section-overview" href="#heading-best-practices-for-using-the-inert-attribute">Best Practices for Using <code>inert</code></a></li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-the-aria-live-attribute">The <code>aria-live</code> Attribute</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-possible-values-for-aria-live">Possible Values for <code>aria-live</code></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-best-practices-for-using-aria-live">Best Practices for Using <code>aria-live</code></a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-the-aria-roledescription-attribute">The <code>aria-roledescription</code> Attribute</a></p>
<ul>
<li><a class="post-section-overview" href="#heading-best-practices-for-using-aria-roledescription">Best Practices for Using <code>aria-roledescription</code></a></li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-the-aria-atomic-attribute">The <code>aria-atomic</code> Attribute</a></p>
<ul>
<li><a class="post-section-overview" href="#heading-the-aria-atomic-attribute">Best Practices for Using <code>aria-atomic</code></a></li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ol>
<h2 id="heading-what-are-aria-attributes">What Are ARIA Attributes?</h2>
<p>Most of the attributes listed in this article are ARIA attributes. ARIA, which stands for <strong>Accessible Rich Internet Applications</strong>, is a set of attributes defined by the W3C (World Wide Web Consortium) to enhance the accessibility of web applications.</p>
<p>ARIA attributes provide additional information to assistive technologies like screen readers. Using them correctly can make complex web applications more accessible to individuals with visual, auditory, or motor impairments.</p>
<p>One key principle of using ARIA is that sometimes it's best not to use it. Although this might seem contradictory, you should only ARIA attributes when necessary. Overusing ARIA can disrupt the experience for users relying on assistive technologies. While sighted users might not notice any issues, excessive or improper use of ARIA can negatively impact accessibility.</p>
<h2 id="heading-the-alt-attribute">The <code>alt</code> Attribute</h2>
<p>The <code>alt</code> attribute likely isn't new to you if you've used HTML images. You use it to provide <em>alternative</em> text that displays when an image isn't properly shown on the screen.</p>
<p>But the most important use of the <code>alt</code> attribute is for accessibility. If the <code>alt</code> attribute is not present in an image element, then a screen reader may announce the name of the image file or the URL of the image instead of explaining what it's showing. This can be unhelpful and we don't want that.</p>
<p>The content in the <code>alt</code> attribute should be concise because its primary purpose is to briefly describe an image for those who cannot see it. This includes users who rely on screen readers, search engines, and users with slow internet connections where images may not load. If the <code>alt</code> text is too long, it may include unnecessary details that don't add value to the user's understanding.</p>
<p>The <code>alt</code> attribute is different from an image caption. Captions are visible and can provide more context or additional information about an image. Using a caption as <code>alt</code> text can make it too long and redundant.</p>
<p>If the image is purely decorative, then the alt attribute should be left empty. If an image has an empty alt attribute, an assistive tool will skip it. This is important to help keep users focused on the content and not distract them with unnecessary information.</p>
<p>Here's an example of how you can use the alt attribute:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Lions are remarkable for their powerful roars, 
which can be heard up to five miles away. 
These roars are used to communicate with other 
members of the pride, as well as to ward off rival lions and intruders. 
Although lions are often associated with the African savannah, 
a small population of Asiatic lions still exists in India's Gir Forest, 
making them one of the world's most endangered big cats.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"lion.jpg"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"a lion"</span> /&gt;</span> <span class="hljs-comment">&lt;!-- brief and gives context to the paragraph --&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"background-stars.png"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">""</span> /&gt;</span> <span class="hljs-comment">&lt;!-- This image is purely for 
decoration so it's left empty --&gt;</span>
</code></pre>
<h2 id="heading-the-aria-label-attribute">The <code>aria-label</code> Attribute</h2>
<p>The <code>aria-label</code> attribute is used to provide an accessible name to an element that might not have visible text. A common example of this is a button that contains an image or SVG.</p>
<p>A lot of elements have an accessible name – the accessible name is the content inside the element. The accessible name for the heading in this example is "Frequently Asked Questions"</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Frequently Asked Questions<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
</code></pre>
<p>Everyone, including people using assistive technology, would clearly understand the meaning of the example above because it contains visible content.</p>
<p>But in the example below, a user relying on a screen reader might miss the content in the button if it doesn't have an <code>aria-label</code>. This is because the content in the button is an SVG and the SVG does not contain any visible content:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"Search"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">svg</span>
      <span class="hljs-attr">fill</span>=<span class="hljs-string">"#000000"</span> 
      <span class="hljs-attr">height</span>=<span class="hljs-string">"20px"</span>
      <span class="hljs-attr">width</span>=<span class="hljs-string">"20px"</span>
      <span class="hljs-attr">xmlns</span>=<span class="hljs-string">"http://www.w3.org/2000/svg"</span> 
      <span class="hljs-attr">viewBox</span>=<span class="hljs-string">"0 0 488.4 488.4"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">g</span> <span class="hljs-attr">stroke-width</span>=<span class="hljs-string">"0"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">g</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">g</span> <span class="hljs-attr">stroke-linecap</span>=<span class="hljs-string">"round"</span> <span class="hljs-attr">stroke-linejoin</span>=<span class="hljs-string">"round"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">g</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">g</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">g</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">g</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">path</span> <span class="hljs-attr">d</span>=<span class="hljs-string">"M0,203.25c0,112.1,91.2,203.2,203.2,203.2c51.6,0,98.8-19.4,134.7-51.2l129.5,129.5c2.4,2.4,5.5,3.6,8.7,3.6 s6.3-1.2,8.7-3.6c4.8-4.8,4.8-12.5,0-17.3l-129.6-129.5c31.8-35.9,51.2-83,51.2-134.7c0-112.1-91.2-203.2-203.2-203.2 S0,91.15,0,203.25z M381.9,203.25c0,98.5-80.2,178.7-178.7,178.7s-178.7-80.2-178.7-178.7s80.2-178.7,178.7-178.7 S381.9,104.65,381.9,203.25z"</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">g</span>&gt;</span> 
        <span class="hljs-tag">&lt;/<span class="hljs-name">g</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">g</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">svg</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p>Do not overuse the <code>aria-label</code>. Not all content needs an <code>aria-label</code> – for example, if you have a button that contains an image with <code>alt</code>, or an SVG with a <code>title</code>, then those attributes act as the accessible name for that element.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"search-icon.png"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Search"</span> /&gt;</span> <span class="hljs-comment">&lt;!-- no need for aria-label --&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

<span class="hljs-comment">&lt;!-- Another example --&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">svg</span>
    <span class="hljs-attr">fill</span>=<span class="hljs-string">"#000000"</span>
    <span class="hljs-attr">height</span>=<span class="hljs-string">"20px"</span>
    <span class="hljs-attr">width</span>=<span class="hljs-string">"20px"</span>
    <span class="hljs-attr">role</span>=<span class="hljs-string">"image"</span>
    <span class="hljs-attr">xmlns</span>=<span class="hljs-string">"http://www.w3.org/2000/svg"</span>
    <span class="hljs-attr">viewBox</span>=<span class="hljs-string">"0 0 488.4 488.4"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Search Icon<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span> <span class="hljs-comment">&lt;!-- Accessible name --&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">g</span> <span class="hljs-attr">stroke-width</span>=<span class="hljs-string">"0"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">g</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">g</span> <span class="hljs-attr">stroke-linecap</span>=<span class="hljs-string">"round"</span> <span class="hljs-attr">stroke-linejoin</span>=<span class="hljs-string">"round"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">g</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">g</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">g</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">g</span>&gt;</span>
         <span class="hljs-tag">&lt;<span class="hljs-name">path</span> <span class="hljs-attr">d</span>=<span class="hljs-string">"M0,203.25c0,112.1,91.2,203.2,203.2,203.2c51.6,0,98.8-19.4,134.7-51.2l129.5,129.5c2.4,2.4,5.5,3.6,8.7,3.6 s6.3-1.2,8.7-3.6c4.8-4.8,4.8-12.5,0-17.3l-129.6-129.5c31.8-35.9,51.2-83,51.2-134.7c0-112.1-91.2-203.2-203.2-203.2 S0,91.15,0,203.25z M381.9,203.25c0,98.5-80.2,178.7-178.7,178.7s-178.7-80.2-178.7-178.7s80.2-178.7,178.7-178.7 S381.9,104.65,381.9,203.25z"</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">g</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">g</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">g</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">svg</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p>You should use the <code>aria-label</code> sparingly and appropriately. Overusing the attribute can lead to several issues:</p>
<ul>
<li><p>The <code>aria-label</code> content is not visible to sighted users. If a user with a cognitive disability is using a screen reader for support, they might not understand why they’re hearing different information from what they see on the screen.</p>
</li>
<li><p>Using <code>aria-label</code> extensively across a large codebase can make the HTML harder to maintain. You may struggle to track where labels are coming from, especially if they’re set programmatically or in multiple places.</p>
</li>
</ul>
<h3 id="heading-best-practices-for-using-aria-label">Best Practices for Using <code>aria-label</code></h3>
<ul>
<li><p>Whenever possible, use visible text labels. They’re easier to understand and maintain, and they ensure consistent experiences for all users.</p>
</li>
<li><p>When Possible: If there is already a visible label on the page, use <code>aria-labelledby</code> to link the element to the existing text instead of creating a new label with <code>aria-label</code> (we'll talk about this below).</p>
</li>
<li><p>If you use <code>aria-label</code>, keep the text short and to the point. It should describe the element’s purpose in as few words as possible.</p>
</li>
</ul>
<h2 id="heading-the-aria-labelledby-attribute">The <code>aria-labelledby</code> Attribute</h2>
<p>The <code>aria-labelledby</code> attribute is used to associate an element with another element that serves as its label. It links the target element to one or more other elements on the page that contain the text that should be used as the label.</p>
<p>You can use this attribute when there is already a visible text label or when the label needs to be composed of multiple text elements.</p>
<p>For example, you can use <code>aria-labelledby</code> in a <code>&lt;section&gt;</code> element to associate it with a heading or other text that serves as a label for the entire section.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"about-heading"</span>&gt;</span>About Us<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span> 
<span class="hljs-tag">&lt;<span class="hljs-name">section</span> <span class="hljs-attr">aria-labelledby</span>=<span class="hljs-string">"about-heading"</span>&gt;</span> <span class="hljs-comment">&lt;!-- use the id of the h2 --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>We are a company dedicated to providing excellent service...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"services-heading"</span>&gt;</span>Our Services<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">section</span> <span class="hljs-attr">aria-labelledby</span>=<span class="hljs-string">"services-heading"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>We offer a wide range of services including...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>
</code></pre>
<p>Sometimes, you might want to combine multiple pieces of text as the label. You can do this by listing multiple IDs in the <code>aria-labelledby</code> attribute:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"dialog-title"</span>&gt;</span>Confirmation Required<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"dialog-description"</span>&gt;</span>Are you sure you want to delete this item?<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">aria-labelledby</span>=<span class="hljs-string">"dialog-title dialog-description"</span>&gt;</span>Yes<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p>The <code>aria-labelledby</code> is similar to the <code>aria-label</code> in that its purpose is to provide an accessible element.</p>
<h3 id="heading-how-is-aria-label-different-from-aria-labelledby">How is <code>aria-label</code> Different from <code>aria-labelledby</code>?</h3>
<p><code>aria-label</code> directly assigns a string of text as a label for an element. This text is not visible on the screen but is announced by assistive technologies like screen readers. It’s typically used when there is no visible text label.</p>
<p><code>aria-labelledby</code> points to one or more existing elements on the page (using their <code>id</code> attributes) that should be used as the label for the element. The label text is visible to all users because it’s part of the content of another element.</p>
<h3 id="heading-best-practices-for-using-aria-labelledby">Best Practices for Using <code>aria-labelledby</code></h3>
<ul>
<li><p>Use <code>aria-labelledby</code> over <code>aria-label</code> when there is already text on the page that can serve as the label. This reduces redundancy and ensures that both sighted users and screen reader users see the same content.</p>
</li>
<li><p>The <code>id</code> attributes referenced by <code>aria-labelledby</code> must be unique on the page and correctly point to existing elements. If the ID is missing or incorrect, the label won’t work, leading to accessibility issues.</p>
</li>
<li><p>When combining multiple labels, ensure that the resulting label makes sense when read together. The order of IDs in <code>aria-labelledby</code> matters, as screen readers will read the labels in the order they are listed.</p>
</li>
<li><p>Like <code>aria-label</code>, avoid overusing <code>aria-labelledby</code> in situations where a simpler approach (like using a visible <code>label</code> element directly) would suffice. This helps keep the code maintainable and reduces the cognitive load for users.</p>
</li>
</ul>
<h2 id="heading-the-aria-describedby-attribute">The <code>aria-describedby</code> Attribute</h2>
<p>The <code>aria-describedby</code> attribute is used to associate an element with one or more elements that provide additional descriptive information about it. The <code>aria-describedby</code> attribute is used to provide additional context or instructions to an element.</p>
<p>Unlike <code>aria-labelledby</code>, which is meant to provide a label or name, <code>aria-describedby</code> is intended to give users more detailed information or context about an element, often to supplement what they already know from the label.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"full-name"</span>&gt;</span>Full name<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">aria-labelledby</span>=<span class="hljs-string">"full-name"</span> <span class="hljs-attr">aria-describedby</span>=<span class="hljs-string">"info"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"info"</span>&gt;</span>Enter your full name.<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
</code></pre>
<p>When both <code>aria-labelledby</code> and <code>aria-describedby</code> are used on the same element, screen readers will first announce the label (from <code>aria-labelledby</code>), then the role of the element (for example, "button"), and finally the description (from <code>aria-describedby</code>).</p>
<h3 id="heading-best-practices-for-using-aria-describedby">Best Practices for Using <code>aria-describedby</code></h3>
<ul>
<li><p>Apply <code>aria-describedby</code> when you need to provide users with additional context or instructions that go beyond the label. This is particularly useful for forms, complex controls, or any element that might require clarification.</p>
</li>
<li><p>While <code>aria-describedby</code> is meant for more detailed descriptions, avoid overly long text. Keep the description focused on what the user needs to know to interact with the element effectively.</p>
</li>
<li><p>Just like with <code>aria-labelledby</code>, ensure that the elements referenced by <code>aria-describedby</code> have unique and relevant <code>id</code> attributes. The content of these elements should be directly relevant to the element they describe.</p>
</li>
</ul>
<h2 id="heading-the-role-attribute">The <code>role</code> Attribute</h2>
<p>The role attribute is used to specify the role of an element. You can use it to override the default role of a semantic element. It helps assistive technologies understand how an element should be interpreted or interacted with.</p>
<p>When using non-semantic elements (like <code>&lt;div&gt;</code> or <code>&lt;span&gt;</code>) to create interactive controls (buttons, dialogs, tabs, and so on), the <code>role</code> attribute informs assistive technologies of the element’s intended behavior. You can also use the role to define landmark roles that assist in navigation, such as <code>banner</code> or <code>complementary</code>, which defines the structure of the page for screen reader users.</p>
<h3 id="heading-common-role-values">Common <code>role</code> Values</h3>
<p>Roles for Landmark Regions:</p>
<ul>
<li><p><code>banner</code>: Represents the site header.</p>
</li>
<li><p><code>navigation</code>: Defines a navigation section of the page, often for site or page navigation links.</p>
</li>
<li><p><code>main</code>: Marks the main content of a document, distinct from sidebars, footers, and so on.</p>
</li>
<li><p><code>contentinfo</code>: Represents the footer information.</p>
</li>
</ul>
<p>This example below is just for demonstration purposes – you should use the right semantic element when possible:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"banner"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>My Website<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"navigation"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#home"</span>&gt;</span>Home<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#about"</span>&gt;</span>About<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"main"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Welcome to My Website<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Here is some main content...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"contentinfo"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span><span class="hljs-symbol">&amp;copy;</span> 2024 My Website<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Roles for Widgets and Interactive Elements:</p>
<ul>
<li><p><code>button</code>: Represents a button element, which users can click to trigger an action.</p>
</li>
<li><p><code>dialog</code>: Marks a dialog box or modal that requires user interaction.</p>
</li>
<li><p><code>alert</code>: Identifies an element as an important message or alert that requires user attention.</p>
</li>
<li><p><code>tablist</code>, <code>tab</code>, <code>tabpanel</code>: Used for tabbed interfaces, where <code>tablist</code> contains the tabs, and each <code>tab</code> controls the visibility of its corresponding <code>tabpanel</code>.</p>
</li>
</ul>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">tabindex</span>=<span class="hljs-string">"0"</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"submitForm()"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"dialog"</span> <span class="hljs-attr">aria-labelledby</span>=<span class="hljs-string">"dialog-title"</span> <span class="hljs-attr">aria-modal</span>=<span class="hljs-string">"true"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"dialog-title"</span>&gt;</span>Confirmation<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Are you sure you want to proceed?<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"closeDialog()"</span>&gt;</span>Close<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Example of Tabbed panel:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"tablist"</span> <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"Sample Tabs"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"tab"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"tab-1"</span> <span class="hljs-attr">aria-controls</span>=<span class="hljs-string">"panel-1"</span> <span class="hljs-attr">aria-selected</span>=<span class="hljs-string">"true"</span> <span class="hljs-attr">tabindex</span>=<span class="hljs-string">"0"</span>&gt;</span>Tab 1<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"tab"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"tab-2"</span> <span class="hljs-attr">aria-controls</span>=<span class="hljs-string">"panel-2"</span> <span class="hljs-attr">aria-selected</span>=<span class="hljs-string">"false"</span> <span class="hljs-attr">tabindex</span>=<span class="hljs-string">"-1"</span>&gt;</span>Tab 2<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"tab"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"tab-3"</span> <span class="hljs-attr">aria-controls</span>=<span class="hljs-string">"panel-3"</span> <span class="hljs-attr">aria-selected</span>=<span class="hljs-string">"false"</span> <span class="hljs-attr">tabindex</span>=<span class="hljs-string">"-1"</span>&gt;</span>Tab 3<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"tabpanel"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"panel-1"</span> <span class="hljs-attr">aria-labelledby</span>=<span class="hljs-string">"tab-1"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Content for Tab 1<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>This is the content of the first tab.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"tabpanel"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"panel-2"</span> <span class="hljs-attr">aria-labelledby</span>=<span class="hljs-string">"tab-2"</span> <span class="hljs-attr">hidden</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Content for Tab 2<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>This is the content of the second tab.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"tabpanel"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"panel-3"</span> <span class="hljs-attr">aria-labelledby</span>=<span class="hljs-string">"tab-3"</span> <span class="hljs-attr">hidden</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Content for Tab 3<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>This is the content of the third tab.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<h3 id="heading-best-practices-for-using-the-role-attribute">Best Practices for Using the <code>role</code> Attribute</h3>
<ul>
<li><p>Always prefer using native HTML elements that already have the appropriate role (for example, <code>&lt;button&gt;</code>, <code>&lt;header&gt;</code>, <code>&lt;nav&gt;</code>, <code>&lt;main&gt;</code>). This provides better accessibility support across a wider range of browsers and devices.</p>
</li>
<li><p>Don't <strong>overuse</strong> or <strong>misuse</strong> the <code>role</code> attribute as this can lead to confusion and reduced accessibility. Use <code>role</code> to enhance or clarify when needed, not to replace semantic HTML.</p>
</li>
<li><p>Understand implicit roles. Many HTML elements have implicit roles. For example, an <code>&lt;a&gt;</code> element with an <code>href</code> attribute automatically has the <code>link</code> role. Avoid adding redundant <code>role</code> attributes to these elements.</p>
</li>
</ul>
<h2 id="heading-the-aria-controls-attribute">The <code>aria-controls</code> Attribute</h2>
<p>The <code>aria-controls</code> attribute informs a screen reader that the element is controlled or affected by another element. It's commonly used to indicate that a component (like a button or a tab) controls or interacts with another part of the page (like a panel or a menu). It is also used in interactive components such as tabs, accordions, and sliders to describe which parts of the page are affected when the user interacts with the component.</p>
<p>For example, you can use <code>aria-controls</code> on a tab button to indicate which panel each button controls:</p>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!-- Tab Buttons --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"tab1"</span> <span class="hljs-attr">aria-controls</span>=<span class="hljs-string">"panel1"</span>&gt;</span>Tab 1<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"tab2"</span> <span class="hljs-attr">aria-controls</span>=<span class="hljs-string">"panel2"</span>&gt;</span>Tab 2<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

<span class="hljs-comment">&lt;!-- Content Panels --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"panel1"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"tabpanel"</span>&gt;</span>Content for Tab 1<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"panel2"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"tabpanel"</span>&gt;</span>Content for Tab 2<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<h3 id="heading-best-practices-for-using-aria-controls">Best Practices for Using <code>aria-controls</code></h3>
<ul>
<li><p>Ensure that the ID used in <code>aria-controls</code> matches the <code>id</code> of the controlled element exactly.</p>
</li>
<li><p>Use <code>aria-controls</code> in conjunction with role and state attributes like <code>aria-selected</code>, or <code>role="tabpanel"</code> to provide more complete information about the controlled elements and their states.</p>
</li>
<li><p>Apply <code>aria-controls</code> to interactive elements such as buttons or links that have a direct effect on other elements. It is not typically used for non-interactive content.</p>
</li>
</ul>
<h2 id="heading-the-aria-selected-attribute">The <code>aria-selected</code> Attribute</h2>
<p>The <code>aria-selected</code> attribute is used to indicate the current selection state of an element within a group of selectable items. A selectable item could be an option in a menu, a tab in a tabbed panel, or an item in a list box.</p>
<p>Here's an example of the selection state in a list box. <code>aria-selected="true"</code> in option 1 indicates that Option 1 is currently selected.</p>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!-- Listbox --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"listbox"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"option"</span> <span class="hljs-attr">aria-selected</span>=<span class="hljs-string">"true"</span>&gt;</span>Option 1<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"option"</span> <span class="hljs-attr">aria-selected</span>=<span class="hljs-string">"false"</span>&gt;</span>Option 2<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"option"</span> <span class="hljs-attr">aria-selected</span>=<span class="hljs-string">"false"</span>&gt;</span>Option 3<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
</code></pre>
<h3 id="heading-best-practices-for-using-aria-selected">Best Practices for Using <code>aria-selected</code></h3>
<ul>
<li><p>Use <code>aria-selected="true"</code> for the selected item and <code>aria-selected="false"</code> for non-selected items. The value should be a string, not a boolean.</p>
</li>
<li><p>Ensure that the visual state of the element (for example, active tab or selected option) matches the <code>aria-selected</code> value. Inconsistent states can lead to confusion for users of assistive technologies.</p>
</li>
<li><p>Use <code>aria-selected</code> in conjunction with appropriate <code>role</code> attributes (for example, <code>role="option"</code> for listbox items) to provide complete context.</p>
</li>
<li><p>Ensure that <code>aria-selected</code> is updated dynamically as users interact with the interface. For example, when a user selects a new option, update the <code>aria-selected</code> attribute accordingly.</p>
</li>
</ul>
<h2 id="heading-the-tabindex-attribute">The <code>tabindex</code> Attribute</h2>
<p>The <code>tabindex</code> attribute is used to control the keyboard navigation of an element. You can use it to activate focus for non-interactive elements like <code>div</code>, <code>p</code>, or <code>span</code> or disable focus for interactive elements like <code>button</code>, <code>a</code>, <code>input</code>. You can also use it to control focus order on a page.</p>
<h3 id="heading-possible-tabindex-values">Possible <code>tabindex</code> Values</h3>
<p><strong>Positive values:</strong> Elements with positive values become focusable and are included in the tab order with their numbers determining the order in which they are focused. Elements with lower numbers are focused before elements with higher numbers.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">tabindex</span>=<span class="hljs-string">"2"</span>&gt;</span>Cancel<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> <span class="hljs-comment">&lt;!-- This will recieve focus last --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">tabindex</span>=<span class="hljs-string">"1"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> <span class="hljs-comment">&lt;!-- This will recieve focus first --&gt;</span>
</code></pre>
<p>Elements with the same values will be navigated in the order in which they appear.</p>
<p><strong>Note:</strong> Using positive <code>tabindex</code> values can lead to a confusing and non-intuitive tab order. It is generally better to use <code>tabindex="0"</code> for elements that should be part of the natural tab order.</p>
<p><strong>Zero:</strong> You use this to make an element focusable and include it in the natural tab order based on its position in the document. It's useful for making elements focusable that are not normally focusable (like <code>&lt;div&gt;</code> or <code>&lt;span&gt;</code>).</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">tabindex</span>=<span class="hljs-string">"0"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> 
<span class="hljs-comment">&lt;!-- The element becomes focusable using the keyboard --&gt;</span>
</code></pre>
<p><strong>Negative values:</strong> You use this to remove an element from the tab order, meaning it cannot be focused using the <code>Tab</code> key. But it can still be focused programmatically (via JavaScript). It's useful for elements that should not be focusable by default but may need to be focusable under certain conditions.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"name"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"other-names"</span> <span class="hljs-attr">tabindex</span>=<span class="hljs-string">"-1"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"email"</span>&gt;</span>

<span class="hljs-comment">&lt;!-- other-names will be skipped when tabbing through the inputs; 
only name and email will receive focus --&gt;</span>
</code></pre>
<h3 id="heading-best-practices-for-using-tabindex">Best Practices for Using <code>tabindex</code></h3>
<ul>
<li><p>Rely on the natural tab order as much as possible. Use <code>tabindex="0"</code> to include elements in the tab order and avoid using positive values unless absolutely necessary.</p>
</li>
<li><p>Using positive <code>tabindex</code> values can create an unpredictable tab order and make it harder for users to navigate. It's better to use the default flow and <code>tabindex="0"</code>.</p>
</li>
<li><p>Use <code>tabindex="-1"</code> for elements not intended to be focused.</p>
</li>
<li><p>Ensure that the focus order follows a logical and intuitive sequence, which matches the visual layout and interaction flow of the page.</p>
</li>
<li><p>Test with keyboard and assistive technologies.</p>
</li>
<li><p>When dynamically adding or removing focusable elements (for example, through JavaScript), ensure that focus management is handled properly to maintain a smooth experience.</p>
</li>
</ul>
<h2 id="heading-the-title-attribute">The <code>title</code> Attribute</h2>
<p>The <code>title</code> attribute in HTML is used to provide additional information about an element. The content in the attribute shows in a tooltip when a user hovers over the element containing the title. It can be applied to most HTML elements, including links, images, and form fields.</p>
<p>You can use the title attribute to provide a brief explanation or description of the content of an element. For example, you can use it to clarify the meaning of abbreviations or acronyms when used with the <code>&lt;abbr&gt;</code> tag.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">abbr</span> <span class="hljs-attr">title</span>=<span class="hljs-string">"World Wide Web"</span>&gt;</span>WWW<span class="hljs-tag">&lt;/<span class="hljs-name">abbr</span>&gt;</span>
<span class="hljs-comment">&lt;!-- Hovering over "WWW" displays the tooltip "World Wide Web," 
explaining the abbreviation. --&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"logo.png"</span> 
<span class="hljs-attr">alt</span>=<span class="hljs-string">"Company Logo"</span> 
<span class="hljs-attr">title</span>=<span class="hljs-string">"This is the logo of our company"</span>&gt;</span>
<span class="hljs-comment">&lt;!-- Users will see "This is the logo of our company" 
when hovering over the image. --&gt;</span>
</code></pre>
<h3 id="heading-accessibility-concerns-with-the-title-attribute">Accessibility Concerns with the <code>title</code> Attribute</h3>
<p>The title attribute can be useful, but it comes with some accessibility concerns:</p>
<ul>
<li><p>Screen readers do not consistently announce the <code>title</code> attribute, especially when there is also an <code>alt</code> attribute – or they may ignore it altogether. Users of assistive technologies may miss out on the information provided by the <code>title</code> attribute, especially if they rely solely on screen readers.</p>
</li>
<li><p>The tooltip generated by the <code>title</code> attribute typically appears only on hover with a mouse or trackpad. Users who navigate with a keyboard or touch screen may not have access to this information.</p>
</li>
<li><p>The content of the <code>title</code> attribute is hidden by default and only revealed on hover. This makes it less accessible to users who don't know they need to hover to get additional information.</p>
</li>
<li><p>Tooltips can be difficult to read because they often disappear quickly, and their content might be truncated or too long to fit within the tooltip window.</p>
</li>
</ul>
<h3 id="heading-best-practices-for-using-the-title-attribute">Best Practices for Using the <code>title</code> Attribute</h3>
<ul>
<li><p>Avoid relying solely on the <code>title</code> attribute. Ensure that critical information is available in a more accessible manner, such as visible text or ARIA attributes.</p>
</li>
<li><p>Use the <code>title</code> attribute for supplementary, non-essential information that enhances user experience but isn’t critical to understanding the content.</p>
</li>
<li><p>For form inputs, use the <code>aria-describedby</code> attribute to associate additional instructions with a form element. Use visible labels or descriptions instead of or in addition to the <code>title</code> attribute to ensure that all users have access to the information.</p>
</li>
<li><p>If you use the <code>title</code> attribute, keep the text brief and to the point. Long tooltips can be difficult to read and may get truncated.</p>
</li>
</ul>
<h2 id="heading-using-the-for-attribute-in-label">Using the <code>for</code> Attribute in <code>label</code></h2>
<p>The <code>for</code> attribute, when used in <code>&lt;label&gt;</code>, is used to connect a label to its corresponding form control element – that is <code>&lt;input&gt;</code>, <code>&lt;select&gt;</code>, or <code>&lt;textarea&gt;</code>. Screen readers will announce the label when the assigned input is focused. When used correctly, clicking on the label will focus on the corresponding input.</p>
<p>The value of the <code>for</code> attribute should match the <code>id</code> of the input it is associated with:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"fullname"</span>&gt;</span>Full Name<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"fullname"</span>&gt;</span>
<span class="hljs-comment">&lt;!-- When the user clicks on the "Full Name" label, 
the cursor will focus on the corresponding input field. --&gt;</span>
</code></pre>
<h3 id="heading-best-practices-for-using-the-for-attribute">Best Practices for Using the <code>for</code> Attribute</h3>
<ul>
<li><p>Ensure that each form control has a unique <code>id</code> attribute so that the <code>for</code> attribute can correctly reference it. Avoid using duplicate <code>id</code> values on the same page.</p>
</li>
<li><p>Avoid empty <code>for</code> attributes. If there’s no associated form control, it can confuse users of assistive technologies.</p>
</li>
<li><p>Position labels close to their associated form controls. Typically, labels should be placed above or to the left of the form controls for optimal readability and usability.</p>
</li>
</ul>
<h2 id="heading-the-scope-attribute">The <code>scope</code> Attribute</h2>
<p>The <code>scope</code> attribute is used in HTML tables to define the relationship between table headers and the cells they describe. The attribute is particularly important for accessibility because it helps screen readers and other assistive technologies understand the structure of the table and convey the correct information to users.</p>
<p>The <code>scope</code> attribute is applied to <code>&lt;th&gt;</code> (table header) elements to specify whether the header applies to a row, a column, or a group of rows or columns</p>
<h3 id="heading-possible-scope-values">Possible <code>scope</code> Values</h3>
<ul>
<li><code>row</code>: Indicates that the <code>&lt;th&gt;</code> element is a header for a row. In the example below, <code>scope="row"</code> is used for the first <code>&lt;th&gt;</code> element in each row, indicating that the header applies to the entire row.</li>
</ul>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">table</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">tbody</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"row"</span>&gt;</span>Product A<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>$1000<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>$1200<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>$1100<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"row"</span>&gt;</span>Product B<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>$900<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>$950<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>$1000<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">tbody</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">table</span>&gt;</span>
</code></pre>
<ul>
<li><code>col</code>: Indicates that the <code>&lt;th&gt;</code> element is a header for a column.</li>
</ul>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">table</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">thead</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"col"</span>&gt;</span>Name<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"col"</span>&gt;</span>Age<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"col"</span>&gt;</span>Occupation<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
<span class="hljs-comment">&lt;!-- The scope="col" attribute indicates that each &lt;th&gt; element 
serves as a header for the corresponding column beneath it. --&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">thead</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">tbody</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>Jane<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>30<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>Engineer<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>Tobe<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>25<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>Designer<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">tbody</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">table</span>&gt;</span>
</code></pre>
<ul>
<li><code>rowgroup</code>: Indicates that the <code>&lt;th&gt;</code> element is a header for a group of rows. In the example below, the rows "Marketing Department" and "Sales Department" have the <code>scope="rowgroup"</code> attribute to indicate that these rows act as headers for the groups of rows that follow:</li>
</ul>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">table</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">thead</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"col"</span>&gt;</span>Department<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"col"</span>&gt;</span>Employee Name<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"col"</span>&gt;</span>Position<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"col"</span>&gt;</span>Salary<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">thead</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">tbody</span>&gt;</span>
    <span class="hljs-comment">&lt;!-- Row Group for the Marketing Department --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"rowgroup"</span> <span class="hljs-attr">colspan</span>=<span class="hljs-string">"4"</span>&gt;</span>Marketing Department<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"row"</span>&gt;</span>Amari Pere<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>Marketing Manager<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>$75,000<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"row"</span>&gt;</span>Uyati Hope<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>SEO Specialist<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>$65,000<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>

    <span class="hljs-comment">&lt;!-- Row Group for the Sales Department --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"rowgroup"</span> <span class="hljs-attr">colspan</span>=<span class="hljs-string">"4"</span>&gt;</span>Sales Department<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"row"</span>&gt;</span>Timini Prosper<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>Sales Manager<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>$80,000<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"row"</span>&gt;</span>Delilu Pink<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>Account Executive<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>$70,000<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">tbody</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">table</span>&gt;</span>
</code></pre>
<ul>
<li><code>colgroup</code>: Indicates that the <code>&lt;th&gt;</code> element is a header for a group of columns. In the example below, <code>scope="colgroup"</code> is used to indicate that the first row of headers applies to groups of columns (Q1 and Q2), while <code>scope="col"</code> and <code>scope="row"</code> are used for individual columns and rows.</li>
</ul>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">table</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">thead</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"colgroup"</span>&gt;</span>Region<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"colgroup"</span>&gt;</span>Q1<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"colgroup"</span>&gt;</span>Q2<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"col"</span>&gt;</span>Sales<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"col"</span>&gt;</span>Profit<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"col"</span>&gt;</span>Sales<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"col"</span>&gt;</span>Profit<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">thead</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">tbody</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"row"</span>&gt;</span>North<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>$2000<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>$400<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>$2500<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>$500<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">tr</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">th</span> <span class="hljs-attr">scope</span>=<span class="hljs-string">"row"</span>&gt;</span>South<span class="hljs-tag">&lt;/<span class="hljs-name">th</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>$1500<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>$300<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>$1800<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">td</span>&gt;</span>$350<span class="hljs-tag">&lt;/<span class="hljs-name">td</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">tr</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">tbody</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">table</span>&gt;</span>
</code></pre>
<h3 id="heading-best-practices-for-using-the-scope-attribute">Best Practices for Using the <code>scope</code> Attribute</h3>
<ul>
<li><p>Always define <code>scope</code> for complex tables to clarify the relationship between headers and data cells.</p>
</li>
<li><p>Simplify table structures when possible. While the <code>scope</code> attribute helps with accessibility, consider simplifying table structures where possible. If a table is too complex, it might be difficult for all users to understand, even with proper markup.</p>
</li>
<li><p>For particularly complex tables, consider using ARIA attributes like <code>aria-labelledby</code> or <code>aria-describedby</code> to provide additional context and ensure that all users can navigate the table effectively.</p>
</li>
<li><p>After applying the <code>scope</code> attribute, test the table with screen readers to ensure that the relationships between headers and data cells are announced correctly.</p>
</li>
<li><p>Don’t use <code>scope</code> in situations where it’s unnecessary. For simple tables where each header is clearly associated with a single row or column, HTML’s default behavior is usually sufficient.</p>
</li>
</ul>
<h2 id="heading-the-aria-hidden-attribute">The <code>aria-hidden</code> Attribute</h2>
<p>The aria-hidden attribute is used to control the visibility of an element for assistive technologies while it's still visible on the screen. You can use it to hide purely decorative elements, like icons or images, that don't add meaningful information to the content. This helps prevent screen readers from reading unnecessary information.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">aria-hidden</span>=<span class="hljs-string">"true"</span>&gt;</span>🔍<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
    Search
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p>You can also use it to hide content that has already been announced to prevent redundancy in what screen readers announce. For content that is toggled on and off (like modals, or expandable sections), you can use <code>aria-hidden</code> to hide the inactive content from screen readers, ensuring that they only interact with the visible, active content.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">aria-hidden</span>=<span class="hljs-string">"true"</span>&gt;</span>✉<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span> <span class="hljs-comment">&lt;!-- hide decorative icon --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Messages<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p>You can also use <code>aria-hidden</code> when creating complex widgets (like carousels or tabbed interfaces) to hide inactive panels or slides from assistive technologies, focusing their attention on the active part of the widget.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"menu"</span> <span class="hljs-attr">aria-hidden</span>=<span class="hljs-string">"true"</span>&gt;</span>
    <span class="hljs-comment">&lt;!-- Menu content here --&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"toggleMenu()"</span>&gt;</span>Toggle Menu<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
    <span class="hljs-keyword">const</span> toggleMenu = <span class="hljs-function">() =&gt;</span> {
        <span class="hljs-keyword">const</span> menu = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'menu'</span>);
        <span class="hljs-keyword">const</span> isHidden = menu.getAttribute(<span class="hljs-string">'aria-hidden'</span>) === <span class="hljs-string">'true'</span>;

        menu.setAttribute(<span class="hljs-string">'aria-hidden'</span>, !isHidden);
    }
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h3 id="heading-best-practices-for-using-aria-hidden">Best Practices for Using <code>aria-hidden</code></h3>
<ul>
<li><p>Only use <code>aria-hidden</code> when you need to hide content from screen readers to avoid overwhelming users with redundant or irrelevant information.</p>
</li>
<li><p>Do not use on elements that users need to interact with, like buttons or links.</p>
</li>
<li><p>Ensure that <code>aria-hidden</code> accurately reflects the visibility of elements on the screen. If an element becomes visible or hidden via JavaScript or CSS, update <code>aria-hidden</code> accordingly to maintain accessibility.</p>
</li>
<li><p>In a team environment, document why and where <code>aria-hidden</code> is used in your codebase, so that other team members understand its purpose and can maintain it properly.</p>
</li>
</ul>
<h2 id="heading-the-inert-attribute">The <code>inert</code> Attribute</h2>
<p>The <code>inert</code> attribute prevents an element and all of its descendants from being focusable, interactive, or perceivable by assistive technologies. When an element has the <code>inert</code> attribute, it cannot receive focus, be clicked on, or be interacted with in any way. It's also hidden from assistive technologies like screen readers.</p>
<p>Unlike <code>aria-hidden</code>, which only affects accessibility, <code>inert</code> applies to all user interactions. The inert attribute can be used to disable sections of a page that are temporarily irrelevant, such as during form validation errors, while loading data, or when a certain section is hidden but still in the DOM. It can also be used in complex user interfaces like multi-step forms or wizards to ensure that users only interact with the current step or section</p>
<p>The most common use of inert, however, is in a modal, where you want to prevent users from interacting with the background content while the modal is open.</p>
<p>Like in the example below, when the modal is open the <code>inert</code> attribute is added to the main content, making it non-interactive and hidden from screen readers. When the modal is closed, the <code>inert</code> attribute is removed, and the main content becomes interactive again.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"main-content"</span> <span class="hljs-attr">inert</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>This is the main content of the page. It will be inactive when the modal is open.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"modal"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"dialog"</span> <span class="hljs-attr">aria-modal</span>=<span class="hljs-string">"true"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Modal Title<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>This is the content inside the modal.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"closeModal()"</span>&gt;</span>Close Modal<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">openModal</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'main-content'</span>).setAttribute(<span class="hljs-string">'inert'</span>, <span class="hljs-string">''</span>);
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'modal'</span>).style.display = <span class="hljs-string">'block'</span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">closeModal</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'main-content'</span>).removeAttribute(<span class="hljs-string">'inert'</span>);
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'modal'</span>).style.display = <span class="hljs-string">'none'</span>;
}
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h3 id="heading-best-practices-for-using-the-inert-attribute">Best Practices for Using the <code>inert</code> Attribute</h3>
<ul>
<li><p>Ensure that when you use <code>inert</code>, the visually inactive or disabled state of elements is clear to sighted users. For example, dimming or blurring background content when a modal is open can complement the <code>inert</code> attribute.</p>
</li>
<li><p>Don't overuse <code>inert</code>, as doing so might unintentionally make significant portions of your page non-interactive and inaccessible. Use it judiciously to manage user focus and interaction only when necessary.</p>
</li>
<li><p>When dynamically adding and removing the <code>inert</code> attribute, ensure that it is properly removed when no longer needed so that users can regain access to previously disabled content.</p>
</li>
</ul>
<h2 id="heading-the-aria-live-attribute">The <code>aria-live</code> Attribute</h2>
<p>You can use the <code>aria-live</code> attribute to notify assistive technologies about dynamic content changes on a webpage. When <code>aria-live</code> is applied to an element, screen readers are alerted when the content inside that element is updated, ensuring that users are informed about important changes that occur after the page has initially loaded.</p>
<p>This attribute can be useful for content that updates dynamically, such as notifications, alerts, chat messages, or stock prices. It ensures that users are aware of changes that might otherwise go unnoticed.</p>
<h3 id="heading-possible-values-for-aria-live">Possible Values for <code>aria-live</code></h3>
<p>There are three main values: <code>off</code>, <code>polite</code>, and <code>assertive</code>.</p>
<ul>
<li><p><code>off</code>: Default value, updates to the element will not be announced by screen readers.</p>
</li>
<li><p><code>polite</code>: Updates will be announced by the screen reader, but only after the user has finished interacting with the current task or reading other content. This ensures that the update does not interrupt the user’s current activity.</p>
</li>
</ul>
<p>In the example below, each new message is added to the <code>#messages</code> container, which has <code>aria-live="polite"</code>. The screen reader will announce the new message only after the user finishes their current activity.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"chat-window"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"messages"</span> <span class="hljs-attr">aria-live</span>=<span class="hljs-string">"polite"</span>&gt;</span>
        <span class="hljs-comment">&lt;!-- Existing messages are here --&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>John: Hello!<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>You: Hi there!<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"addMessage()"</span>&gt;</span>Send Message<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">addMessage</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> newMessage = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>);
    newMessage.textContent = <span class="hljs-string">'Alice: How are you?'</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'messages'</span>).appendChild(newMessage);
}
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<ul>
<li><code>assertive</code>: Updates will be announced immediately, interrupting whatever the screen reader is currently announcing. Use this for urgent or critical information that requires the user’s immediate attention.</li>
</ul>
<p>In the example below, updates to the stock prices are placed within a container that has <code>aria-live="assertive"</code>.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"stock-ticker"</span> <span class="hljs-attr">aria-live</span>=<span class="hljs-string">"assertive"</span>&gt;</span>
    <span class="hljs-comment">&lt;!-- Initial stock prices --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"stock1"</span>&gt;</span>Stock A: $100<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"stock2"</span>&gt;</span>Stock B: $150<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"updateStockPrices()"</span>&gt;</span>Update Prices<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">updateStockPrices</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'stock1'</span>).textContent = <span class="hljs-string">'Stock A: $95'</span>;
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'stock2'</span>).textContent = <span class="hljs-string">'Stock B: $155'</span>;
}
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h3 id="heading-best-practices-for-using-aria-live">Best Practices for Using <code>aria-live</code></h3>
<ul>
<li><p>Use <code>aria-live="polite"</code> for non-critical updates to avoid disrupting the user’s experience. Reserve <code>aria-live="assertive"</code> for urgent updates that require immediate attention, such as critical errors or security warnings.</p>
</li>
<li><p>Be mindful of how often you use <code>aria-live</code> elements on a page. Overusing it can lead to an overstimulating experience for users who rely on screen readers, as they may be overwhelmed by frequent announcements.</p>
</li>
<li><p>Don’t use <code>aria-live</code> on content that doesn’t need to be announced, or on content that’s already being communicated to the user in another way.</p>
</li>
<li><p><code>aria-live</code> is particularly useful for content that is updated dynamically, such as live sports scores, breaking news, or chat applications. Make sure that the user is kept informed of important updates as they occur.</p>
</li>
</ul>
<h2 id="heading-the-aria-roledescription-attribute">The <code>aria-roledescription</code> Attribute</h2>
<p>You can use <code>aria-roledescription</code> to provide a human-readable, localized description for the role of an element. It overrides the implicit or explicit <code>role</code> value for screen readers, and allows developers to create more intuitive and context-specific descriptions for complex or unconventional user interface components that may not have a standard role name.</p>
<p>You can use it to provide a clearer explanation of the element’s purpose or functionality.</p>
<p>In the example below, screen readers will announce it as "Bookmark Button" instead of just "Button."</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">aria-roledescription</span>=<span class="hljs-string">"Bookmark Button"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">aria-hidden</span>=<span class="hljs-string">"true"</span>&gt;</span>⭐<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span> Save this page
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p>You can also use it to support internationalization, like providing role descriptions in different languages.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">aria-roledescription</span>=<span class="hljs-string">"Search Button"</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">aria-hidden</span>=<span class="hljs-string">"true"</span>&gt;</span>🔍<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span> Search
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">aria-roledescription</span>=<span class="hljs-string">"Botón de busqueda"</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"es"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">aria-hidden</span>=<span class="hljs-string">"true"</span>&gt;</span>🔍<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span> Buscar
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">aria-roledescription</span>=<span class="hljs-string">"Bouton de recherche"</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"fr"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">aria-hidden</span>=<span class="hljs-string">"true"</span>&gt;</span>🔍<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span> Recherche
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<h3 id="heading-best-practices-for-using-aria-roledescription">Best Practices for Using <code>aria-roledescription</code></h3>
<ul>
<li><p>Only use <code>aria-roledescription</code> when the standard role does not sufficiently describe the element's purpose.</p>
</li>
<li><p>The description should be short, clear, and directly related to the element's function. Avoid using jargon or overly technical language.</p>
</li>
<li><p><code>aria-roledescription</code> should be used alongside an appropriate ARIA role, not as a replacement. The <code>role</code> provides the foundational context (like <code>"button"</code> or <code>"listbox"</code>), while the description adds clarity.</p>
</li>
<li><p>If your application supports multiple languages, ensure that the <code>aria-roledescription</code> values are localized to match the user's language preferences. This helps provide a consistent and understandable experience.</p>
</li>
<li><p>Ensure that the <code>aria-roledescription</code> does not repeat or conflict with other ARIA attributes or element labels. It should complement, not duplicate, the information already provided.</p>
</li>
</ul>
<h2 id="heading-the-aria-atomic-attribute">The <code>aria-atomic</code> Attribute</h2>
<p>You can use the <code>aria-atomic</code> attribute to control how updates to an element are announced by assistive technologies. When <code>aria-atomic</code> is set to <code>true</code>, it indicates that when changes occur within the element, the entire content of the element should be treated as a single unit and announced in full by the screen reader (rather than announcing only the changed parts).</p>
<p>In cases where updates to part of an element might make the overall context unclear, <code>aria-atomic</code> helps by providing a full announcement of the element's content, giving users a complete understanding of the context.</p>
<p>It is often used in conjunction with <code>aria-live</code>. While <code>aria-live</code> determines how updates are announced (politely or assertively), <code>aria-atomic</code> controls whether the entire content is read or just the changes.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"news-ticker"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"region"</span> <span class="hljs-attr">aria-live</span>=<span class="hljs-string">"polite"</span> <span class="hljs-attr">aria-atomic</span>=<span class="hljs-string">"true"</span>&gt;</span>
  Breaking News: Major storm expected this weekend.
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"updateHeadline()"</span>&gt;</span>Update Headline<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">updateHeadline</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'news-ticker'</span>).innerText = <span class="hljs-string">'Breaking News: Stock market hits record high!'</span>;
}
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<h3 id="heading-best-practices-for-using-aria-atomic">Best Practices for Using <code>aria-atomic</code></h3>
<ul>
<li><p>Apply <code>aria-atomic="true"</code> only to elements where a full announcement of updates is essential for understanding the context.</p>
</li>
<li><p>When using <code>aria-atomic="true"</code>, ensure that the content within the element provides consistent and complete context to users.</p>
</li>
<li><p>Use <code>aria-atomic</code> in combination with <code>aria-live</code> to specify how updates should be announced. This ensures that the updates are announced in the appropriate manner and with full context.</p>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Understanding and effectively using HTML attributes for accessibility is crucial for creating inclusive web experiences. By understanding and using these attributes appropriately, you can ensure that your application has a great user experience for all visitors.</p>
<h3 id="heading-resources">Resources</h3>
<ul>
<li><p><a target="_blank" href="https://www.w3.org/WAI/ARIA/apg/practices/names-and-descriptions/">Providing Accessible Names and Descriptions</a></p>
</li>
<li><p><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA">MDN ARIA</a></p>
</li>
<li><p><a target="_blank" href="https://www.w3.org/WAI/ARIA/apg/practices/read-me-first/">No ARIA is better than Bad ARIA</a></p>
</li>
<li><p><a target="_blank" href="https://www.w3.org/WAI/ARIA/apg/example-index/#examples_by_props_label">ARIA examples by properties and states</a></p>
</li>
</ul>
<p>Thank you so much for reading, I hope this guide helps you create more accessible web content. If you found it helpful, consider sharing.</p>
<p>You can connect with me on <a target="_blank" href="https://www.linkedin.com/in/elizabeth-meshioye/">LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
