Skip to main content
referenceliving

Canvas PowerApps Quick Fix 4: Custom Confirmation Modal Replacing Confirm() for 508 Compliance in GCC

Why the out-of-the-box Confirm() function renders as a native browser dialog in the CMS GCC environment, breaking accessibility and styling, and how to replace it with a custom overlay modal that supports focus management and screen readers.

Reviewed Wed Jul 15 2026 00:00:00 GMT+0000 (Coordinated Universal Time) · Sensitivity: internal

#Evidence classification

Evidence labels used in this guide:

  • Microsoft documented: confirmed in Microsoft documentation
  • CMS tenant observed: reproduced in the CMS GCC environment
  • Production validated: currently used successfully in a production app
  • Unconfirmed root cause: behavior reproduced, but the underlying platform mechanism has not been independently confirmed

#TL;DR

Evidence: CMS tenant observed. In the CMS GCC environment, the out-of-the-box Canvas Apps Confirm() function renders as a native browser window.confirm() dialog rather than an in-app styled modal. This breaks visual consistency and, more importantly, is not reliably accessible: it falls outside the app's normal focus and screen reader flow. Replace Confirm() with a custom overlay modal built from containers and controls, so focus management and screen reader labeling can be handled explicitly.

#Issue

Confirm() is the built-in Canvas Apps function for a simple yes/no confirmation dialog. In our CMS GCC environment, Confirm() was observed rendering as the browser's native window.confirm() dialog. This differs from the in-app confirmation experience commonly observed in commercial Canvas Apps environments.

This was found while building duplicate-detection logic for the CCIIO SME Booking App, where a confirmation was needed before allowing a user to proceed with what looked like a duplicate SME entry.

#Impact

  • The native browser dialog doesn't match the app's visual design, which is a usability issue but not by itself an accessibility one.
  • More importantly, a native browser dialog sits outside Canvas Apps' own control tree. SetFocus(), custom tab order, and screen reader labeling patterns used elsewhere in the app (see Quick Fix 1 and Quick Fix 2) don't apply to it, so accessibility behavior for this dialog can't be controlled or guaranteed the way it can for an in-app modal.
  • Behavior may vary by browser, since native window.confirm() rendering and keyboard handling are controlled by the browser itself, not by Power Apps.

#Solution

Replace Confirm() with a custom overlay modal:

  • Build the modal from a container (or group of containers) that overlays the screen, with Visible controlled by a variable rather than the built-in Confirm() function.
  • Apply the same focus-management pattern from Quick Fix 2: call SetFocus() on the modal's primary control when it becomes visible.
  • Style the modal to match the rest of the app, and explicitly set accessible labels on its buttons (for example, clear AccessibleLabel values on "Yes"/"No" or "Confirm"/"Cancel" buttons) rather than relying on default button text alone.
  • Use the container-based tab order approach from Quick Fix 1 to keep keyboard order predictable inside the modal.
  • After the modal closes, return keyboard focus to the control that opened it.

#Implementation Guidance

  1. Create a container that will act as the confirmation overlay, initially set to Visible: false.
  2. Add a semi-transparent background rectangle behind the modal content to visually indicate the rest of the screen is inactive, matching the effect a native dialog would have.
  3. Add the confirmation message as a label, and two buttons for the confirm/cancel actions, inside the container.
  4. Trigger the modal by setting a variable (for example, Set(varShowDuplicateConfirm, true)) instead of calling Confirm(), and bind the container's Visible property to that variable.
  5. Since containers don't have their own OnVisible property, trigger SetFocus() using the mechanism your app uses after the modal becomes visible (for example, from the triggering control, a timer, or another visibility-driven pattern). Verify during testing that focus actually lands on the primary action button; calling SetFocus() in the same step that sets the visibility variable can race ahead of the control actually becoming visible.
  6. Set explicit AccessibleLabel values on both buttons so a screen reader announces their purpose clearly, not just "Button."
  7. On each button's OnSelect, reset the visibility variable to close the modal and route to the corresponding Yes/No logic.
  8. Test the full flow with the keyboard and a screen reader: opening the modal should move focus into it, both buttons should be reachable and clearly announced, and closing the modal should return focus sensibly to the triggering control.

#Example

Illustrative example: the exact placement of SetFocus() depends on how the app makes the modal visible.

// Trigger button
Set(varShowDuplicateConfirm, true);

// Modal container
Visible: varShowDuplicateConfirm

// Once the modal is visible,
// move focus to the primary action button
SetFocus(btnConfirmYes)

// Confirm button
AccessibleLabel: "Confirm duplicate SME entry"
OnSelect:
Set(varShowDuplicateConfirm, false);
// proceed with save logic

// Cancel button
AccessibleLabel: "Cancel and return to form"
OnSelect:
Set(varShowDuplicateConfirm, false)

Containers don't have their own OnVisible property, so the SetFocus() call above needs to be wired through whatever mechanism your app uses once the modal actually becomes visible, for example the triggering control, a timer, or another visibility-driven pattern. Verify during testing that focus actually lands on the button rather than firing before it's visible.

#Media

None yet. A screenshot comparing the native browser Confirm() dialog to the custom overlay modal should be added here.

#Platform limitation

Microsoft's accessibility guidance for Canvas Apps notes that overlay-style dialogs are not fully supported for accessibility and recommends using a separate screen or Notify where appropriate.

The custom overlay modal described in this guide is a practical workaround for the CMS GCC Confirm() behavior, but it should be validated with keyboard-only navigation and screen readers before production deployment.

#Open items

  • Confirm whether Confirm() rendering as a native browser dialog is a general GCC platform behavior or specific to the CMS tenant; this has not been independently verified against Microsoft documentation.
  • This pattern has not yet been validated in production. Test with keyboard-only navigation and a screen reader before relying on it for a production deployment.

#References

#Notes

  • This issue is easy to miss during development if testing happens in a browser where the native dialog still looks "fine." The accessibility gap only becomes apparent when testing with a screen reader or reviewing focus behavior directly.
  • This pattern builds directly on Quick Fix 1 (container-based tab order) and Quick Fix 2 (SetFocus() for modals); build those patterns first if they aren't already in place, since the custom Confirm() replacement depends on them.
power-platformcanvas-appsaccessibilitysection-508gccconfirmmodalduplicate-detection