Skip to content

bug: ion-router-outlet not marked aria-hidden when multiple overlays are presented and some dismissed #28180

@nagashimam

Description

@nagashimam

Prerequisites

Ionic Framework Version

v7.x

Current Behavior

When multiple overlays are presented, and some of them are dismissed, the ion-router-outlet element isn't marked as aria-hidden.

As a result, assistive technologies like screen readers can access contents within the ion-router-outlet element, even though they are visually obscured by the remaining overlays.

Expected Behavior

The ion-router-outlet element should remain marked as aria-hidden even after some of the overlays are dismissed, and it should be marked as not aria-hidden only after all overlays are dismissed.

Steps to Reproduce

To reproduce the bug, follow these steps:

  1. Access the StackBlitz page.

    • At this point, confirm that ion-router-outlet isn't marked as aria-hidden.
  2. Click the "OPEN ION-MODAL" button.

    • Confirm that ion-router-outlet is marked as aria-hidden.
  3. Click the "OPEN ION-ALERT" button.

    • Once again, confirm that ion-router-outlet is marked as aria-hidden.
  4. Click the "OK" button.

    • Now, confirm that ion-router-outlet is NOT marked as aria-hidden.

Code Reproduction URL

StackBlitz
GitHub repo

Ionic Info

Ionic:

Ionic CLI : 7.1.1 (/Users/mac/.anyenv/envs/nodenv/versions/18.17.1/lib/node_modules/@ionic/cli)
Ionic Framework : @ionic/angular 7.3.3
@angular-devkit/build-angular : 16.2.1
@angular-devkit/schematics : 16.2.1
@angular/cli : 16.2.1
@ionic/angular-toolkit : 9.0.0

Capacitor:

Capacitor CLI : 5.3.0
@capacitor/android : not installed
@capacitor/core : 5.3.0
@capacitor/ios : not installed

Utility:

cordova-res : not installed globally
native-run : 1.7.2

System:

NodeJS : v18.17.1 (/Users/mac/.anyenv/envs/nodenv/versions/18.17.1/bin/node)
npm : 9.6.7
OS : macOS Big Sur

Additional Information

Suggestions on how to fix

Currently, the dismiss function always calls setRootAriaHidden(false) in the ionic-framework/core/src/utils/overlays.ts file:

export const setRootAriaHidden = (hidden = false) => {
  // ...
};

export const dismiss = async <OverlayDismissOptions>(
  // ...
): Promise<boolean> => {
  // ...
  setRootAriaHidden(false);
}

To address the issue, we should consider calling setRootAriaHidden(false) only when there's a single overlay remaining:

export const dismiss = async <OverlayDismissOptions>(
  // ...
): Promise<boolean> => {
  // ...
  const overlays = getOverlays(document);
  if (overlays.length === 1) {
    setRootAriaHidden(false);
  }
}

This change ensures that the ion-router-outlet element is marked as not aria-hidden only when the last overlay is dismissed, which aligns with the expected behavior.

Screen Recordings

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions