Embedding Accessibility in the Design Process
AI generated
A11Y
WCAG
Accessibility · Design Process · WCAG 2.2 · Design Handoff
Embedding Accessibility in the Design Process
Why designing accessibly upfront is cheaper than fixing it after launch

A contrast error in a mockup can be fixed with a single click, the same error after launch costs person-days. This article shows how to check contrast, focus order, and touch target sizes during design, how accessibility acceptance criteria belong in the design handoff, and why designers share responsibility from the start.

13 min read Design Handoff · Contrast · Focus Order · Touch Targets WCAG 2.2 · Figma · Design Systems

1. Why fixing accessibility after the fact costs more than designing first

Software development has followed a well-known rule of thumb about defect costs for decades: a defect caught during the conception phase costs a fraction of the same defect caught after launch. The same logic applies to accessibility, yet it is routinely ignored in practice. A contrast problem that can be fixed in the mockup by switching to a different shade of grey turns, after development, into a search through dozens of templates, CSS files, and components where the color has been hardcoded. What costs five minutes in design often costs several person-days in code, because every occurrence has to be found, changed, and retested individually.

It gets even more expensive when structural problems only surface after launch, for example a missing focus order in a multi-step checkout or a form without proper semantic structure. Such defects can rarely be fixed with a CSS patch, they require reworking the HTML structure, retesting with screen readers, and often a full regression check of the affected flow. For Magento and Hyva stores in Germany, the Barrierefreiheitsstarkungsgesetz (BFSG) adds legal risk on top: rushed remediation because an auditor or a user reported a barrier is more expensive and more stressful than planned quality assurance during the design process.

2. Shift-left: thinking about accessibility from the wireframe stage

Shift-left originated in testing and describes moving quality assurance as early as possible in the development process instead of pushing it to the end. Applied to accessibility, that means asking, already at the first wireframe, in what order information makes sense for a screen reader user, rather than waiting until the HTML markup is written. Designers who think through heading hierarchy, landmark regions, and reading order at the sketch stage hand developers a blueprint that translates directly into semantic HTML instead of one that has to be reinterpreted afterward.

In practice, this means design tools like Figma let teams annotate frames with layer order, contrast values, and ARIA roles before a single developer is involved. Design tokens, the centrally maintained values for color, spacing, and typography, should be defined as contrast-safe from the start, so that every component consuming those tokens automatically stays WCAG-compliant. The following example shows a color token set exported as CSS custom properties, including a comment on the validated contrast ratio.


/* Design tokens exported from Figma variables */
/* Each color pair is pre-validated against its intended background */
:root {
  /* Text on white background, contrast ratio 7.2:1 (AAA) */
  --color-text-primary: #27272a;

  /* Secondary text on white background, contrast ratio 4.6:1 (AA) */
  --color-text-secondary: #52525b;

  /* Placeholder text, informational only, not required to meet 4.5:1 */
  --color-text-placeholder: #a1a1aa;

  /* Primary button background, white text on top, contrast ratio 8.1:1 */
  --color-button-primary-bg: #18181b;
  --color-button-primary-text: #ffffff;

  /* Error state, text on white background, contrast ratio 5.9:1 */
  --color-error: #b91c1c;
}

/* Component consuming the tokens automatically stays WCAG-compliant */
.form-label {
  color: var(--color-text-primary);
}
.form-hint {
  color: var(--color-text-secondary);
}

3. Checking contrast directly in the mockup

Color contrast is the accessibility aspect easiest to check during design, and at the same time one of the most common violations in live stores. WCAG 2.2 requires a contrast ratio of at least 4.5:1 against the background for normal text at Level AA, and at least 3:1 for large text starting at 18pt or 14pt bold. Plugins like Stark, Able, or the built-in contrast tools of modern design applications calculate this ratio directly in the mockup, while the color is still easy to change, not after it has been built into thirty templates.

For design systems, it is also worth running an automated check across the entire color palette so that new color combinations do not accidentally drop below the threshold. The calculation is based on the relative luminance of both colors according to the WCAG formula. A small script that runs this check as part of the design token pipeline prevents a new grey tone for secondary text from silently falling below 4.5:1 long before a developer ever copies the color into code.


// Contrast validation script, run against design tokens before export
// Implements the WCAG relative luminance formula

function relativeLuminance(hex) {
  const [r, g, b] = hexToRgb(hex).map((channel) => {
    const c = channel / 255;
    return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
  });
  return 0.2126 * r + 0.7152 * g + 0.0722 * b;
}

function contrastRatio(hexForeground, hexBackground) {
  const l1 = relativeLuminance(hexForeground);
  const l2 = relativeLuminance(hexBackground);
  const lighter = Math.max(l1, l2);
  const darker = Math.min(l1, l2);
  return (lighter + 0.05) / (darker + 0.05);
}

function hexToRgb(hex) {
  const value = hex.replace('#', '');
  return [0, 2, 4].map((i) => parseInt(value.substring(i, i + 2), 16));
}

const tokens = {
  textSecondary: '#52525b',
  background: '#ffffff',
};

const ratio = contrastRatio(tokens.textSecondary, tokens.background);
if (ratio < 4.5) {
  throw new Error(`Token textSecondary fails AA: ${ratio.toFixed(2)}:1`);
}
console.log(`textSecondary passes AA: ${ratio.toFixed(2)}:1`);

4. Annotating focus order in the design

The visual order in a mockup does not automatically match the order a keyboard user experiences while tabbing through, especially in multi-column layouts, card grids, or forms with fields arranged side by side. Without an explicit annotation, the developer decides the focus order at their own discretion, often simply following the order elements land in the source code, which does not necessarily match the reading order the design intended. A numbered overlay annotation directly on the frame, showing the intended tab order, removes this ambiguity entirely.

This annotation matters most for modals, multi-step forms, and custom components like date pickers or comboboxes, where the DOM order can diverge significantly from the visual arrangement. Developers should resolve the order primarily through DOM source order, not through positive tabindex values, which are hard to maintain and easily create inconsistencies. The following example shows how a focus order numbered in the design is translated into natural DOM order, with comments referencing the corresponding design annotation.


<!-- Focus order annotated in the design frame as 1-5, mapped here via DOM source order -->
<!-- WRONG: relying on positive tabindex to force an order -->
<div class="checkout-summary">
  <input type="text" name="promo-code" tabindex="3">
  <button type="submit" tabindex="1">Complete order</button>
  <a href="/cart" tabindex="2">Back to cart</a>
</div>

<!-- RIGHT: source order matches the intended focus order from the design annotation -->
<div class="checkout-summary">
  <!-- design annotation #1 -->
  <a href="/cart" class="checkout-summary__back">Back to cart</a>

  <!-- design annotation #2 -->
  <label for="promo-code">Promo code</label>
  <input type="text" id="promo-code" name="promo-code">

  <!-- design annotation #3 -->
  <button type="submit">Complete order</button>
</div>

5. Defining touch target sizes and spacing

WCAG 2.2 introduced Success Criterion 2.5.8 "Target Size (Minimum)" at Level AA, requiring a minimum size of 24 by 24 CSS pixels for interactive elements, with defined exceptions for cases such as inline links in body text or when an equivalent, larger target is available elsewhere. The stricter Success Criterion 2.5.5 "Target Size (Enhanced)" at Level AAA recommends 44 by 44 pixels. If these dimensions are not defined as a minimum in the design system for buttons, icons, and interactive cards, every developer ends up deciding individually how large a clickable area should be, with correspondingly inconsistent results.

In practice, this affects compact UI elements in particular, such as icon buttons in filter bars, pagination arrows, or close icons in modals, which look large enough in the desktop mockup but drop below the minimum size in the mobile view when breakpoints are not checked separately. Beyond raw target size, the spacing between adjacent touch targets is critical to avoid accidental taps on the wrong element. A design system should therefore define both minimum sizes and minimum spacing as reusable spacing tokens.


/* Touch target tokens, enforced across every interactive component */
:root {
  --target-size-min: 24px;   /* WCAG 2.5.8 Level AA minimum */
  --target-size-comfort: 44px; /* WCAG 2.5.5 Level AAA recommended */
  --target-spacing-min: 8px;   /* minimum gap between adjacent targets */
}

/* Icon button, visually 20px icon, but the tappable area meets the minimum */
.icon-button {
  min-width: var(--target-size-comfort);
  min-height: var(--target-size-comfort);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}
.icon-button svg {
  width: 20px;
  height: 20px;
}

/* Pagination links spaced to avoid accidental adjacent taps */
.pagination__item + .pagination__item {
  margin-left: var(--target-spacing-min);
}

6. Embedding accessibility acceptance criteria in the design handoff

A design handoff that contains only visual specifications like colors, spacing, and typography leaves every question about keyboard operation, screen reader behavior, and ARIA structure open, and those questions then get decided implicitly by the developer, usually under time pressure and without checking back with design. Accessibility acceptance criteria are explicit, testable requirements attached to every ticket in the handoff alongside the visual specification: expected keyboard behavior, visible focus indicators, screen reader announcement text for dynamic status changes, and the expected semantics, for example whether an element should be marked up as a button or as a link.

The effect on the definition of done is significant: a ticket no longer counts as finished once it "looks right", but only once the documented accessibility criteria are demonstrably met. This also moves test cases earlier in the process, because QA and development already know the criteria before the first line of code is written, instead of improvising them at the end of the sprint. The following example shows a JSON template for a handoff ticket with explicit accessibility acceptance criteria.


{
  "ticket": "PDP-482",
  "component": "Product image gallery with thumbnails",
  "visualSpec": {
    "figmaFrame": "PDP / Gallery / v3",
    "breakpoints": ["mobile", "tablet", "desktop"]
  },
  "accessibilityAcceptanceCriteria": [
    "Thumbnails are navigable via arrow keys once one has focus",
    "Active thumbnail has aria-current='true' and a visible focus ring",
    "Main image change is announced via aria-live='polite': 'Image 2 of 6'",
    "Every thumbnail has an alt attribute with product detail, not just 'Image 2'",
    "Touch target of every thumbnail is at least 44 by 44 CSS pixels",
    "Contrast ratio of the active border is at least 3:1 against the background"
  ],
  "testMethod": "Keyboard test + NVDA/VoiceOver + automated axe-core",
  "status": "ready-for-development"
}

7. Designers and developers: shared responsibility instead of silos

A common organizational pattern treats accessibility as a purely developer-owned task checked off by QA at the end of the sprint. This pattern overlooks that many barriers originate in design and can be avoided there with far less effort than in code. Designers need a basic understanding of WCAG principles for this, not at a developer's depth, but enough to judge contrast, focus order, and target sizes independently before a mockup reaches the development process.

In practice, this can be anchored through fixed rituals: an accessibility check as a fixed part of every design review before development starts, joint pairing sessions where designers and developers try out a screen reader together, and a shared checklist that belongs not only to QA but is maintained by both roles. A named accessibility champion per team, who does not have to be a developer, keeps the topic visible and prevents responsibility from diffusing between design and development.

8. Accessible design systems and component libraries

The biggest lever for accessibility in the design process is the component library itself. Once accessibility is solved correctly once in the base component of a button, form field, or modal within the design system, including contrast, focus state, and expected ARIA semantics, every single use of that component benefits automatically, without every team having to repeat the same check. Conversely, a single defect in the base component multiplies across every place it is used, which is exactly why extra care at this level pays off disproportionately.

To keep the design system and the code components from drifting apart, every Figma component should be linked to the corresponding Hyva or Alpine.js pattern in shared documentation, for example through Storybook or an internal pattern library. Changes to the design component then trigger a check on whether the corresponding code component is still in sync. A short accessibility checklist per component, right in the documentation, makes the requirements traceable for every team instead of hiding them in a separate, rarely-read WCAG document.

9. Design-stage fixes vs. post-launch fixes compared

The following overview compares typical accessibility tasks, once solved during the design stage and once fixed after launch. The difference in effort makes clear why investing in early checks pays off.

Task Fix during the design stage Fix after launch Effort difference
Contrast check Adjust color token in the mockup, minutes Find and replace the color across every template and CSS file Significantly higher
Focus order Add an overlay annotation to the frame Rework the HTML structure of multiple templates and retest Significantly higher
Touch target size Adjust a spacing token in the design system Fix each affected component individually in code Significantly higher
ARIA semantics for custom widget Document the expected role in the handoff Restructure existing markup after the fact Significantly higher
Legal risk (BFSG) No risk, checked before launch Possible complaint, rushed remediation under time pressure High, including reputational risk

In all five cases, the difference is not about how technically difficult the solution itself is, but about when it enters the process. Changing a wrongly chosen color in a mockup costs one click, finding and replacing the same color across fifty shipped templates costs days and carries extra regression risk.

Mironsoft

Accessibility, design systems, and accessibility implementation for Magento and Hyva stores

Ready to embed accessibility into design the right way?

We audit your design system for contrast, focus order, and touch target sizes, build accessibility acceptance criteria into your handoff process, and bring design and development into one shared accessibility workflow.

Design system audit

Check contrast, focus states, and touch targets in existing components

Handoff process

Embed accessibility acceptance criteria into tickets and definition of done

Team workshops

WCAG fundamentals for designers, establishing joint reviews with development

10. Summary

Embedding accessibility in the design process is not a luxury, it is the economically sound order in which accessibility work should happen. A contrast error costs one click in the mockup, often days in code. Focus order can be fixed with a numbered annotation on the frame instead of being rescued later with tabindex hacks in the markup. Touch target sizes of at least 24 by 24, ideally 44 by 44 CSS pixels, belong in the design system as spacing tokens, not left to the individual judgment of each developer.

Accessibility acceptance criteria in the design handoff turn implicit assumptions into explicit, testable requirements and move test cases to the beginning of the process. The biggest lever lies in the component library: solved correctly once, every use benefits automatically. In the end, what is needed is shared responsibility between design and development, not a silo structure in which accessibility shows up only at the end of the sprint as rework.

Embedding Accessibility in the Design Process, the key points at a glance

Cost advantage

A fix in the mockup costs minutes, the same fix after launch costs person-days across dozens of templates.

Design-stage checks

Check contrast, focus order, and touch target sizes in the mockup with tooling before code is written.

Acceptance criteria

Explicit, testable accessibility requirements in the handoff ticket instead of implicit assumptions by development.

Shared responsibility

Designers and developers check together, accessibility is not a pure QA task at the end of the sprint.

11. FAQ: Embedding Accessibility in the Design Process

1Why is it more expensive to fix accessibility only after launch?
A contrast error in a mockup is changed with a single click. After launch, the color has to be found and replaced in every template individually, costing person-days instead of minutes.
2What does shift-left mean for accessibility?
Questions about reading order, contrast, and semantics are asked already at the wireframe stage, not only once the HTML markup exists after development.
3What contrast ratio does WCAG 2.2 require for text?
At least 4.5:1 for normal text at Level AA, at least 3:1 for large text starting at 18pt or 14pt bold.
4Why does focus order need to be annotated in the design?
Without an annotation, the developer decides the tab order on their own, often diverging from the reading order the design intended.
5What is the minimum touch target size under WCAG 2.2?
At least 24 by 24 CSS pixels at Level AA, with 44 by 44 pixels recommended at Level AAA for comfortable operation.
6What are accessibility acceptance criteria?
Explicit, testable requirements in the handoff such as keyboard behavior, focus indicators, and expected ARIA semantics, documented alongside the visual specification.
7Who is responsible for accessibility in the design process?
Design and development together. Designers need basic WCAG knowledge to independently judge contrast and focus order.
8Why is accessibility at the design-system component level worth the investment?
A correctly solved base component passes its benefit on to every use. A defect in the base component, in turn, multiplies across every place it is used.
9How can contrast be checked automatically already in the mockup?
With plugins like Stark or Able in the design tool, or a script that calculates relative luminance using the WCAG formula as part of the design token pipeline.
10What happens if accessibility acceptance criteria are missing from the handoff?
Keyboard behavior and ARIA semantics get decided implicitly by the developer, usually under time pressure and without checking back with design, leading to inconsistent results.