← All Sparks

Sparks, Design systems

I audited my own design system and replaced Storybook

I pointed AccessSpark at the Flint docs. My components passed. The tool I was testing them in did not.

By Mike Binder3 min read

Two AccessSpark crawls of the Flint docsFirst crawl: score 83 with 83 failures and 548 issues. Between the crawls: page structure, security headers, and SEO fixed in the docs, and the Storybook workbench replaced with one built into the docs site. Second crawl: score 94 with zero failures and 131 issues left, all warnings and info.First crawl8383 failures548 issuesMost from Storybook's own UIThe fixesDocs siteHeadings, security headers, SEOStorybookReplaced with a built-in workbenchAccessSpark5 false positives flagged backSecond crawl940 failures131 issues leftWarnings and info only

Flint is my design system. It runs under AccessSpark and the Inner Spark Media sites. The whole point of it is accessibility built in: text contrast at 7:1, focus rings and target sizes baked into the tokens, and a build that fails if any of that slips.

When the Flint docs went live at flint.innersparkmedia.com, I did the obvious thing. I pointed AccessSpark, my own accessibility tool, at them.

The first crawl

83 out of 100. 83 failures. 548 issues.

That stung a little. Most of it came from two places.

How I built the docs site. These were real, and they were mine:

  • The side nav used headings for its group labels, so the page outline started in the wrong place.
  • No Content Security Policy, and nothing stopping another site from loading mine in a frame.
  • Missing share tags, no sitemap, and page titles that were too short.

None of that was Flint’s tokens or components. All of it was an afternoon of fixes.

Storybook. My component workbench ran on Storybook. The components inside it passed. Storybook’s own interface around them did not: no main landmark, no skip link, buttons with no names, focus outlines turned off, and zoom disabled on the preview.

The call

I couldn’t fix Storybook’s interface without forking it, and every update would break my patch.

I also couldn’t keep publishing it. A design system that sells accessibility can’t ship a test tool that fails an accessibility audit. Anyone who scanned it would see the failures first and never get to the passing components.

When I looked at what I actually used, the answer was easy. Stories, a theme toggle, a density toggle, and forced hover and focus states. The docs site already had most of that.

I moved the workbench into the docs site. Same job: every component in MUI, shadcn/ui, and plain CSS, side by side, in every state. It took about a day.

The build now checks the workbench the same way it checks everything else. Zero axe violations in light and dark, at both densities. If a forced hover state looks exactly like the default, the build fails, because that means the preview is lying to you.

The second crawl

94 out of 100. Zero failures. 131 issues left, all warnings and notes.

It went both ways

Five of AccessSpark’s findings were wrong:

  • It said reduced motion support was missing. The rule was in the stylesheet. AccessSpark was only reading inline CSS.
  • It said the dark mode toggle should be a link. A toggle is a button.
  • Its suggested fix for same-page links said to drop preventDefault. That breaks focus for screen reader users. I learned that one the hard way on this site.
  • It flagged Storybook’s search box as a required field. It isn’t.
  • It rolled Storybook’s problems up as if the whole site had them, without naming a page.

Those are bugs for me to fix in AccessSpark. Having two of my own products check each other made both of them better.

What I took from it

Audit your test tools too. The workbench was there to catch problems, and it ended up being the biggest problem on the site. I only found it because I ran the same audit on it that I run on everything else.

The full story, with how the tokens and build checks work, is in the Flint case study.

Keep reading

Work with meAccessibility and design systems consulting