Introduction to Semantic HTML
Semantic HTML uses elements that clearly describe their meaning and purpose, both to browsers and developers. This improves accessibility, SEO, and code maintainability compared to generic <div> and <span> elements.
Core Semantic Elements
Document Structure Elements
html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Semantic HTML Example</title>
</head>
<body>
  <!-- Main page header -->
  <header>
    <h1>Website Title</h1>
    <nav>
      <ul>
        <li><a href="#home">Home</a></li>
        <li><a href="#about">About</a></li>
        <li><a href="#contact">Contact</a></li>
      </ul>
    </nav>
  </header>
  
  <!-- Main content area -->
  <main>
    <article>
      <header>
        <h1>Article Title</h1>
        <p>Published on <time datetime="2024-09-14">September 14, 2024</time></p>
      </header>
      
      <section>
        <h2>Introduction</h2>
        <p>Article introduction content...</p>
      </section>
      
      <section>
        <h2>Main Content</h2>
        <p>Main article content...</p>
      </section>
    </article>
    
    <aside>
      <h2>Related Articles</h2>
      <ul>
        <li><a href="#article1">Related Article 1</a></li>
        <li><a href="#article2">Related Article 2</a></li>
      </ul>
    </aside>
  </main>
  
  <!-- Page footer -->
  <footer>
    <p>© 2024 Website Name. All rights reserved.</p>
  </footer>
</body>
</html>
Content Sectioning Elements
html
<!-- Article: Self-contained content -->
<article>
  <h1>How to Learn HTML</h1>
  <p>A complete guide to learning HTML...</p>
  
  <!-- Section: Thematic grouping of content -->
  <section>
    <h2>Getting Started</h2>
    <p>Begin with the basics...</p>
  </section>
  
  <section>
    <h2>Advanced Topics</h2>
    <p>Once you master the basics...</p>
  </section>
</article>
<!-- Aside: Tangentially related content -->
<aside>
  <h3>Quick Tips</h3>
  <ul>
    <li>Always validate your HTML</li>
    <li>Use semantic elements</li>
    <li>Consider accessibility</li>
  </ul>
</aside>
Text-Level Semantic Elements
html
<!-- Emphasis and importance -->
<p>This is <em>emphasized</em> text (usually italic).</p>
<p>This is <strong>important</strong> text (usually bold).</p>
<!-- Technical content -->
<p>To create a paragraph, use the <code><p></code> element.</p>
<pre><code>
function example() {
  console.log("Hello World");
}
</code></pre>
<!-- Definitions and abbreviations -->
<p>The <dfn>World Wide Web</dfn> is a system of interlinked documents.</p>
<p>We use <abbr title="HyperText Markup Language">HTML</abbr> to structure content.</p>
<!-- Dates and times -->
<p>The event starts at <time datetime="2024-09-14T19:00">7:00 PM</time>.</p>
<p>Published <time datetime="2024-09-14">September 14, 2024</time>.</p>
<!-- Contact information -->
<address>
  <p>Contact us:</p>
  <p>Email: <a href="mailto:info@example.com">info@example.com</a></p>
  <p>Phone: <a href="tel:+1234567890">+1 (234) 567-890</a></p>
</address>
Introduction to ARIA (Accessible Rich Internet Applications)
ARIA provides additional semantic information for complex web applications, especially when semantic HTML isn't sufficient.
ARIA Roles
ARIA roles define what an element is or does:
html
<!-- Landmark roles -->
<div role="banner">
  <h1>Site Header</h1>
</div>
<div role="navigation">
  <ul>
    <li><a href="#home">Home</a></li>
    <li><a href="#about">About</a></li>
  </ul>
</div>
<div role="main">
  <h1>Main Content</h1>
</div>
<div role="complementary">
  <h2>Sidebar Content</h2>
</div>
<div role="contentinfo">
  <p>Footer information</p>
</div>
<!-- Widget roles -->
<div role="button" tabindex="0">Custom Button</div>
<div role="tab" tabindex="0">Tab 1</div>
<div role="tabpanel">Tab content</div>
<div role="dialog" aria-labelledby="dialog-title">
  <h2 id="dialog-title">Dialog Title</h2>
  <p>Dialog content goes here.</p>
</div>
ARIA Properties and States
html
<!-- Labels and descriptions --> <button aria-label="Close dialog">×</button> <input type="text" aria-describedby="help-text"> <div id="help-text">Enter your full name</div> <!-- States --> <button aria-pressed="false">Toggle Button</button> <div aria-expanded="false" aria-controls="menu">Menu</div> <ul id="menu" aria-hidden="true"> <li>Menu Item 1</li> <li>Menu Item 2</li> </ul> <!-- Live regions --> <div aria-live="polite" id="status">Status updates appear here</div> <div aria-live="assertive" id="errors">Critical errors appear here</div> <!-- Form validation --> <input type="email" aria-invalid="false" aria-describedby="email-error"> <div id="email-error" role="alert" aria-live="assertive"></div>
Complete Semantic HTML Example
html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Tech Blog - Semantic HTML Guide</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      max-width: 1200px;
      margin: 0 auto;
      padding: 20px;
      line-height: 1.6;
    }
    
    header {
      background: #f8f9fa;
      padding: 20px;
      border-radius: 8px;
      margin-bottom: 20px;
    }
    
    nav ul {
      list-style: none;
      padding: 0;
      display: flex;
      gap: 20px;
    }
    
    main {
      display: grid;
      grid-template-columns: 2fr 1fr;
      gap: 20px;
    }
    
    article {
      background: white;
      padding: 20px;
      border-radius: 8px;
      box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    }
    
    aside {
      background: #f8f9fa;
      padding: 20px;
      border-radius: 8px;
      height: fit-content;
    }
    
    footer {
      background: #343a40;
      color: white;
      text-align: center;
      padding: 20px;
      border-radius: 8px;
      margin-top: 20px;
    }
    
    .sr-only {
      position: absolute;
      width: 1px;
      height: 1px;
      padding: 0;
      margin: -1px;
      overflow: hidden;
      clip: rect(0,0,0,0);
      white-space: nowrap;
      border: 0;
    }
    
    .skip-link {
      position: absolute;
      top: -40px;
      left: 6px;
      background: #000;
      color: white;
      padding: 8px;
      text-decoration: none;
      z-index: 1000;
    }
    
    .skip-link:focus {
      top: 6px;
    }
  </style>
</head>
<body>
  <!-- Skip navigation for screen readers -->
  <a href="#main-content" class="skip-link">Skip to main content</a>
  
  <!-- Site header with navigation -->
  <header role="banner">
    <h1>Tech Learning Hub</h1>
    <nav role="navigation" aria-label="Main navigation">
      <ul>
        <li><a href="#home" aria-current="page">Home</a></li>
        <li><a href="#tutorials">Tutorials</a></li>
        <li><a href="#blog">Blog</a></li>
        <li><a href="#about">About</a></li>
        <li><a href="#contact">Contact</a></li>
      </ul>
    </nav>
  </header>
  
  <!-- Main content area -->
  <main id="main-content">
    <!-- Primary content -->
    <section>
      <article>
        <header>
          <h1>Understanding Semantic HTML and ARIA</h1>
          <p>By <span class="author">Jane Developer</span></p>
          <p>Published on <time datetime="2024-09-14T10:30:00">September 14, 2024</time></p>
          <p>Reading time: <span class="reading-time">11 minutes</span></p>
        </header>
        
        <section aria-labelledby="introduction">
          <h2 id="introduction">Introduction</h2>
          <p>Semantic HTML and ARIA work together to create accessible, meaningful web experiences. 
             In this comprehensive guide, we'll explore both concepts and learn how to implement them effectively.</p>
        </section>
        
        <section aria-labelledby="semantic-elements">
          <h2 id="semantic-elements">Semantic Elements</h2>
          <p>HTML5 introduced many semantic elements that clearly describe their content:</p>
          
          <dl>
            <dt><code><header></code></dt>
            <dd>Represents introductory content or navigation aids</dd>
            
            <dt><code><nav></code></dt>
            <dd>Contains navigation links</dd>
            
            <dt><code><main></code></dt>
            <dd>Represents the main content of the document</dd>
            
            <dt><code><article></code></dt>
            <dd>Self-contained content that could be distributed independently</dd>
            
            <dt><code><section></code></dt>
            <dd>Thematic grouping of content with a heading</dd>
            
            <dt><code><aside></code></dt>
            <dd>Content indirectly related to the main content</dd>
            
            <dt><code><footer></code></dt>
            <dd>Footer information for its section or page</dd>
          </dl>
        </section>
        
        <section aria-labelledby="aria-basics">
          <h2 id="aria-basics">ARIA Basics</h2>
          <p><abbr title="Accessible Rich Internet Applications">ARIA</abbr> provides 
             additional semantic information for complex interfaces.</p>
          
          <h3>Key ARIA Concepts:</h3>
          <ul>
            <li><strong>Roles:</strong> Define what an element is</li>
            <li><strong>Properties:</strong> Describe element properties</li>
            <li><strong>States:</strong> Describe current conditions</li>
          </ul>
          
          <blockquote cite="https://www.w3.org/WAI/ARIA/">
            <p>"ARIA defines a way to make web content more accessible to people with disabilities."</p>
            <footer>— <cite>W3C Web Accessibility Initiative</cite></footer>
          </blockquote>
        </section>
        
        <section aria-labelledby="best-practices">
          <h2 id="best-practices">Best Practices</h2>
          <ol>
            <li>Use semantic HTML first, ARIA when necessary</li>
            <li>Test with screen readers</li>
            <li>Validate your markup</li>
            <li>Keep accessibility in mind from the start</li>
          </ol>
        </section>
        
        <footer>
          <p>Tags: 
            <a href="#html" rel="tag">HTML</a>, 
            <a href="#accessibility" rel="tag">Accessibility</a>, 
            <a href="#aria" rel="tag">ARIA</a>
          </p>
          
          <nav aria-label="Article navigation">
            <a href="#previous-article" rel="prev">← Previous: HTML Forms</a>
            <a href="#next-article" rel="next">Next: CSS Basics →</a>
          </nav>
        </footer>
      </article>
      
      <!-- Comments section -->
      <section aria-labelledby="comments-heading">
        <h2 id="comments-heading">Comments <span class="sr-only">(3 comments)</span></h2>
        
        <form role="form" aria-labelledby="comment-form-heading">
          <h3 id="comment-form-heading" class="sr-only">Leave a comment</h3>
          
          <div>
            <label for="comment-name">Name <span aria-label="required">*</span></label>
            <input type="text" id="comment-name" name="name" required aria-describedby="name-help">
            <div id="name-help">Please enter your full name</div>
          </div>
          
          <div>
            <label for="comment-email">Email <span aria-label="required">*</span></label>
            <input type="email" id="comment-email" name="email" required aria-describedby="email-help">
            <div id="email-help">Your email will not be published</div>
          </div>
          
          <div>
            <label for="comment-text">Comment <span aria-label="required">*</span></label>
            <textarea id="comment-text" name="comment" rows="4" required 
                      aria-describedby="comment-help" maxlength="500"></textarea>
            <div id="comment-help">Maximum 500 characters. <span id="char-count">0/500</span></div>
          </div>
          
          <button type="submit">Post Comment</button>
        </form>
        
        <!-- Existing comments -->
        <ol>
          <li>
            <article>
              <header>
                <h4>John Smith</h4>
                <p><time datetime="2024-09-14T11:30:00">Today at 11:30 AM</time></p>
              </header>
              <p>Great article! Very comprehensive explanation of semantic HTML.</p>
            </article>
          </li>
          
          <li>
            <article>
              <header>
                <h4>Sarah Johnson</h4>
                <p><time datetime="2024-09-14T12:15:00">Today at 12:15 PM</time></p>
              </header>
              <p>The ARIA examples are particularly helpful. Thanks for sharing!</p>
            </article>
          </li>
        </ol>
      </section>
    </section>
    
    <!-- Sidebar content -->
    <aside role="complementary" aria-labelledby="sidebar-heading">
      <h2 id="sidebar-heading" class="sr-only">Sidebar</h2>
      
      <section aria-labelledby="related-articles">
        <h3 id="related-articles">Related Articles</h3>
        <ul>
          <li><a href="#form-accessibility">Form Accessibility Best Practices</a></li>
          <li><a href="#screen-reader-testing">Testing with Screen Readers</a></li>
          <li><a href="#wcag-guidelines">Understanding WCAG Guidelines</a></li>
        </ul>
      </section>
      
      <section aria-labelledby="quick-reference">
        <h3 id="quick-reference">Quick Reference</h3>
        <details>
          <summary>Common ARIA Attributes</summary>
          <dl>
            <dt><code>aria-label</code></dt>
            <dd>Provides accessible name</dd>
            
            <dt><code>aria-describedby</code></dt>
            <dd>References descriptive text</dd>
            
            <dt><code>aria-expanded</code></dt>
            <dd>Indicates if collapsible element is expanded</dd>
            
            <dt><code>aria-hidden</code></dt>
            <dd>Hides decorative elements from screen readers</dd>
          </dl>
        </details>
      </section>
      
      <section aria-labelledby="newsletter">
        <h3 id="newsletter">Newsletter</h3>
        <form aria-labelledby="newsletter">
          <label for="newsletter-email" class="sr-only">Email address for newsletter</label>
          <input type="email" id="newsletter-email" placeholder="Enter your email" required>
          <button type="submit">Subscribe</button>
        </form>
      </section>
    </aside>
  </main>
  
  <!-- Site footer -->
  <footer role="contentinfo">
    <nav aria-label="Footer navigation">
      <ul>
        <li><a href="#privacy">Privacy Policy</a></li>
        <li><a href="#terms">Terms of Service</a></li>
        <li><a href="#accessibility">Accessibility Statement</a></li>
      </ul>
    </nav>
    
    <address>
      <p>Contact us: <a href="mailto:info@techlearninghub.com">info@techlearninghub.com</a></p>
    </address>
    
    <p>© 2024 Tech Learning Hub. All rights reserved.</p>
  </footer>
  
  <script>
    // Character counter for comment form
    const commentText = document.getElementById('comment-text');
    const charCount = document.getElementById('char-count');
    
    if (commentText && charCount) {
      commentText.addEventListener('input', function() {
        const count = this.value.length;
        const max = this.getAttribute('maxlength');
        charCount.textContent = `${count}/${max}`;
        
        if (count > max * 0.9) {
          charCount.style.color = '#d63384';
        } else {
          charCount.style.color = '#6c757d';
        }
      });
    }
    
    // Announce form errors to screen readers
    function announceError(message) {
      const announcement = document.createElement('div');
      announcement.setAttribute('role', 'alert');
      announcement.setAttribute('aria-live', 'assertive');
      announcement.textContent = message;
      announcement.style.position = 'absolute';
      announcement.style.left = '-9999px';
      
      document.body.appendChild(announcement);
      
      setTimeout(() => {
        document.body.removeChild(announcement);
      }, 1000);
    }
  </script>
</body>
</html>
ARIA Live Regions
Live regions announce dynamic content changes to screen readers:
html
<!-- Polite announcements (non-interrupting) -->
<div aria-live="polite" id="status-updates">
  Status messages appear here
</div>
<!-- Assertive announcements (interrupting) -->
<div aria-live="assertive" id="error-messages" role="alert">
  Error messages appear here
</div>
<!-- Atomic updates (announce entire region) -->
<div aria-live="polite" aria-atomic="true" id="weather-widget">
  <p>Temperature: 72°F</p>
  <p>Condition: Sunny</p>
</div>
<script>
  // Example of updating live regions
  function updateStatus(message) {
    document.getElementById('status-updates').textContent = message;
  }
  
  function showError(message) {
    document.getElementById('error-messages').textContent = message;
    // Clear after 5 seconds
    setTimeout(() => {
      document.getElementById('error-messages').textContent = '';
    }, 5000);
  }
</script>
Complex Widget Patterns
Accessible Tab Panel
html
<div class="tab-container">
  <div role="tablist" aria-label="Content sections">
    <button role="tab" aria-selected="true" aria-controls="panel-1" id="tab-1" tabindex="0">
      Overview
    </button>
    <button role="tab" aria-selected="false" aria-controls="panel-2" id="tab-2" tabindex="-1">
      Details
    </button>
    <button role="tab" aria-selected="false" aria-controls="panel-3" id="tab-3" tabindex="-1">
      Reviews
    </button>
  </div>
  
  <div role="tabpanel" id="panel-1" aria-labelledby="tab-1">
    <h3>Overview</h3>
    <p>Overview content goes here...</p>
  </div>
  
  <div role="tabpanel" id="panel-2" aria-labelledby="tab-2" hidden>
    <h3>Details</h3>
    <p>Detailed information goes here...</p>
  </div>
  
  <div role="tabpanel" id="panel-3" aria-labelledby="tab-3" hidden>
    <h3>Reviews</h3>
    <p>User reviews go here...</p>
  </div>
</div>
Accessible Dropdown Menu
html
<div class="dropdown">
  <button aria-haspopup="true" 
          aria-expanded="false" 
          aria-controls="dropdown-menu"
          id="menu-button">
    Menu <span aria-hidden="true">▼</span>
  </button>
  
  <ul role="menu" 
      id="dropdown-menu" 
      aria-labelledby="menu-button"
      hidden>
    <li role="none">
      <a href="#option1" role="menuitem">Option 1</a>
    </li>
    <li role="none">
      <a href="#option2" role="menuitem">Option 2</a>
    </li>
    <li role="none">
      <a href="#option3" role="menuitem">Option 3</a>
    </li>
  </ul>
</div>
Best Practices Summary
- Use semantic HTML first - Choose appropriate elements before adding ARIA
- Don't change native semantics - Avoid <button role="heading">
- Ensure keyboard accessibility - All interactive elements should be keyboard accessible
- Test with screen readers - Use NVDA, JAWS, or VoiceOver for testing
- Provide meaningful labels - Use aria-label or aria-labelledby
- Maintain focus management - Ensure logical focus order
- Use landmarks effectively - Help users navigate page structure
- Keep ARIA updated - Sync states with visual changes