Website Accessibility Audit

Our company is engaged in the development, support and maintenance of sites of any complexity. From simple one-page sites to large-scale cluster systems built on micro services. Experience of developers is confirmed by certificates from vendors.
Development and maintenance of all types of websites:
Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:
Development stages
Latest works
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    822
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    847
  • image_website-sbh_0.png
    Website development for SBH Partners
    999
  • image_website-_0.png
    Website development for Red Pear
    451

Website Accessibility Audit

An accessibility audit identifies barriers that prevent users with vision impairments, hearing loss, mobility issues, or cognitive differences from using your website effectively. The standard is WCAG 2.1/2.2 Level AA, which is mandatory for government websites in many countries and is the de facto standard for commercial sites.

What's Included in an Audit

Automated Scanning — detects approximately 30–40% of violations: missing alt texts, insufficient contrast, incorrect heading structure, missing ARIA attributes.

Manual Testing — essential for interactive elements: keyboard navigation, screen reader compatibility, modal windows and form behavior.

Real AT Testing — NVDA + Firefox (Windows), VoiceOver + Safari (macOS/iOS), TalkBack (Android).

Automated Scanning

# axe-core via CLI
npm install -g @axe-core/cli
axe https://mysite.com --reporter=json > axe-report.json

# Lighthouse Accessibility
npx lighthouse https://mysite.com \
  --only-categories=accessibility \
  --output=html \
  --output-path=./lighthouse-a11y.html

# Pa11y: batch scan of all pages
npm install -g pa11y-ci
# .pa11yci
defaults:
  standard: WCAG2AA
  runners:
    - axe
    - htmlcs
  timeout: 30000
urls:
  - https://mysite.com
  - https://mysite.com/about
  - https://mysite.com/contact
  - https://mysite.com/blog
pa11y-ci --config .pa11yci --json > pa11y-report.json

# Parse results
node -e "
const r = require('./pa11y-report.json');
const issues = Object.values(r.results).flat();
const errors = issues.filter(i => i.type === 'error');
console.log('Total errors:', errors.length);
errors.slice(0,10).forEach(e => console.log(e.code, e.selector));
"

Key WCAG AA Criteria

Criterion Requirement Common Error
1.1.1 Alt Text All images have alt text Decorative images without alt=""
1.3.1 Info and Relationships Structure conveyed through semantics <div> instead of <button>, <nav>, <main>
1.4.3 Contrast 4.5:1 for text, 3:1 for large text Gray text on white background
1.4.4 Resize Text Up to 200% without content loss Fixed height on blocks
2.1.1 Keyboard Everything accessible via keyboard No focus on custom dropdowns
2.4.3 Focus Order Logical focus order tabindex with arbitrary numbers
2.4.7 Focus Visible Visible focus indicator outline: none without alternative
3.3.1 Error Identification Form errors described in text Color only indicates error
4.1.2 Name, Role, Value ARIA for custom components No role/aria-label on icon buttons

Manual Checking: Checklist

Keyboard Navigation:

  • Tab moves through all interactive elements
  • Shift+Tab works in reverse direction
  • Enter/Space activates buttons
  • Escape closes modals and dropdowns
  • Arrow keys work inside <select>, radio groups, tablist

Focus Trapping:

// Proper focus management in modal window
const Modal = ({ isOpen, onClose, children }) => {
  const modalRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (isOpen) {
      // Save previously focused element
      const previouslyFocused = document.activeElement as HTMLElement;

      // Move focus to modal
      modalRef.current?.focus();

      return () => {
        // Restore focus on close
        previouslyFocused?.focus();
      };
    }
  }, [isOpen]);

  return (
    <div
      ref={modalRef}
      role="dialog"
      aria-modal="true"
      aria-labelledby="modal-title"
      tabIndex={-1}
    >
      {children}
    </div>
  );
};

Contrast Checking:

# Use axe DevTools in browser — Elements tab
# Or programmatically:
node -e "
const { getContrastRatio } = require('polished');
const ratio = getContrastRatio('#767676', '#ffffff');
console.log('Ratio:', ratio.toFixed(2), ratio >= 4.5 ? 'PASS' : 'FAIL AA');
"

Common Findings and Fixes

Custom Components Without ARIA:

// BAD: icon button without description
<div onClick={handleDelete}>
  <TrashIcon />
</div>

// GOOD:
<button
  type="button"
  onClick={handleDelete}
  aria-label="Delete record"
>
  <TrashIcon aria-hidden="true" />
</button>

Form Without Label–Input Connection:

<!-- BAD -->
<label>Email</label>
<input type="email" name="email">

<!-- GOOD -->
<label for="email">Email</label>
<input type="email" id="email" name="email">

<!-- Or via aria-labelledby -->
<span id="email-label">Email</span>
<input type="email" aria-labelledby="email-label">

Skip Navigation:

<!-- First page element — skip navigation link -->
<a href="#main-content" class="skip-link">
  Skip to main content
</a>
<nav>...</nav>
<main id="main-content">...</main>
.skip-link {
  position: absolute;
  left: -9999px;
}
.skip-link:focus {
  left: 0;
  top: 0;
  z-index: 9999;
}

CI/CD Integration

# GitHub Actions
- name: Accessibility Check
  run: |
    npx pa11y-ci --config .pa11yci --threshold 0
  # threshold 0 = no WCAG AA errors allowed

# Or axe in Playwright tests
- name: Run axe in E2E
  run: npx playwright test accessibility.spec.ts
// accessibility.spec.ts
import { test, expect } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';

test('Homepage should not have accessibility violations', async ({ page }) => {
  await page.goto('/');
  const results = await new AxeBuilder({ page })
    .withTags(['wcag2a', 'wcag2aa', 'wcag21aa'])
    .analyze();
  expect(results.violations).toEqual([]);
});

Report Format

After the audit, a structured report is provided:

  • Critical (block keyboard or screen reader usage) — immediate fixing required
  • Serious (WCAG AA violations) — fix within sprint
  • Moderate (WCAG AAA recommendations, best practices) — roadmap

Audit for sites up to 20 pages takes 2–3 business days, including NVDA testing and manual checking of all interactive scenarios.