AgentStack
SKILL verified MIT Self-run

Accessibility Checker

skill-armanzeroeight-fastagent-plugins-accessibility-checker · by armanzeroeight

Validate WCAG compliance, check screen reader support, and audit accessibility issues. Use when ensuring accessibility, fixing WCAG violations, or implementing inclusive design.

No reviews yet
0 installs
15 views
0.0% view→install

Install

$ agentstack add skill-armanzeroeight-fastagent-plugins-accessibility-checker

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Accessibility Checker? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Accessibility Checker

Validate web accessibility and ensure WCAG compliance.

Quick Start

Use semantic HTML, add ARIA labels, ensure keyboard navigation, test color contrast, validate with axe or Lighthouse.

Instructions

WCAG Compliance Levels

Level A (minimum):

  • Basic accessibility
  • Must meet for legal compliance

Level AA (recommended):

  • Standard for most websites
  • Includes contrast requirements
  • Government sites requirement

Level AAA (enhanced):

  • Highest level
  • Not required for all content
  • Best practices

Common Accessibility Issues

1. Missing alt text:

// Bad

// Good

// Decorative images

2. Poor color contrast:

/* Bad: 2.5:1 contrast */
color: #777;
background: #fff;

/* Good: 4.5:1 contrast (AA) */
color: #595959;
background: #fff;

/* Better: 7:1 contrast (AAA) */
color: #333;
background: #fff;

3. Missing form labels:

// Bad

// Good
Name

// Or with aria-label

4. No keyboard navigation:

// Bad: onClick on div
Click me

// Good: Use button
Click me

// Or make div focusable
 e.key === 'Enter' && handleClick()}
>
  Click me

5. Missing ARIA labels:

// Bad: Icon button without label

// Good: Add aria-label

  

Semantic HTML

Use proper elements:

// Bad
Submit

// Good
Submit

// Bad
Title

// Good
Title

Heading hierarchy:

// Bad: Skipping levels
Page Title
Section

// Good: Proper hierarchy
Page Title
Section
Subsection

Landmarks:


  
    {/* Navigation links */}
  

  
    {/* Main content */}
  
  
    {/* Sidebar */}
  

  {/* Footer content */}

ARIA Attributes

aria-label:


  

aria-labelledby:

Confirm Action

  {/* Dialog content */}

aria-describedby:


  Must be at least 8 characters

aria-live:

// Announce updates to screen readers

  {statusMessage}

// For urgent updates

  {errorMessage}

aria-expanded:


  Menu

  {/* Menu items */}

Keyboard Navigation

Tab order:

// Use tabIndex to control focus order
First
Second
Not in tab order

Focus management:

function Dialog({ onClose }) {
  const closeButtonRef = useRef();
  
  useEffect(() => {
    // Focus close button when dialog opens
    closeButtonRef.current?.focus();
    
    // Trap focus in dialog
    const handleTab = (e) => {
      if (e.key === 'Tab') {
        // Implement focus trap
      }
    };
    
    document.addEventListener('keydown', handleTab);
    return () => document.removeEventListener('keydown', handleTab);
  }, []);
  
  return (
    
      
        Close
      
    
  );
}

Keyboard shortcuts:

useEffect(() => {
  const handleKeyPress = (e) => {
    if (e.key === 'Escape') {
      closeDialog();
    }
    if (e.key === '/' && e.ctrlKey) {
      openSearch();
    }
  };
  
  document.addEventListener('keydown', handleKeyPress);
  return () => document.removeEventListener('keydown', handleKeyPress);
}, []);

Screen Reader Support

Skip links:


  Skip to main content

  {/* Content */}

// CSS
.skip-link {
  position: absolute;
  top: -40px;
  left: 0;
  background: #000;
  color: #fff;
  padding: 8px;
  z-index: 100;
}

.skip-link:focus {
  top: 0;
}

Visually hidden text:

// CSS
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}

// Usage

  
  Delete item

Announce dynamic content:

function Toast({ message }) {
  return (
    
      {message}
    
  );
}

Color Contrast

Check contrast ratios:

  • Normal text: 4.5:1 (AA), 7:1 (AAA)
  • Large text (18pt+): 3:1 (AA), 4.5:1 (AAA)
  • UI components: 3:1

Tools:

  • WebAIM Contrast Checker
  • Chrome DevTools
  • Lighthouse

Don't rely on color alone:

// Bad: Only color indicates error

// Good: Color + icon + text

  
  
     Email is required
  

Forms Accessibility

Labels:

Email

Error messages:


{hasError && (
  
    Please enter a valid email
  
)}

Fieldsets:


  Shipping Address
  Street
  

Testing Tools

Automated testing:

# Install axe-core
npm install --save-dev @axe-core/react

# Use in tests
import { axe, toHaveNoViolations } from 'jest-axe';
expect.extend(toHaveNoViolations);

test('should have no accessibility violations', async () => {
  const { container } = render();
  const results = await axe(container);
  expect(results).toHaveNoViolations();
});

Browser extensions:

  • axe DevTools
  • WAVE
  • Lighthouse

Screen readers:

  • NVDA (Windows, free)
  • JAWS (Windows)
  • VoiceOver (Mac, built-in)
  • TalkBack (Android)

Common Patterns

Modal dialog:

function Modal({ isOpen, onClose, title, children }) {
  const modalRef = useRef();
  
  useEffect(() => {
    if (isOpen) {
      modalRef.current?.focus();
      document.body.style.overflow = 'hidden';
    }
    return () => {
      document.body.style.overflow = '';
    };
  }, [isOpen]);
  
  if (!isOpen) return null;
  
  return (
    
      {title}
      {children}
      
        Close
      
    
  );
}

Dropdown menu:

function Dropdown({ label, items }) {
  const [isOpen, setIsOpen] = useState(false);
  
  return (
    
       setIsOpen(!isOpen)}
      >
        {label}
      
      {isOpen && (
        
          {items.map(item => (
            
              
                {item.label}
              
            
          ))}
        
      )}
    
  );
}

Tabs:

function Tabs({ tabs }) {
  const [activeTab, setActiveTab] = useState(0);
  
  return (
    
      
        {tabs.map((tab, index) => (
           setActiveTab(index)}
          >
            {tab.label}
          
        ))}
      
      {tabs.map((tab, index) => (
        
          {tab.content}
        
      ))}
    
  );
}

Accessibility Checklist

Perceivable:

  • [ ] All images have alt text
  • [ ] Color contrast meets WCAG AA (4.5:1)
  • [ ] Text can be resized to 200%
  • [ ] Content is not conveyed by color alone

Operable:

  • [ ] All functionality available via keyboard
  • [ ] No keyboard traps
  • [ ] Skip links provided
  • [ ] Focus indicators visible

Understandable:

  • [ ] Page language specified
  • [ ] Labels for form inputs
  • [ ] Error messages clear
  • [ ] Consistent navigation

Robust:

  • [ ] Valid HTML
  • [ ] ARIA used correctly
  • [ ] Works with assistive technologies
  • [ ] No console errors

Best Practices

Start accessible:

  • Use semantic HTML first
  • Add ARIA only when needed
  • Test with keyboard
  • Test with screen reader

Progressive enhancement:

  • Core functionality works without JS
  • Enhanced experience with JS
  • Graceful degradation

Regular testing:

  • Automated tests (axe)
  • Manual keyboard testing
  • Screen reader testing
  • User testing with disabled users

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.