Building Inclusive Fabric Apps: Who’s Responsible?

There is a lot of speculation about whether Fabric Apps will eventually replace Power BI. Everyone is talking about how AI can build these applications faster and more efficiently. But there’s a question I think deserves just as much attention: Are the apps we’re building inclusive?

In Power BI, we work with a canvas that is managed by the platform. Microsoft provides the keyboard model, focus handling and screen reader support. Our responsibility is to configure what the canvas exposes: alt text, titles, tab order, contrast and reading order.

With Fabric Apps, things are different. There’s no managed canvas, so most of that responsibility moves into the app’s code, written by an agent from someone’s prompt.

So who’s responsible? Microsoft is responsible for the components it provides, while the person prompting is responsible for what they ask for and what they check. The agent sits in between: it writes the code, but it only follows the accessibility rules it’s been given.

In this article I explore where accessibility responsibilities sit when building Fabric Apps, what needs to be considered when writing prompts, and how to ensure the resulting applications are inclusive.

This article is based on my research into Fabric Apps, Rayfin, Microsoft’s published components and documentation, and the WCAG requirements that apply to web applications, all seen through my experience of Power BI accessibility.

At the end, I’ll also share an Agent Skill I’ve created to put accessibility requirements directly into a coding agent’s instructions.

What are Fabric Apps and Rayfin?

Let’s start with a bit of context.

Fabric Apps is a preview feature in Microsoft Fabric, built on the Rayfin SDK. Microsoft’s documentation describes a data model defined in TypeScript, with Fabric providing the APIs, authentication and hosting. The app lives in a workspace like other Fabric items, and Rayfin is the open-source SDK and command-line tool behind it

Microsoft announced Rayfin at Build in June 2026, and Fabric Apps is still in preview at the time of writing.

For those of us coming from Power BI, the Fabric App template is the most relevant starting point. It gives the agent components and patterns for visualisation, formatting, data grids and browser validation, with the data coming from a semantic model.

The result looks familiar: charts, cards, a grid and a data model, much like a Power BI report. Underneath, though, it’s a web application, and its accessibility depends on how the agent puts those components together.

From a managed canvas to a prompted web app

This is where things get interesting.

In Power BI, Microsoft takes care of several accessibility behaviours at platform level. In a Fabric App, they become part of the code, so they depend on what the agent writes and what the person prompting asks it to check.

I’ve put together the comparison below to show where that responsibility moves. The Power BI column reflects my own experience of auditing reports, while the Fabric App column is based on my research into web accessibility requirements.

AreaPower BI reportFabric App
Keyboard modelProvided by the platformBuilt into Microsoft’s published chart and grid components; elsewhere the agent has to build it. Either way, it has to keep working, and someone has to test it
Focus indicatorProvided by the platformBrowser default unless the app’s styling removes or changes it; check that it stays visible and has enough contrast
Reading orderSet with tab order and layer orderSet by the order and structure of the elements the agent generates
Visual names and descriptionsTitle and alt text propertiesAccessible names, descriptions and visible text in the code
Page changesPage navigation handled by the platformThe app has to manage focus and the page title
Layout and zoomFixed canvas with reflow limitsSurrounding content must reflow; two-dimensional content is exempt
Error and loading messagesPlatform messagesThe app has to show them and tell assistive technologies when they change

There is one area where a Fabric App has an advantage: reflow.

Power BI’s fixed canvas makes WCAG 1.4.10 Reflow difficult to meet. An application built for the web, on the other hand, can adapt to narrower viewports.

There is an important exception here. WCAG recognises that some content needs a two-dimensional layout to keep its meaning or functionality. Data tables are an explicit example, and a data grid would usually fall under the same exception. Charts may also need a two-dimensional presentation.

This doesn’t mean the entire app is exempt. The surrounding interface, including navigation, filters, cards and text, still needs to work at a width equivalent to 320 CSS pixels, even when a grid or chart has its own scrolling area.

What WCAG asks of a Fabric App

I’ve grouped the requirements around the four WCAG principles: Perceivable, Operable, Understandable and Robust (POUR). These are the areas where I expect a Fabric Apps to differ most from a Power BI report.

You don’t need to read code to use this section. Each requirement is something to ask the agent for, and most of them can be checked by using the app.

Perceivable

The first Perceivable requirement is WCAG 1.1.1 Non-text Content: anything that isn’t text needs a text alternative that does the same job. In Power BI, I write alt text visual by visual. In a Fabric App, the agent generates the interface, so alt text has to be asked for and then checked.

Let’s start with charts

Charts need an accessible name and a useful text alternative. In Power BI, I use dynamic DAX alt text to describe what a visual communicates. The idea is to give someone using a screen reader access to the insight, rather than simply describing colours, shapes or chart types.

Microsoft has published chart and grid packages for Fabric Apps on npm, and their documentation describes much of this functionality as built in.

For example, the chart component, VegaVisual, takes its accessible name from its header title and subtitle. It also offers a “Show as a table” view of its data, and keyboard users can explore its axes, data points and legend items inside the chart itself. That keyboard exploration only works for Vega-Lite charts, though; in version 5.0.0, charts written in Microsoft’s Flint format don’t get it.

This changes the job. Instead of building all these features, the agent’s job is not to break them. Every chart needs a meaningful title and alternative text, and nothing should hide it from assistive technology.

For charts built in other ways, one option is role=”img” with an aria-label, alongside a data table alternative that screen reader users can navigate cell by cell.

If you’ve worked with Power BI custom visuals, you’ll recognise a familiar problem here. Keyboard and high contrast support depend on whoever developed the visual.

In a Fabric App, any chart that doesn’t use Microsoft’s own component is effectively a custom visual, and nothing reviews it before it reaches your users.

Microsoft’s extensibility package offers a container that can wrap any visual, giving it a name from its header and a “Show as a table” view when the data is supplied. Keyboard access to the individual points inside the chart is still down to the code the agent writes.

Alt text beyond charts

Charts are not the only non-text content in an app. These are the places I’d check:

  • Icon-only buttons. A button that shows only a funnel, a download arrow or a cog needs an accessible name such as “Filter” or “Download data”. Without one, a screen reader announces just “button”.
  • Meaningful images. Logos, diagrams and screenshots need alt text that says what they convey in context. A logo that links to the home page should be named for where it goes, not for how it looks.
  • Decorative images. Dividers, background shapes and purely visual flourishes should be hidden from assistive technology (an empty alt attribute, or aria-hidden), so people don’t have to listen to them.
  • Status icons and KPI cards. If a red arrow or a traffic light is the only sign that a measure is off target, that meaning needs a text equivalent, such as “Revenue: 4% below target”. This also overlaps with WCAG 1.4.1 Use of Color.
  • Tooltips. Information that only appears on hover is invisible to screen reader, keyboard and touch users. If it matters, it needs to be available in the page text too.

The agent will often add decorative icons and charts without being asked, so I’d put these rules in the prompt up front: every icon-only control gets a name, decorative graphics are hidden, and every status shown in colour or an icon also gets a text label.

Get the colour contrast right

Colour needs its own check, too. The template keeps its styles in one central place, so a palette change from a single prompt can apply across cards, charts and grids. That’s useful for consistency, but it doesn’t make the colours accessible.

Dark mode and chart series colours still need to be checked against WCAG 1.4.3 Contrast (Minimum) and 1.4.11 Non-text Contrast.

Typography

Text size is another area where responsibility changes.

In Power BI, I set font sizes in each visual’s format pane, and readers who need larger text zoom the whole canvas. In a Fabric App, text has to work with the reader’s own browser settings.

WCAG 1.4.4 Resize Text requires text to scale up to 200 per cent without losing content or functionality. Browser zoom usually covers this, but text sized in relative units such as rem, which is worth asking the agent for, also respects the default font size people set in their browsers.

Then there’s WCAG 1.4.12 Text Spacing. Content must stay available when people increase line height to 1.5 times the font size, paragraph spacing to 2 times, letter spacing to 0.12 times and word spacing to 0.16 times.

In a Fabric App, I’d pay particular attention to:

  • Data grids set to load rows as you scroll, which gives every row the same fixed height.
  • Cells cut off with “…”, where the full text only appears in a hover tooltip that keyboard and touch users can’t usually open.
  • Chart axes that hide or shorten labels to avoid crowding, so larger text or wider spacing hides more of them.
  • Charts built without Microsoft’s component, where text often shrinks as the chart gets narrower.

These are exactly the places where content tends to get cut off when text spacing increases. The cut-off cells also affect keyboard and touch users, which matters beyond text spacing.

One more thing worth remembering: WCAG doesn’t set a minimum font size, but text size affects the contrast requirement.

Text below 18 point, or below 14 point if it’s bold, counts as normal text and needs a contrast ratio of 4.5:1 rather than 3:1. That includes the small labels and legends charts tend to use.

Operable

Keyboard accessibility is where I’d expect the most work.

Think about everything people can interact with in a Fabric App: chart points, cross-highlighting, grid cells, tooltips and the image preview in the grid. They all need to work with a keyboard, without creating a keyboard trap.

Microsoft’s chart and grid components handle some of this already. Anything the agent builds itself, or changes, needs checking.

Fabric Apps are single-page applications, which brings another consideration: focus management.

When someone moves to a different view in the app, focus should move to the new heading or content container, rather than staying on an element that no longer exists.

There’s also the page title. A single-page application is one web page, so its title stays the same unless the app updates it for every view.

Three WCAG 2.2 criteria are particularly relevant here.

Focus Not Obscured (Minimum) (2.4.11)

This is something I’d check carefully in apps with sticky headers and filter panels. The grid package’s header row is sticky, so it’s one of the first places I’d look.

The criterion fails when author-created content completely hides the element with keyboard focus. Partial covering passes at AA, although it’s still worth avoiding, and the AAA criterion, 2.4.12 Focus Not Obscured (Enhanced), doesn’t allow it.

Dragging Movements (2.5.7)

If an interaction uses dragging, there needs to be an alternative with a single pointer, such as buttons or a click-to-place action, unless dragging is essential.

The grid package documents column resizing and reordering as drag interactions, so an app that offers them also needs a button-based alternative.

Target Size (Minimum) (2.5.8)

This criterion sets a minimum of 24 by 24 CSS pixels for pointer targets, with exceptions, including smaller targets that have enough space around them.

If I were testing the template, dense data grids and small interactive chart elements would be among the first things I’d look at.

Understandable

There’s another difference between Power BI reports and Fabric Apps worth mentioning.

Fabric Apps can write data, whereas most Power BI reports don’t. An app that asks people to enter or edit data needs labels, error identification and error suggestions, and it shouldn’t ask for the same information twice (Redundant Entry, 3.3.7).

There’s one more thing I’d look at in this section: the words on the screen.

In a Fabric App, the agent takes its labels from the semantic model, and model field names are often written for the people who built the model, not the people reading the app. Unless someone asks for something better, names like “SalesAmt_LY”, “CustCnt” or “GM%” can end up as column headers, axis titles and card labels.

That’s a problem for everyone, but especially for screen reader users. A screen reader might read “GM%” as “G M percent”, or try to pronounce an abbreviation as if it were a word.

WCAG 2.4.6 Headings and Labels (AA) asks for headings and labels that describe their topic or purpose, and an abbreviated column header often doesn’t. I’d write column headers in full (“Gross margin %” rather than “GM%”), and if a header has to be short to fit, make sure the full name is still available to assistive technologies.

Plain language goes further than AA. Avoiding business jargon and spelling out acronyms is covered by 3.1.4 Abbreviations and 3.1.5 Reading Level, which are both AAA. But it makes a data app easier to understand for people with cognitive disabilities, for people reading in a second language, and honestly for most of us.

This is also something the person prompting can ask for directly: “use plain-language labels, not the model’s field names”.

Robust

There’s one criterion I suspect could easily be overlooked: Status Messages (4.1.3).

Fabric apps have plenty of things happening without anyone moving keyboard focus: loading indicators, empty results, errors and saved changes.

Assistive technologies need to be told when these states change, without people having to go looking for the information. In the code, this usually means a status role or a live region.

Then there’s Name, Role, Value (4.1.2), which applies to every custom control.

The template includes several, such as the cell renderers in the grid. Each one needs to expose its name, role, state and value correctly.

The documentation gap

After researching the template and its components, I wanted to understand what Microsoft actually tells people to check.

The Fabric Apps template includes a Playwright-based browser-validation workflow. It checks whether visuals render correctly, charts are cut off or compressed, text is readable, data grids handle overflow, loading, empty and error states are usable, interactions work and the console has no unexpected errors.

The GitHub Copilot tutorial also asks Copilot to check for clipped charts, unreadable labels, empty visuals and console errors at desktop and mobile sizes.

However, I haven’t found equivalent guidance on Microsoft Learn covering WCAG conformance, keyboard navigation or screen reader testing.

Some of this information is in the READMEs of the chart and grid packages Microsoft has published on npm, but I still have three questions.

Which libraries does the template actually use?

Microsoft has published @microsoft/fabric-visuals, a Vega-Lite (and Flint) chart component, and @microsoft/fabric-datagrid on npm.

The grid’s documented features match those of the template, but I haven’t confirmed whether the scaffold actually installs these packages.

This matters because their accessibility behaviour decides how much the agent needs to add, and how much needs testing.

How exactly is an app embedded in the Fabric portal?

The authentication documentation confirms that deployed sign-in runs through the portal, but it doesn’t describe the embedding mechanism.

I’d want to understand this before drawing conclusions about frame-specific requirements, such as frame titles and focus.

How does the data grid behave with a screen reader?

The grid package documents sort state, a labelled grand totals row and image previews named from their alt text.

That’s useful, but documentation isn’t the same as testing. Someone using assistive technology still needs to try navigating its cells and understanding their content.

Fabric Apps is still in preview, so I’d expect the guidance to develop alongside the platform.

If you’ve tested the template and found accessibility issues, I’d encourage you to send a short, specific report to the Rayfin team. That’s much more useful than a general request to make it accessible.

Agents write the code, so give them the rules

If most Fabric Apps are built by prompting, the agent’s instructions are where accessibility is won or lost.

Microsoft has already built this idea into the template. The scaffold includes instructions and skills for coding agents, and the Copilot tutorial tells the agent to read any copilot-instructions.md files in the project before changing code.

The person prompting is usually thinking about the data, not about focus order or live regions. Someone asking for “a sales dashboard with a region filter” won’t add “and make sure the filter is announced to screen readers”. That’s not a criticism; it’s exactly why accessibility rules belong in the agent’s instructions rather than in each prompt. Otherwise, we end up with an app that looks finished but leaves some people unable to use it.

There’s a considerable difference between an agent that has accessibility rules in its instructions and one that doesn’t. An agent told to use native HTML elements first, give charts accessible names and alternatives, announce status changes and keep keyboard focus visible will produce a very different app.

This is my own recommendation, rather than something from the Fabric Apps documentation. It’s the same principle behind my PBIR A11y CLI: put the checks next to the work, so problems are found while the app is being built.

Putting accessibility into an Agent Skill

To put this into practice, I’ve turned the guidance in this article into an Agent Skill called Building accessible Fabric Apps, which I’ve published on GitHub.

Agent Skills is an open format: a folder containing a SKILL.md file with instructions, alongside reference files that the agent reads when it needs them. The same folder works with GitHub Copilot (agent mode in VS Code, the Copilot CLI and the Copilot cloud agent) and Claude.

Once it’s in a project’s .github/skills folder, everyone prompting in that project gets it. I don’t know yet whether Replit’s agent supports Agent Skills, so for now it covers the Copilot and Claude routes.

The skill loads whenever an agent works on a Fabric App’s user interface, even when the prompt doesn’t mention accessibility, and applies the requirements in this article as it writes the code. When a project uses Microsoft’s chart and grid components, it tells the agent to use their built-in accessibility rather than replace it. Without that guidance, the agent in my tests hid both charts from screen readers and guessed at component settings that don’t exist. With it, the code passed 13 of 13 checks, against 5 of 13 without. The repository has the details and all the test results.

These tests ran in Claude and checked the code, not the experience of using it, so they don’t replace manual testing with a keyboard and screen reader.

If you’re the one prompting

Even with the skill, the person prompting still has a part to play. Three things help:

  • Mention accessibility in the prompt anyway, for example “make it work with a keyboard and a screen reader”, and say who’ll be using the app.
  • Ask the agent to explain how each chart and filter works with a keyboard, and where the “Show as a table” view is.
  • Check it yourself. You don’t need to read the code: put the mouse aside and use Tab to move through the page, zoom to 200 per cent, and try a screen reader such as NVDA or Windows Narrator.

Where I would start

As I mentioned at the beginning, I haven’t built or tested a Fabric App yet. My next step is to prompt a Fabric App against a small semantic model, with the skill installed, and work through five checks.

I’ll use a keyboard, NVDA, browser zoom and a text spacing bookmarklet to look at:

  1. Keyboard access to every interactive chart and grid.
  2. Focus management after a view change.
  3. How loading, empty, saved and error states are announced.
  4. Contrast in both light and dark themes.
  5. Reflow at 320 CSS pixels, allowing for the two-dimensional content exception, alongside text resized to 200 per cent and increased text spacing.

None of these checks need you to read the code. I’ll then map each finding to its WCAG criterion, document the results and update the skill with anything it missed.

Moving from Power BI to Fabric Apps means leaving behind a canvas that handles some accessibility at platform level. In return, we get the flexibility of a web application, built from a description rather than a fixed reporting canvas.

If agents are going to write these apps, they need accessibility rules from the start. This skill is my first attempt at providing them.

If you’ve already tested the Fabric App template with a keyboard or screen reader, or decide to try the skill with Copilot or Claude, I’d love to hear what you find.

Sources

Research gathered on 1 November 2026. Fabric Apps is in preview, so details may change.

Microsoft

Coverage of Fabric Apps and Rayfin

WCAG and web accessibility

Agent Skills

Leave a Reply