CSS Focus Styles 🎯

Create accessible, beautiful focus states that work for keyboard users, screen reader users, and everyone in between. Essential for WCAG compliance and great UX.

What are Focus Styles?

Focus styles are visual indicators that show which element currently has keyboard focus. They are essential for accessibility, helping users who navigate with keyboards, switch controls, screen readers, and other assistive technologies understand where they are on the page.

♿ Accessibility

Essential for keyboard and screen reader users to navigate your site

⚖️ Legal Requirement

Required by WCAG 2.1 and various accessibility laws worldwide

🎨 UX Enhancement

Improves usability for all users, not just those with disabilities

Focus Styles Fundamentals

WCAG 2.4.7 Focus Visible:

  • Any keyboard operable user interface must have a mode of operation where the keyboard focus indicator is visible.
  • Focus indicator should have a 3:1 contrast ratio against adjacent colors
  • Should be at least 2 CSS pixels thick
  • Should not be hidden or removed without providing an alternative

Focus Fundamentals Implementation

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Focus Styles Fundamentals - CSS Focus States & Accessibility</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    body {
      font-family: 'Inter', sans-serif;
      line-height: 1.6;
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      min-height: 100vh;
      padding: 2rem;
      color: #2c3e50;
    }
    
    .container {
      max-width: 1200px;
      margin: 0 auto;
    }
    
    .header {
      text-align: center;
      margin-bottom: 3rem;
      color: white;
    }
    
    .header h1 {
      font-size: 3rem;
      margin-bottom: 1rem;
      text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
    }
    
    .principles-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));
      gap: 2rem;
      margin-bottom: 3rem;
    }
    
    .principle-card {
      background: white;
      border-radius: 15px;
      padding: 2rem;
      box-shadow: 0 10px 30px rgba(0,0,0,0.1);
    }
    
    .demo-area {
      background: white;
      border-radius: 15px;
      padding: 2rem;
      margin: 2rem 0;
      box-shadow: 0 10px 30px rgba(0,0,0,0.1);
    }
    
    .focus-demo {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
      gap: 2rem;
      margin: 2rem 0;
    }
    
    .focus-example {
      padding: 2rem;
      border: 2px solid #e2e8f0;
      border-radius: 10px;
      text-align: center;
    }
    
    .good-focus {
      border-left: 4px solid #10b981;
    }
    
    .bad-focus {
      border-left: 4px solid #ef4444;
    }
    
    .code-comparison {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 1rem;
      margin: 1rem 0;
    }
    
    .good-code, .bad-code {
      background: #2c3e50;
      color: #ecf0f1;
      padding: 1rem;
      border-radius: 5px;
      font-family: 'Fira Code', monospace;
      font-size: 0.8rem;
      line-height: 1.4;
      overflow-x: auto;
    }
    
    .comment { color: #7f8c8d; }
    .selector { color: #9b59b6; }
    .property { color: #3498db; }
    .value { color: #2ecc71; }
    
    .button-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
      gap: 1rem;
      margin: 2rem 0;
    }
    
    .btn {
      padding: 1rem 2rem;
      border: none;
      border-radius: 8px;
      font-weight: 600;
      cursor: pointer;
      transition: all 0.2s ease;
      text-align: center;
    }
    
    .btn-default {
      background: #3b82f6;
      color: white;
    }
    
    .btn-custom {
      background: #10b981;
      color: white;
    }
    
    .btn-outline {
      background: transparent;
      border: 2px solid #6366f1;
      color: #6366f1;
    }
    
    .btn-danger {
      background: #ef4444;
      color: white;
    }
    
    .btn-disabled {
      background: #9ca3af;
      color: white;
      cursor: not-allowed;
    }
    
    /* Good Focus Styles */
    .btn-default:focus {
      outline: 3px solid #1d4ed8;
      outline-offset: 2px;
      box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.2);
    }
    
    .btn-custom:focus {
      outline: none;
      box-shadow: 
        0 0 0 3px white,
        0 0 0 6px #10b981,
        0 4px 12px rgba(16, 185, 129, 0.3);
      transform: translateY(-2px);
    }
    
    .btn-outline:focus {
      outline: none;
      background: #6366f1;
      color: white;
      box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.3);
    }
    
    .btn-danger:focus {
      outline: 3px solid #dc2626;
      outline-offset: 2px;
      box-shadow: 0 4px 12px rgba(239, 68, 68, 0.3);
    }
    
    .btn-disabled:focus {
      outline: 2px dashed #6b7280;
      outline-offset: 2px;
    }
    
    /* Bad Focus Styles */
    .btn-no-focus:focus {
      outline: none;
    }
    
    .btn-weak-focus:focus {
      outline: 1px solid #3b82f6;
    }
    
    .btn-confusing-focus:focus {
      outline: none;
      background: #000;
      color: #000;
    }
    
    @media (max-width: 768px) {
      .principles-grid {
        grid-template-columns: 1fr;
      }
      
      .code-comparison {
        grid-template-columns: 1fr;
      }
      
      .header h1 {
        font-size: 2rem;
      }
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="header">
      <h1>🎯 Focus Styles</h1>
      <p>CSS Focus States & Accessibility - Making navigation visible for everyone</p>
    </div>
    
    <!-- Why Focus Styles Matter -->
    <div class="principles-grid">
      <div class="principle-card">
        <h3>♿ Why Focus Styles Matter</h3>
        <p>Focus indicators are essential for keyboard and assistive technology users.</p>
        
        <div class="demo-area">
          <div class="focus-demo">
            <div class="focus-example good-focus">
              <h4>✅ Good Focus</h4>
              <p>Clear, visible focus indicator</p>
              <button class="btn btn-default" style="margin-top: 1rem;">
                Try Me (Tab)
              </button>
            </div>
            
            <div class="focus-example bad-focus">
              <h4>❌ No Focus</h4>
              <p>Invisible to keyboard users</p>
              <button class="btn btn-default btn-no-focus" style="margin-top: 1rem;">
                Try Me (Tab)
              </button>
            </div>
          </div>
        </div>
        
        <div style="margin-top: 2rem;">
          <h4>Key Benefits:</h4>
          <ul class="list-disc pl-5 text-gray-700 space-y-2">
            <li><strong>Keyboard Accessibility:</strong> Essential for users who navigate with keyboards</li>
            <li><strong>Visual Impairments:</strong> Helps users with low vision track their position</li>
            <li><strong>Motor Disabilities:</strong> Crucial for switch control and voice input users</li>
            <li><strong>Cognitive Disabilities:</strong> Provides orientation and reduces cognitive load</li>
            <li><strong>WCAG Compliance:</strong> Required by accessibility standards (2.4.7 Focus Visible)</li>
          </ul>
        </div>
      </div>
      
      <!-- Focus Statistics -->
      <div class="principle-card">
        <h3>📊 Focus Styles Impact</h3>
        <p>Proper focus indicators affect millions of users worldwide.</p>
        
        <div class="demo-area">
          <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;">
            <div style="background: #10b981; color: white; padding: 1.5rem; border-radius: 8px; text-align: center;">
              <div style="font-size: 2rem; font-weight: bold;">15%</div>
              <div style="font-size: 0.9rem;">Users rely on keyboard navigation</div>
            </div>
            
            <div style="background: #3b82f6; color: white; padding: 1.5rem; border-radius: 8px; text-align: center;">
              <div style="font-size: 2rem; font-weight: bold;">2.2B</div>
              <div style="font-size: 0.9rem;">People with vision impairments</div>
            </div>
            
            <div style="background: #8b5cf6; color: white; padding: 1.5rem; border-radius: 8px; text-align: center;">
              <div style="font-size: 2rem; font-weight: bold;">71%</div>
              <div style="font-size: 0.9rem;">Leave sites with poor accessibility</div>
            </div>
            
            <div style="background: #f59e0b; color: white; padding: 1.5rem; border-radius: 8px; text-align: center;">
              <div style="font-size: 2rem; font-weight: bold;">100%</div>
              <div style="font-size: 0.9rem;">WCAG 2.1 requires focus indicators</div>
            </div>
          </div>
        </div>
        
        <div class="demo-area">
          <h4>Legal Requirements</h4>
          <ul class="list-disc pl-5 text-gray-700 space-y-1">
            <li><strong>WCAG 2.1 Success Criterion 2.4.7:</strong> Focus must be visible</li>
            <li><strong>ADA Title III:</strong> Requires accessible web experiences</li>
            <li><strong>Section 508:</strong> Federal websites must be accessible</li>
            <li><strong>EU Web Accessibility Directive:</strong> Mandatory for public sector</li>
          </ul>
        </div>
      </div>
    </div>
    
    <!-- Basic Focus Styles -->
    <div class="principle-card">
      <h3>🎨 Basic Focus Styles</h3>
      <p>Fundamental CSS properties for creating accessible focus indicators.</p>
      
      <div class="code-comparison">
        <div class="good-code">
          <span class="comment">/* Good: Clear, visible focus */</span><br>
          <span class="selector">button</span>:focus {<br>
          &nbsp;&nbsp;<span class="property">outline</span>: <span class="value">3px solid #3b82f6</span>;<br>
          &nbsp;&nbsp;<span class="property">outline-offset</span>: <span class="value">2px</span>;<br>
          &nbsp;&nbsp;<span class="property">box-shadow</span>: <span class="value">0 0 0 4px rgba(59, 130, 246, 0.2)</span>;<br>
          }<br><br>
          <span class="selector">.custom-btn</span>:focus {<br>
          &nbsp;&nbsp;<span class="property">outline</span>: <span class="value">none</span>;<br>
          &nbsp;&nbsp;<span class="property">box-shadow</span>: <span class="value">0 0 0 3px white, 0 0 0 6px #10b981</span>;<br>
          &nbsp;&nbsp;<span class="property">transform</span>: <span class="value">translateY(-2px)</span>;<br>
          }
        </div>
        
        <div class="bad-code">
          <span class="comment">/* Bad: Poor or no focus */</span><br>
          <span class="selector">button</span>:focus {<br>
          &nbsp;&nbsp;<span class="property">outline</span>: <span class="value">none</span>;<br>
          &nbsp;&nbsp;<span class="comment">/* No visible focus indicator */</span><br>
          }<br><br>
          <span class="selector">.btn-weak</span>:focus {<br>
          &nbsp;&nbsp;<span class="property">outline</span>: <span class="value">1px solid #3b82f6</span>;<br>
          &nbsp;&nbsp;<span class="comment">/* Too subtle to see */</span><br>
          }<br><br>
          <span class="selector">.btn-confusing</span>:focus {<br>
          &nbsp;&nbsp;<span class="property">outline</span>: <span class="value">none</span>;<br>
          &nbsp;&nbsp;<span class="property">background</span>: <span class="value">#000</span>;<br>
          &nbsp;&nbsp;<span class="property">color</span>: <span class="value">#000</span>;<br>
          &nbsp;&nbsp;<span class="comment">/* Makes text invisible */</span><br>
          }
        </div>
      </div>
      
      <div class="button-grid">
        <button class="btn btn-default">
          Default Focus
        </button>
        
        <button class="btn btn-custom">
          Custom Focus
        </button>
        
        <button class="btn btn-outline">
          Outline Focus
        </button>
        
        <button class="btn btn-danger">
          Danger Focus
        </button>
        
        <button class="btn btn-disabled" disabled>
          Disabled State
        </button>
        
        <button class="btn btn-default btn-no-focus">
          No Focus
        </button>
      </div>
    </div>
    
    <!-- Focus States for Different Elements -->
    <div class="principle-card">
      <h3>🔧 Focus for Various Elements</h3>
      <p>Different HTML elements require different focus strategies.</p>
      
      <div class="demo-area">
        <div style="display: grid; gap: 1.5rem;">
          <div>
            <label for="input1" style="display: block; margin-bottom: 0.5rem; font-weight: 600;">Input with Good Focus</label>
            <input type="text" id="input1" placeholder="Try tabbing to me" 
                   style="width: 100%; padding: 1rem; border: 2px solid #e2e8f0; border-radius: 8px; font-size: 1rem;">
            <style>
              #input1:focus {
                outline: none;
                border-color: #3b82f6;
                box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2);
              }
            </style>
          </div>
          
          <div>
            <label for="select1" style="display: block; margin-bottom: 0.5rem; font-weight: 600;">Select with Focus</label>
            <select id="select1" style="width: 100%; padding: 1rem; border: 2px solid #e2e8f0; border-radius: 8px; font-size: 1rem;">
              <option>Option 1</option>
              <option>Option 2</option>
              <option>Option 3</option>
            </select>
            <style>
              #select1:focus {
                outline: none;
                border-color: #10b981;
                box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.2);
              }
            </style>
          </div>
          
          <div>
            <label style="display: block; margin-bottom: 0.5rem; font-weight: 600;">Checkbox Group</label>
            <div style="display: flex; gap: 2rem; flex-wrap: wrap;">
              <label style="display: flex; align-items: center; gap: 0.5rem;">
                <input type="checkbox" class="custom-checkbox">
                Option 1
              </label>
              <label style="display: flex; align-items: center; gap: 0.5rem;">
                <input type="checkbox" class="custom-checkbox">
                Option 2
              </label>
              <label style="display: flex; align-items: center; gap: 0.5rem;">
                <input type="checkbox" class="custom-checkbox">
                Option 3
              </label>
            </div>
            <style>
              .custom-checkbox {
                width: 20px;
                height: 20px;
              }
              .custom-checkbox:focus {
                outline: 3px solid #8b5cf6;
                outline-offset: 2px;
                border-radius: 4px;
              }
            </style>
          </div>
        </div>
      </div>
    </div>
    
    <!-- Focus Management -->
    <div class="principle-card">
      <h3>🎯 Focus Management</h3>
      <p>Controlling focus behavior for complex interactions and accessibility.</p>
      
      <div class="code-comparison">
        <div class="good-code">
          <span class="comment">/* Programmatic Focus Management */</span><br>
          <span class="comment">// Open modal</span><br>
          <span class="selector">function openModal()</span> {<br>
          &nbsp;&nbsp;<span class="property">modal</span>.showModal();<br>
          &nbsp;&nbsp;<span class="property">modal</span>.querySelector(<span class="value">'button'</span>).focus();<br>
          }<br><br>
          <span class="comment">// Close modal</span><br>
          <span class="selector">function closeModal()</span> {<br>
          &nbsp;&nbsp;<span class="property">modal</span>.close();<br>
          &nbsp;&nbsp;<span class="property">triggerButton</span>.focus();<br>
          }<br><br>
          <span class="comment">// Trap focus in modal</span><br>
          <span class="selector">modal</span>.addEventListener(<span class="value">'keydown'</span>, (e) => {<br>
          &nbsp;&nbsp;if (e.key === <span class="value">'Tab'</span>) {<br>
          &nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">// Implement focus trap</span><br>
          &nbsp;&nbsp;}<br>
          });
        </div>
        
        <div class="bad-code">
          <span class="comment">/* Poor Focus Management */</span><br>
          <span class="comment">// Opening modal without focus</span><br>
          <span class="selector">function openModal()</span> {<br>
          &nbsp;&nbsp;<span class="property">modal</span>.showModal();<br>
          &nbsp;&nbsp;<span class="comment">// No focus management</span><br>
          }<br><br>
          <span class="comment">// Closing modal loses focus</span><br>
          <span class="selector">function closeModal()</span> {<br>
          &nbsp;&nbsp;<span class="property">modal</span>.close();<br>
          &nbsp;&nbsp;<span class="comment">// Focus goes to body</span><br>
          }<br><br>
          <span class="comment">// No focus trapping</span><br>
          <span class="comment">// User can tab out of modal</span>
        </div>
      </div>
    </div>
  </div>
</body>
</html>

Advanced Focus Techniques

🎯 :focus-visible

Show focus rings only when needed (keyboard navigation) and hide them for mouse users. Prevents unnecessary visual noise while maintaining accessibility.

button:focus { outline: none; }
button:focus-visible { outline: 2px solid blue; }

🎪 :focus-within

Style parent elements when any child receives focus. Perfect for form groups, cards, and other container elements that need to indicate active state.

.form-group:focus-within {
  border-color: blue;
  box-shadow: 0 0 0 3px lightblue;
}

Advanced Focus Techniques Implementation

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Advanced Focus Techniques - CSS Focus Strategies & Patterns</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    body {
      font-family: 'Inter', sans-serif;
      line-height: 1.6;
      background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
      min-height: 100vh;
      padding: 2rem;
      color: #2c3e50;
    }
    
    .container {
      max-width: 1200px;
      margin: 0 auto;
    }
    
    .header {
      text-align: center;
      margin-bottom: 3rem;
      color: white;
    }
    
    .header h1 {
      font-size: 3rem;
      margin-bottom: 1rem;
      text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
    }
    
    .tech-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));
      gap: 2rem;
      margin-bottom: 3rem;
    }
    
    .tech-card {
      background: white;
      border-radius: 15px;
      padding: 2rem;
      box-shadow: 0 10px 30px rgba(0,0,0,0.1);
    }
    
    .demo-area {
      background: white;
      border-radius: 15px;
      padding: 2rem;
      margin: 2rem 0;
      box-shadow: 0 10px 30px rgba(0,0,0,0.1);
    }
    
    .focus-techniques {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
      gap: 2rem;
      margin: 2rem 0;
    }
    
    .technique {
      padding: 2rem;
      border: 2px solid #e2e8f0;
      border-radius: 10px;
      text-align: center;
    }
    
    .code-block {
      background: #2c3e50;
      color: #ecf0f1;
      padding: 1.5rem;
      border-radius: 8px;
      font-family: 'Fira Code', monospace;
      font-size: 0.9rem;
      margin: 1rem 0;
      overflow-x: auto;
    }
    
    .interactive-demo {
      background: #f8f9fa;
      padding: 2rem;
      border-radius: 10px;
      margin: 2rem 0;
    }
    
    .custom-components {
      display: grid;
      gap: 1.5rem;
      margin: 2rem 0;
    }
    
    .custom-btn {
      padding: 1rem 2rem;
      border: none;
      border-radius: 8px;
      font-weight: 600;
      cursor: pointer;
      transition: all 0.3s ease;
    }
    
    .card {
      background: white;
      padding: 2rem;
      border-radius: 12px;
      box-shadow: 0 4px 6px rgba(0,0,0,0.1);
      border: 2px solid transparent;
    }
    
    .tab-list {
      display: flex;
      gap: 0.5rem;
      margin-bottom: 1rem;
    }
    
    .tab {
      padding: 1rem 2rem;
      background: #f8f9fa;
      border: none;
      border-radius: 8px 8px 0 0;
      cursor: pointer;
    }
    
    @media (max-width: 768px) {
      .tech-grid {
        grid-template-columns: 1fr;
      }
      
      .focus-techniques {
        grid-template-columns: 1fr;
      }
      
      .header h1 {
        font-size: 2rem;
      }
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="header">
      <h1>⚡ Advanced Focus Techniques</h1>
      <p>Advanced CSS focus strategies, focus traps, and custom component focus</p>
    </div>
    
    <!-- Focus Visible Pseudoclass -->
    <div class="tech-grid">
      <div class="tech-card">
        <h3>🎯 :focus-visible Pseudoclass</h3>
        <p>Show focus rings only when needed (keyboard navigation vs mouse clicks).</p>
        
        <div class="code-block">
          <span style="color: #7f8c8d;">/* Only show focus for keyboard navigation */</span><br>
          <span style="color: #9b59b6;">.custom-element</span>:focus {<br>
          &nbsp;&nbsp;<span style="color: #3498db;">outline</span>: <span style="color: #2ecc71;">none</span>;<br>
          }<br><br>
          <span style="color: #9b59b6;">.custom-element</span>:focus-visible {<br>
          &nbsp;&nbsp;<span style="color: #3498db;">outline</span>: <span style="color: #2ecc71;">3px solid #3b82f6</span>;<br>
          &nbsp;&nbsp;<span style="color: #3498db;">outline-offset</span>: <span style="color: #2ecc71;">2px</span>;<br>
          &nbsp;&nbsp;<span style="color: #3498db;">box-shadow</span>: <span style="color: #2ecc71;">0 0 0 4px rgba(59, 130, 246, 0.2)</span>;<br>
          }
        </div>
        
        <div class="interactive-demo">
          <h4>Try it:</h4>
          <p>Click with mouse vs tab with keyboard</p>
          <button class="custom-btn" style="background: #3b82f6; color: white; margin: 1rem;">
            focus-visible Button
          </button>
          <style>
            .custom-btn:focus {
              outline: none;
            }
            .custom-btn:focus-visible {
              outline: 3px solid #1d4ed8;
              outline-offset: 2px;
              box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.2);
            }
          </style>
        </div>
      </div>
      
      <!-- Focus Within -->
      <div class="tech-card">
        <h3>🎪 :focus-within Pseudoclass</h3>
        <p>Style parent elements when any child receives focus.</p>
        
        <div class="code-block">
          <span style="color: #7f8c8d;">/* Style form when any input focused */</span><br>
          <span style="color: #9b59b6;">.form-group</span>:focus-within {<br>
          &nbsp;&nbsp;<span style="color: #3498db;">border-color</span>: <span style="color: #2ecc71;">#3b82f6</span>;<br>
          &nbsp;&nbsp;<span style="color: #3498db;">box-shadow</span>: <span style="color: #2ecc71;">0 0 0 3px rgba(59, 130, 246, 0.1)</span>;<br>
          &nbsp;&nbsp;<span style="color: #3498db;">transform</span>: <span style="color: #2ecc71;">translateY(-2px)</span>;<br>
          }
        </div>
        
        <div class="interactive-demo">
          <h4>Form with focus-within:</h4>
          <div class="form-group" style="border: 2px solid #e2e8f0; padding: 2rem; border-radius: 8px; transition: all 0.3s ease;">
            <label style="display: block; margin-bottom: 0.5rem; font-weight: 600;">Email</label>
            <input type="email" placeholder="Focus me to see effect" 
                   style="width: 100%; padding: 1rem; border: 2px solid #e2e8f0; border-radius: 4px;">
          </div>
          <style>
            .form-group:focus-within {
              border-color: #3b82f6;
              box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
              transform: translateY(-2px);
            }
          </style>
        </div>
      </div>
    </div>
    
    <!-- Custom Component Focus -->
    <div class="tech-card">
      <h3>🏗️ Custom Component Focus</h3>
      <p>Advanced focus patterns for complex components and design systems.</p>
      
      <div class="custom-components">
        <!-- Card with Focus -->
        <div class="card" tabindex="0">
          <h4>Focusable Card</h4>
          <p>This entire card is focusable. Great for product cards or interactive containers.</p>
          <button class="custom-btn" style="background: #10b981; color: white; margin-top: 1rem;">
            Action Button
          </button>
        </div>
        
        <!-- Tabs with Focus -->
        <div>
          <div class="tab-list">
            <button class="tab" style="background: #3b82f6; color: white;">Tab 1</button>
            <button class="tab">Tab 2</button>
            <button class="tab">Tab 3</button>
          </div>
          <div style="background: white; padding: 2rem; border-radius: 0 8px 8px 8px;">
            Tab content area
          </div>
        </div>
      </div>
      
      <style>
        .card:focus {
          outline: none;
          border-color: #3b82f6;
          box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2),
                      0 8px 25px rgba(0,0,0,0.1);
        }
        
        .tab:focus {
          outline: none;
          background: #3b82f6;
          color: white;
          box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.3);
        }
      </style>
    </div>
    
    <!-- Focus Trap Demo -->
    <div class="tech-card">
      <h3>🚫 Focus Trapping</h3>
      <p>Containing focus within modal dialogs and other overlay components.</p>
      
      <div class="code-block">
        <span style="color: #7f8c8d;">// Simple focus trap implementation</span><br>
        <span style="color: #9b59b6;">function</span> <span style="color: #3498db;">trapFocus</span>(element) {<br>
        &nbsp;&nbsp;<span style="color: #9b59b6;">const</span> focusableElements = element.<span style="color: #3498db;">querySelectorAll</span>(<br>
        &nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #2ecc71;">'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'</span><br>
        &nbsp;&nbsp;);<br>
        &nbsp;&nbsp;<span style="color: #9b59b6;">const</span> firstElement = focusableElements[<span style="color: #e74c3c;">0</span>];<br>
        &nbsp;&nbsp;<span style="color: #9b59b6;">const</span> lastElement = focusableElements[focusableElements.<span style="color: #3498db;">length</span> - <span style="color: #e74c3c;">1</span>];<br>
        <br>
        &nbsp;&nbsp;element.<span style="color: #3498db;">addEventListener</span>(<span style="color: #2ecc71;">'keydown'</span>, (e) => {<br>
        &nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #9b59b6;">if</span> (e.key === <span style="color: #2ecc71;">'Tab'</span>) {<br>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #9b59b6;">if</span> (e.shiftKey) {<br>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #9b59b6;">if</span> (document.activeElement === firstElement) {<br>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lastElement.<span style="color: #3498db;">focus</span>();<br>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.<span style="color: #3498db;">preventDefault</span>();<br>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <span style="color: #9b59b6;">else</span> {<br>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #9b59b6;">if</span> (document.activeElement === lastElement) {<br>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;firstElement.<span style="color: #3498db;">focus</span>();<br>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.<span style="color: #3498db;">preventDefault</span>();<br>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
        &nbsp;&nbsp;&nbsp;&nbsp;}<br>
        &nbsp;&nbsp;});<br>
        }
      </div>
    </div>
    
    <!-- High Contrast Mode -->
    <div class="tech-card">
      <h3>🌓 High Contrast Mode Support</h3>
      <p>Ensuring focus indicators work in Windows High Contrast Mode and other accessibility modes.</p>
      
      <div class="focus-techniques">
        <div class="technique">
          <h4>Forced Colors Mode</h4>
          <div class="code-block">
            @media (forced-colors: active) {<br>
            &nbsp;&nbsp;.btn:focus {<br>
            &nbsp;&nbsp;&nbsp;&nbsp;outline: 2px solid;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;outline-offset: 2px;<br>
            &nbsp;&nbsp;}<br>
            }
          </div>
        </div>
        
        <div class="technique">
          <h4>Border + Outline</h4>
          <div class="code-block">
            .btn:focus {<br>
            &nbsp;&nbsp;outline: 2px solid #3b82f6;<br>
            &nbsp;&nbsp;border: 2px solid transparent;<br>
            }<br>
            @media (forced-colors: active) {<br>
            &nbsp;&nbsp;.btn:focus {<br>
            &nbsp;&nbsp;&nbsp;&nbsp;border-color: currentColor;<br>
            &nbsp;&nbsp;}<br>
            }
          </div>
        </div>
      </div>
    </div>
  </div>
</body>
</html>

Focus Patterns & Examples

🎨 Real-World Focus Patterns

Implement consistent, accessible focus patterns across different UI components including navigation, forms, buttons, and interactive cards.

// Navigation focus
nav a:focus { outline: 3px solid blue; outline-offset: 2px; }
// Form focus
input:focus { border-color: blue; box-shadow: 0 0 0 3px lightblue; }
// Button focus
button:focus { outline: 2px solid; outline-offset: 2px; }

Focus Patterns & Examples Implementation

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Focus Patterns & Examples - Real World Focus Implementations</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    body {
      font-family: 'Inter', sans-serif;
      line-height: 1.6;
      background: linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%);
      min-height: 100vh;
      padding: 2rem;
      color: #2c3e50;
    }
    
    .container {
      max-width: 1200px;
      margin: 0 auto;
    }
    
    .header {
      text-align: center;
      margin-bottom: 3rem;
    }
    
    .header h1 {
      font-size: 3rem;
      margin-bottom: 1rem;
      color: #2c3e50;
    }
    
    .patterns-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
      gap: 2rem;
      margin-bottom: 3rem;
    }
    
    .pattern-card {
      background: white;
      border-radius: 15px;
      padding: 2rem;
      box-shadow: 0 10px 30px rgba(0,0,0,0.1);
    }
    
    .demo-area {
      background: white;
      border-radius: 15px;
      padding: 2rem;
      margin: 2rem 0;
      box-shadow: 0 10px 30px rgba(0,0,0,0.1);
    }
    
    .component-demo {
      background: #f8f9fa;
      padding: 2rem;
      border-radius: 10px;
      margin: 1rem 0;
    }
    
    .nav-demo {
      display: flex;
      gap: 1rem;
      flex-wrap: wrap;
      margin: 1rem 0;
    }
    
    .nav-item {
      padding: 1rem 2rem;
      background: #3b82f6;
      color: white;
      text-decoration: none;
      border-radius: 8px;
      font-weight: 600;
      transition: all 0.2s ease;
    }
    
    .form-demo {
      display: grid;
      gap: 1.5rem;
      max-width: 500px;
    }
    
    .form-group {
      display: flex;
      flex-direction: column;
      gap: 0.5rem;
    }
    
    .form-input {
      padding: 1rem;
      border: 2px solid #e2e8f0;
      border-radius: 8px;
      font-size: 1rem;
    }
    
    .button-group {
      display: flex;
      gap: 1rem;
      flex-wrap: wrap;
      margin: 1rem 0;
    }
    
    .btn-pattern {
      padding: 1rem 2rem;
      border: none;
      border-radius: 8px;
      font-weight: 600;
      cursor: pointer;
      transition: all 0.2s ease;
    }
    
    .card-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
      gap: 1.5rem;
      margin: 2rem 0;
    }
    
    .product-card {
      background: white;
      padding: 1.5rem;
      border-radius: 12px;
      box-shadow: 0 4px 6px rgba(0,0,0,0.1);
      border: 2px solid transparent;
    }
    
    .code-example {
      background: #2c3e50;
      color: #ecf0f1;
      padding: 1.5rem;
      border-radius: 8px;
      font-family: 'Fira Code', monospace;
      font-size: 0.9rem;
      margin: 1rem 0;
      overflow-x: auto;
    }
    
    @media (max-width: 768px) {
      .patterns-grid {
        grid-template-columns: 1fr;
      }
      
      .header h1 {
        font-size: 2rem;
      }
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="header">
      <h1>🎨 Focus Patterns & Examples</h1>
      <p>Real-world focus implementations for common UI components and patterns</p>
    </div>
    
    <!-- Navigation Focus -->
    <div class="patterns-grid">
      <div class="pattern-card">
        <h3>🧭 Navigation Focus</h3>
        <p>Accessible navigation menus with clear focus indicators.</p>
        
        <div class="component-demo">
          <nav class="nav-demo">
            <a href="#" class="nav-item">Home</a>
            <a href="#" class="nav-item">Products</a>
            <a href="#" class="nav-item">Services</a>
            <a href="#" class="nav-item">About</a>
            <a href="#" class="nav-item">Contact</a>
          </nav>
        </div>
        
        <div class="code-example">
          <span style="color: #7f8c8d;">/* Navigation focus styles */</span><br>
          <span style="color: #9b59b6;">.nav-item</span>:focus {<br>
          &nbsp;&nbsp;<span style="color: #3498db;">outline</span>: <span style="color: #2ecc71;">none</span>;<br>
          &nbsp;&nbsp;<span style="color: #3498db;">background</span>: <span style="color: #2ecc71;">#1d4ed8</span>;<br>
          &nbsp;&nbsp;<span style="color: #3498db;">box-shadow</span>: <span style="color: #2ecc71;">0 0 0 3px white, 0 0 0 6px #3b82f6</span>;<br>
          &nbsp;&nbsp;<span style="color: #3498db;">transform</span>: <span style="color: #2ecc71;">translateY(-2px)</span>;<br>
          }
        </div>
      </div>
      
      <!-- Form Focus -->
      <div class="pattern-card">
        <h3>📝 Form Focus</h3>
        <p>Accessible form controls with clear focus states.</p>
        
        <div class="component-demo">
          <form class="form-demo">
            <div class="form-group">
              <label for="name">Full Name</label>
              <input type="text" id="name" class="form-input" placeholder="Enter your name">
            </div>
            
            <div class="form-group">
              <label for="email">Email Address</label>
              <input type="email" id="email" class="form-input" placeholder="Enter your email">
            </div>
            
            <div class="form-group">
              <label for="message">Message</label>
              <textarea id="message" class="form-input" placeholder="Enter your message" rows="4"></textarea>
            </div>
            
            <button type="submit" class="btn-pattern" style="background: #10b981; color: white;">
              Submit Form
            </button>
          </form>
        </div>
        
        <div class="code-example">
          <span style="color: #7f8c8d;">/* Form focus styles */</span><br>
          <span style="color: #9b59b6;">.form-input</span>:focus {<br>
          &nbsp;&nbsp;<span style="color: #3498db;">outline</span>: <span style="color: #2ecc71;">none</span>;<br>
          &nbsp;&nbsp;<span style="color: #3498db;">border-color</span>: <span style="color: #2ecc71;">#10b981</span>;<br>
          &nbsp;&nbsp;<span style="color: #3498db;">box-shadow</span>: <span style="color: #2ecc71;">0 0 0 3px rgba(16, 185, 129, 0.2)</span>;<br>
          }<br>
          <span style="color: #9b59b6;">.btn-pattern</span>:focus {<br>
          &nbsp;&nbsp;<span style="color: #3498db;">outline</span>: <span style="color: #2ecc71;">3px solid #047857</span>;<br>
          &nbsp;&nbsp;<span style="color: #3498db;">outline-offset</span>: <span style="color: #2ecc71;">2px</span>;<br>
          }
        </div>
      </div>
    </div>
    
    <!-- Button Variants -->
    <div class="pattern-card">
      <h3>🔘 Button Focus Variants</h3>
      <p>Different focus styles for various button types and states.</p>
      
      <div class="component-demo">
        <div class="button-group">
          <button class="btn-pattern" style="background: #3b82f6; color: white;">
            Primary
          </button>
          <button class="btn-pattern" style="background: #6b7280; color: white;">
            Secondary
          </button>
          <button class="btn-pattern" style="background: transparent; border: 2px solid #3b82f6; color: #3b82f6;">
            Outline
          </button>
          <button class="btn-pattern" style="background: #ef4444; color: white;">
            Danger
          </button>
          <button class="btn-pattern" style="background: #f59e0b; color: white;">
            Warning
          </button>
        </div>
      </div>
      
      <div class="code-example">
        <span style="color: #7f8c8d;">/* Button focus variants */</span><br>
        <span style="color: #9b59b6;">.btn-primary</span>:focus {<br>
        &nbsp;&nbsp;<span style="color: #3498db;">outline</span>: <span style="color: #2ecc71;">3px solid #1d4ed8</span>;<br>
        &nbsp;&nbsp;<span style="color: #3498db;">outline-offset</span>: <span style="color: #2ecc71;">2px</span>;<br>
        }<br>
        <span style="color: #9b59b6;">.btn-outline</span>:focus {<br>
        &nbsp;&nbsp;<span style="color: #3498db;">outline</span>: <span style="color: #2ecc71;">none</span>;<br>
        &nbsp;&nbsp;<span style="color: #3498db;">background</span>: <span style="color: #2ecc71;">#3b82f6</span>;<br>
        &nbsp;&nbsp;<span style="color: #3498db;">color</span>: <span style="color: #2ecc71;">white</span>;<br>
        &nbsp;&nbsp;<span style="color: #3498db;">box-shadow</span>: <span style="color: #2ecc71;">0 0 0 3px rgba(59, 130, 246, 0.3)</span>;<br>
        }<br>
        <span style="color: #9b59b6;">.btn-danger</span>:focus {<br>
        &nbsp;&nbsp;<span style="color: #3498db;">outline</span>: <span style="color: #2ecc71;">3px solid #dc2626</span>;<br>
        &nbsp;&nbsp;<span style="color: #3498db;">outline-offset</span>: <span style="color: #2ecc71;">2px</span>;<br>
        &nbsp;&nbsp;<span style="color: #3498db;">box-shadow</span>: <span style="color: #2ecc71;">0 4px 12px rgba(239, 68, 68, 0.3)</span>;<br>
        }
      </div>
    </div>
    
    <!-- Product Cards -->
    <div class="pattern-card">
      <h3>🛍️ Product Card Focus</h3>
      <p>Focusable product cards with interactive elements.</p>
      
      <div class="card-grid">
        <div class="product-card" tabindex="0">
          <h4>Premium Headphones</h4>
          <p style="color: #6b7280; margin: 0.5rem 0;">Noise-cancelling wireless headphones</p>
          <div style="font-size: 1.5rem; font-weight: bold; color: #10b981; margin: 1rem 0;">$299</div>
          <button class="btn-pattern" style="background: #3b82f6; color: white; width: 100%;">
            Add to Cart
          </button>
        </div>
        
        <div class="product-card" tabindex="0">
          <h4>Smart Watch</h4>
          <p style="color: #6b7280; margin: 0.5rem 0;">Fitness tracking and notifications</p>
          <div style="font-size: 1.5rem; font-weight: bold; color: #10b981; margin: 1rem 0;">$199</div>
          <button class="btn-pattern" style="background: #3b82f6; color: white; width: 100%;">
            Add to Cart
          </button>
        </div>
        
        <div class="product-card" tabindex="0">
          <h4>Wireless Earbuds</h4>
          <p style="color: #6b7280; margin: 0.5rem 0;">Compact and powerful sound</p>
          <div style="font-size: 1.5rem; font-weight: bold; color: #10b981; margin: 1rem 0;">$149</div>
          <button class="btn-pattern" style="background: #3b82f6; color: white; width: 100%;">
            Add to Cart
          </button>
        </div>
      </div>
      
      <div class="code-example">
        <span style="color: #7f8c8d;">/* Product card focus */</span><br>
        <span style="color: #9b59b6;">.product-card</span>:focus {<br>
        &nbsp;&nbsp;<span style="color: #3498db;">outline</span>: <span style="color: #2ecc71;">none</span>;<br>
        &nbsp;&nbsp;<span style="color: #3498db;">border-color</span>: <span style="color: #2ecc71;">#3b82f6</span>;<br>
        &nbsp;&nbsp;<span style="color: #3498db;">box-shadow</span>: <span style="color: #2ecc71;">0 0 0 3px rgba(59, 130, 246, 0.2)</span>;<br>
        &nbsp;&nbsp;<span style="color: #3498db;">transform</span>: <span style="color: #2ecc71;">translateY(-4px)</span>;<br>
        }<br>
        <span style="color: #9b59b6;">.product-card</span> <span style="color: #9b59b6;">button</span>:focus {<br>
        &nbsp;&nbsp;<span style="color: #3498db;">outline</span>: <span style="color: #2ecc71;">2px solid white</span>;<br>
        &nbsp;&nbsp;<span style="color: #3498db;">outline-offset</span>: <span style="color: #2ecc71;">-2px</span>;<br>
        }
      </div>
      
      <style>
        .product-card:focus {
          outline: none;
          border-color: #3b82f6;
          box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2);
          transform: translateY(-4px);
        }
        .product-card button:focus {
          outline: 2px solid white;
          outline-offset: -2px;
        }
        .nav-item:focus {
          outline: none;
          background: #1d4ed8;
          box-shadow: 0 0 0 3px white, 0 0 0 6px #3b82f6;
          transform: translateY(-2px);
        }
        .form-input:focus {
          outline: none;
          border-color: #10b981;
          box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.2);
        }
        .btn-pattern:focus {
          outline: 3px solid;
          outline-offset: 2px;
        }
        .btn-pattern[style*="background: #3b82f6"]:focus {
          outline-color: #1d4ed8;
        }
        .btn-pattern[style*="background: #6b7280"]:focus {
          outline-color: #4b5563;
        }
        .btn-pattern[style*="background: #ef4444"]:focus {
          outline-color: #dc2626;
        }
        .btn-pattern[style*="background: #f59e0b"]:focus {
          outline-color: #d97706;
        }
        .btn-pattern[style*="border: 2px solid #3b82f6"]:focus {
          outline: none;
          background: #3b82f6;
          color: white;
          box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.3);
        }
      </style>
    </div>
  </div>
</body>
</html>

Focus Testing & Tools

⌨️ Keyboard Testing

Test your site using only keyboard navigation - no mouse allowed!

🔍 DevTools

Use browser developer tools to inspect focus states and accessibility

🤖 Automated Testing

Integrate focus testing into your CI/CD pipeline with tools like axe-core

Focus Testing & Tools Implementation

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Focus Testing & Tools - Accessibility Testing for Focus States</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    body {
      font-family: 'Inter', sans-serif;
      line-height: 1.6;
      background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
      min-height: 100vh;
      padding: 2rem;
      color: #2c3e50;
    }
    
    .container {
      max-width: 1200px;
      margin: 0 auto;
    }
    
    .header {
      text-align: center;
      margin-bottom: 3rem;
    }
    
    .header h1 {
      font-size: 3rem;
      margin-bottom: 1rem;
      color: #2c3e50;
    }
    
    .testing-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
      gap: 2rem;
      margin-bottom: 3rem;
    }
    
    .testing-card {
      background: white;
      border-radius: 15px;
      padding: 2rem;
      box-shadow: 0 10px 30px rgba(0,0,0,0.1);
    }
    
    .checklist {
      background: #f8f9fa;
      padding: 2rem;
      border-radius: 10px;
      margin: 1rem 0;
    }
    
    .checklist-item {
      display: flex;
      align-items: center;
      gap: 1rem;
      margin: 0.5rem 0;
      padding: 0.5rem;
    }
    
    .tool-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
      gap: 1.5rem;
      margin: 2rem 0;
    }
    
    .tool-card {
      background: #e8f4fd;
      padding: 1.5rem;
      border-radius: 10px;
      text-align: center;
      border-left: 4px solid #3498db;
    }
    
    .browser-demo {
      background: #2c3e50;
      color: #ecf0f1;
      padding: 1.5rem;
      border-radius: 8px;
      font-family: 'Fira Code', monospace;
      margin: 1rem 0;
    }
    
    .testing-demo {
      background: #fff3cd;
      border-left: 4px solid #ffc107;
      padding: 1.5rem;
      margin: 1rem 0;
      border-radius: 5px;
    }
    
    .keyboard-test {
      background: #d4edda;
      border-left: 4px solid #28a745;
      padding: 1.5rem;
      margin: 1rem 0;
      border-radius: 5px;
    }
    
    @media (max-width: 768px) {
      .testing-grid {
        grid-template-columns: 1fr;
      }
      
      .header h1 {
        font-size: 2rem;
      }
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="header">
      <h1>🔧 Focus Testing & Tools</h1>
      <p>Comprehensive testing strategies and tools for focus state accessibility</p>
    </div>
    
    <!-- Testing Checklist -->
    <div class="testing-grid">
      <div class="testing-card">
        <h3>✅ Focus Testing Checklist</h3>
        <p>Essential tests to ensure your focus states are accessible.</p>
        
        <div class="checklist">
          <div class="checklist-item">
            <span style="color: #10b981; font-weight: bold;">✓</span>
            <span>All interactive elements are focusable</span>
          </div>
          
          <div class="checklist-item">
            <span style="color: #10b981; font-weight: bold;">✓</span>
            <span>Focus order follows visual layout</span>
          </div>
          
          <div class="checklist-item">
            <span style="color: #10b981; font-weight: bold;">✓</span>
            <span>Focus indicators are clearly visible</span>
          </div>
          
          <div class="checklist-item">
            <span style="color: #10b981; font-weight: bold;">✓</span>
            <span>No focus traps except in modals</span>
          </div>
          
          <div class="checklist-item">
            <span style="color: #10b981; font-weight: bold;">✓</span>
            <span>Focus works in high contrast mode</span>
          </div>
          
          <div class="checklist-item">
            <span style="color: #10b981; font-weight: bold;">✓</span>
            <span>Skip links are available and functional</span>
          </div>
          
          <div class="checklist-item">
            <span style="color: #10b981; font-weight: bold;">✓</span>
            <span>Focus doesn't get lost in single-page apps</span>
          </div>
          
          <div class="checklist-item">
            <span style="color: #10b981; font-weight: bold;">✓</span>
            <span>Custom components have proper focus</span>
          </div>
        </div>
      </div>
      
      <!-- Testing Tools -->
      <div class="testing-card">
        <h3>🛠️ Focus Testing Tools</h3>
        <p>Essential tools for testing focus accessibility.</p>
        
        <div class="tool-grid">
          <div class="tool-card">
            <h4>Browser DevTools</h4>
            <p>Accessibility panels and focus debugging</p>
          </div>
          
          <div class="tool-card">
            <h4>axe DevTools</h4>
            <p>Automated accessibility testing</p>
          </div>
          
          <div class="tool-card">
            <h4>Lighthouse</h4>
            <p>Accessibility audits and scoring</p>
          </div>
          
          <div class="tool-card">
            <h4>WAVE</h4>
            <p>Web accessibility evaluation</p>
          </div>
          
          <div class="tool-card">
            <h4>NVDA</h4>
            <p>Screen reader for Windows testing</p>
          </div>
          
          <div class="tool-card">
            <h4>VoiceOver</h4>
            <p>Built-in macOS screen reader</p>
          </div>
        </div>
      </div>
    </div>
    
    <!-- Browser DevTools Demo -->
    <div class="testing-card">
      <h3>🔍 Browser DevTools for Focus</h3>
      <p>Using browser developer tools to test and debug focus states.</p>
      
      <div class="browser-demo">
        <span style="color: #7f8c8d;">// Chrome/Edge DevTools Accessibility Panel</span><br>
        1. Press F12 to open DevTools<br>
        2. Go to <span style="color: #2ecc71;">"Elements"</span> panel<br>
        3. Select an element<br>
        4. Check <span style="color: #2ecc71;">"Accessibility"</span> tab in sidebar<br>
        5. View focus and ARIA properties<br><br>
        
        <span style="color: #7f8c8d;">// Firefox Accessibility Inspector</span><br>
        1. F12 → <span style="color: #2ecc71;">"Accessibility"</span> tab<br>
        2. Enable <span style="color: #2ecc71;">"Show Tabbing Order"</span><br>
        3. Check focusable elements and order
      </div>
    </div>
    
    <!-- Keyboard Testing -->
    <div class="testing-card">
      <h3>⌨️ Keyboard-Only Testing</h3>
      <p>Essential keyboard navigation testing procedures.</p>
      
      <div class="keyboard-test">
        <h4>Keyboard Testing Steps:</h4>
        <ol style="margin: 1rem 0; padding-left: 1.5rem;">
          <li>Disconnect mouse/trackpad</li>
          <li>Use Tab to move forward through elements</li>
          <li>Use Shift+Tab to move backward</li>
          <li>Use Enter/Space to activate buttons and links</li>
          <li>Use Arrow keys for radio groups, sliders, menus</li>
          <li>Use Esc to close modals and dialogs</li>
          <li>Verify focus never gets trapped (except in modals)</li>
          <li>Check focus returns to appropriate place after interactions</li>
        </ol>
      </div>
      
      <div class="testing-demo">
        <h4>Common Keyboard Issues:</h4>
        <ul style="margin: 1rem 0; padding-left: 1.5rem;">
          <li>Focus order doesn't match visual order</li>
          <li>Interactive elements not focusable</li>
          <li>Focus indicators missing or unclear</li>
          <li>Focus trapped in components</li>
          <li>Focus lost after dynamic updates</li>
          <li>Keyboard shortcuts conflict with browser</li>
        </ul>
      </div>
    </div>
    
    <!-- Screen Reader Testing -->
    <div class="testing-card">
      <h3>🎧 Screen Reader Testing</h3>
      <p>Testing focus with popular screen readers.</p>
      
      <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; margin: 2rem 0;">
        <div>
          <h4>NVDA (Windows)</h4>
          <ul>
            <li>Free, open-source screen reader</li>
            <li>Tab to navigate interactive elements</li>
            <li>Arrow keys to read content</li>
            <li>Insert+F7 to open elements list</li>
          </ul>
        </div>
        
        <div>
          <h4>VoiceOver (macOS)</h4>
          <ul>
            <li>Cmd+F5 to enable</li>
            <li>Ctrl+Opt+Arrow to navigate</li>
            <li>Ctrl+Opt+U for rotor</li>
            <li>Ctrl+Opt+Space to activate</li>
          </ul>
        </div>
      </div>
    </div>
    
    <!-- Automated Testing -->
    <div class="testing-card">
      <h3>🤖 Automated Focus Testing</h3>
      <p>Using automated tools to catch focus accessibility issues.</p>
      
      <div class="browser-demo">
        <span style="color: #7f8c8d;">// axe-core automated testing</span><br>
        <span style="color: #9b59b6;">const</span> axe = <span style="color: #3498db;">require</span>(<span style="color: #2ecc71;">'axe-core'</span>);<br><br>
        
        axe.<span style="color: #3498db;">run</span>(document, {<br>
        &nbsp;&nbsp;runOnly: {<br>
        &nbsp;&nbsp;&nbsp;&nbsp;type: <span style="color: #2ecc71;">'tag'</span>,<br>
        &nbsp;&nbsp;&nbsp;&nbsp;values: [<span style="color: #2ecc71;">'wcag2a'</span>, <span style="color: #2ecc71;">'wcag2aa'</span>]<br>
        &nbsp;&nbsp;}<br>
        }, (err, results) => {<br>
        &nbsp;&nbsp;<span style="color: #9b59b6;">if</span> (err) <span style="color: #9b59b6;">throw</span> err;<br>
        &nbsp;&nbsp;<span style="color: #3498db;">console</span>.log(results.violations);<br>
        });<br><br>
        
        <span style="color: #7f8c8d;">// Common focus-related violations:</span><br>
        <span style="color: #7f8c8d;">// - focusable-element-not-visible</span><br>
        <span style="color: #7f8c8d;">// - no-focusable-content</span><br>
        <span style="color: #7f8c8d;">// - focus-order-semantics</span>
      </div>
    </div>
    
    <!-- Continuous Integration -->
    <div class="testing-card">
      <h3>⚙️ CI/CD Focus Testing</h3>
      <p>Integrating focus accessibility testing into your development workflow.</p>
      
      <div class="browser-demo">
        <span style="color: #7f8c8d;">// GitHub Actions workflow example</span><br>
        <span style="color: #9b59b6;">name</span>: Accessibility Tests<br>
        <span style="color: #9b59b6;">on</span>: [push, pull_request]<br><br>
        
        <span style="color: #9b59b6;">jobs</span>:<br>
        &nbsp;&nbsp;<span style="color: #9b59b6;">accessibility</span>:<br>
        &nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #9b59b6;">runs-on</span>: ubuntu-latest<br>
        &nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #9b59b6;">steps</span>:<br>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- <span style="color: #9b59b6;">uses</span>: actions/checkout@v2<br>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- <span style="color: #9b59b6;">name</span>: Run axe tests<br>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #9b59b6;">run</span>: npm test -- --grep="accessibility"<br>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- <span style="color: #9b59b6;">name</span>: Lighthouse CI<br>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #9b59b6;">run</span>: npm run lhci -- assert
      </div>
    </div>
  </div>
</body>
</html>

Practical Applications & Best Practices

✅ Do's for Focus Styles

  • Use high contrast colors for focus indicators
  • Make focus indicators at least 2px thick
  • Use :focus-visible for intelligent focus display
  • Test with keyboard navigation only
  • Ensure focus order matches visual layout
  • Provide skip links for long pages

❌ Don'ts for Focus Styles

  • Never remove outline without providing alternative
  • Don't rely on color alone for focus indication
  • Avoid very subtle focus indicators
  • Don't trap focus except in modals
  • Avoid changing content layout on focus
  • Don't forget to test in high contrast mode

💡 Pro Tips for Focus Styles

Development:

  • Use CSS custom properties for consistent focus styling
  • Implement focus traps for modal dialogs
  • Manage focus programmatically in single-page apps
  • Use outline-offset for better visual separation
  • Combine outline with box-shadow for enhanced visibility

Design:

  • Design focus states as part of your design system
  • Ensure focus indicators work on all background colors
  • Consider animation for focus transitions
  • Test focus states in different themes and modes
  • Document focus patterns for team consistency

Ready to Master Focus Styles? 🎯

Start implementing accessible focus styles that work for all users. Remember: good focus states aren't just about compliance - they're about creating better experiences for everyone who uses your website.

< PreviousNext >