Designing accessible Canvas apps: what Power Apps doesn't tell you
Most of my design career has lived in browsers — HTML, CSS, the GOV.UK Design System, a decade of accessibility habits that just come automatically now. So when I picked up a Canvas Power Apps project at DBT — a case management system for export licensing, built on Power Apps and referred to internally as BIST — I expected some friction. What I didn't expect was how much of my normal toolkit simply doesn't apply, and how much of it I'd need to rebuild from scratch for a low-code platform that wasn't designed with accessibility as a first-class citizen.
The platform problem
Power Apps Studio is genuinely good at what it's built for: letting people assemble business applications quickly, with minimal code, on top of Microsoft's data ecosystem. What it's not built for, at least not by default, is accessible-by-construction UI. There's no equivalent of a design system with baked-in focus states, no semantic HTML tree to inspect, no aria-* attributes you can just set and trust. Every accessible behaviour — tab order, visible focus, screen reader labelling — has to be deliberately authored using a fairly unfamiliar set of properties: TabIndex, AccessibleLabel, Focus().
That's a different mental model to reaching for a <button> and getting keyboard and screen reader support for free. In Power Apps, you're specifying accessibility behaviour explicitly, control by control, and it's very easy for a screen with forty components to have forty opportunities to get it wrong.
The good news: this problem is well enough understood that there's decent guidance out there if you know where to look. Defra published accessibility guidance for Canvas Power Apps in 2024 that became a genuine reference document for me, and the xGov low-code accessibility control catalogue filled in a lot of the gaps between "this is the WCAG requirement" and "this is the specific Power Apps property that satisfies it." Neither of those exists inside the product itself — you have to go looking.
Bringing GDS discipline to a non-GDS tool
One thing I didn't compromise on was the "one thing per page" principle from the GOV.UK Design System. It's tempting, in a tool that makes it easy to cram a data table, three filters, and a set of action buttons onto a single screen, to do exactly that. But BIST is a case management system used by people processing export licensing decisions — the cognitive load of a screen matters as much as it would in any public-facing GOV.UK service, arguably more, because the users are doing this for hours a day.
Applying that discipline meant treating each interaction — reviewing a case, adding a note, escalating a decision — as its own screen or step, rather than a single dense workspace. It's a design decision that Power Apps doesn't push you towards; you have to actively hold the line on it, especially when the fastest build is usually the most cluttered one.
Figma for alignment, HTML for truth
The workflow that ended up working best split responsibilities cleanly. Figma stayed at low fidelity — good enough for flow mapping and stakeholder alignment, quick to iterate on in a workshop, disposable if a direction changed. But it stopped being the source of truth the moment a screen needed real specification.
For that, I built HTML prototypes. Partly this was about fidelity — HTML lets you actually demonstrate tab order, focus states, and interaction logic rather than describe them in a comment. But it was also about developer trust: a working prototype in the browser, hosted on GitLab Pages given DBT's security constraints, closes far more ambiguity than an annotated static frame ever could. When a developer can tab through a prototype themselves and see the focus ring land where it should, there's no argument left to have about intent.
Where the prototype couldn't show something directly — a dropdown's full option list sitting off-canvas, a bit of conditional logic that only fires under certain data states — I used wireframe annotation panels alongside the prototype rather than over-specifying inside it. That kept the prototype clean and kept the edge cases documented without turning every screen into a wall of callouts.
Testing for real, not for show
Accessibility testing on this project wasn't a single audit at the end — it ran continuously through axe DevTools, WAVE, Lighthouse, and manual VoiceOver passes, plus Sim Daltonism and a contrast-checking menu bar app for colour work. Power Apps' own Accessibility Checker inside Studio is useful as a first pass, but it catches a narrower slice of issues than a proper multi-tool sweep, and it says nothing about how a screen actually feels when you're navigating it with a screen reader rather than just checking that labels exist.
Where design ends and requirements begin
Not every gap I found in the requirements was mine to close. A recurring, and genuinely useful, discipline on this project was distinguishing accessibility and interaction problems I could solve through design from ones that were actually business analyst or product owner decisions in disguise — what happens to a case if a required field is missing, who gets notified on an escalation, what "done" means for a particular case type. Rather than guessing or quietly deciding those myself, I got into the habit of writing them up as structured open questions ahead of walkthroughs with the BA. It sounds like a small process tweak, but it's the difference between a design that's internally consistent and one that's actually correct.
What I'd take into the next low-code project
If there's a single lesson from BIST, it's that low-code doesn't mean low accessibility effort — if anything it shifts the effort from "learn the platform's conventions" to "build the conventions yourself, and know enough about the underlying standards to do it properly." The tools that made this manageable weren't inside Power Apps at all: they were an external accessibility guidance document, a browser-based prototype that could carry real interaction fidelity, and a set of testing habits imported wholesale from web design. None of that is specific to government work or to export licensing, it's just what it takes to make a low-code platform behave like it takes accessibility seriously, even when the platform itself doesn't insist on it.