Skip to content

bug: ion-toast does not remove backdrop-no-scroll from body when dismiss #30112

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
3 tasks done
tobiloeb opened this issue Jan 7, 2025 · 14 comments · Fixed by #30123
Closed
3 tasks done

bug: ion-toast does not remove backdrop-no-scroll from body when dismiss #30112

tobiloeb opened this issue Jan 7, 2025 · 14 comments · Fixed by #30123
Labels
package: core @ionic/core package type: bug a confirmed bug report

Comments

@tobiloeb
Copy link
Contributor

tobiloeb commented Jan 7, 2025

Prerequisites

Ionic Framework Version

v8.x

Current Behavior

We are currently migrating to Ionic 8.4.1 from Ionic 7 with Angular 18.2.

Now we are facing following issue with ion-toast:
When an ion-toast will be present the css class "backdrop-no-scroll" is added to the body. And the class will be removed from body after the toast dismiss. This was the behaviour with Ionic 7 and with Ionic 8. But with Ionic 8.4.1 the class stay there and is not removed from body after the toast dismiss.

For me this seems to be a bug and I am able to reproduce this very easy. With the following code you can reproduce the issue. Just take a look at the HTML (body in iframe). After you change the ionic version to 8.4.1 in the package.json and reload the code you see the difference.

In case this is a new feature or I did something wrong, maybe someone can tell me how to remove this class on my one. :)

Expected Behavior

The "backdrop-no-scroll" css class is removed from body when toast dismiss.

Steps to Reproduce

  1. Got to: https://stackblitz.com/edit/angular-ywh4p1-cszqn3rp
  2. Take a look at the HTML, the class is removed from body after the toast dismiss (in the iframe)
  3. Go to package.json and set ionic version to 8.4.1 - wait for loading dependencies
  4. Reload the page and take a look at the body tag (in the iframe) again.

Code Reproduction URL

https://stackblitz.com/edit/angular-ywh4p1-cszqn3rp

Ionic Info

Ionic:

Ionic CLI : 7.2.0 (/Users/tobias/.nvm/versions/node/v22.11.0/lib/node_modules/@ionic/cli)
Ionic Framework : @ionic/angular 8.4.1
@angular-devkit/build-angular : 18.2.12
@angular-devkit/schematics : 18.2.12
@angular/cli : 18.2.12
@ionic/angular-toolkit : 12.1.1

Capacitor:

Capacitor CLI : 5.7.0
@capacitor/android : 5.7.0
@capacitor/core : 5.7.0
@capacitor/ios : 5.7.0

Cordova:

Cordova CLI : not installed
Cordova Platforms : not available
Cordova Plugins : not available

Utility:

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

Additional Information

No response

@ionitron-bot ionitron-bot bot added the triage label Jan 7, 2025
@tobiloeb
Copy link
Contributor Author

tobiloeb commented Jan 8, 2025

I dig deeper to the overlay.ts in ionic/core and found some changes 3 month ago. This is the issue to the changes: #29773
Without this changes (Version 8.3.3) the "backdrop-no-scroll" is removed from body after the toast dismiss.
With version 8.3.3 I am facing the issue.

@thetaPC Is it possible that the changes 3 month ago in overlay.ts result in this behavior? Thanks :)

@thetaPC
Copy link
Contributor

thetaPC commented Jan 9, 2025

Thank you for submitting the issue!

I do see the issue in the provided StackBlitz but I couldn't replicate it through the examples provided on the Ionic docs.

I would recommend reviewing the docs. If the issue still persists after that, please provide minimal reproduction that only includes the toast component.

Thanks!

@tobiloeb
Copy link
Contributor Author

tobiloeb commented Jan 9, 2025

Thanks for you fast reply! Good point, I did't think about the examples from the docs. But I can reproduce the issue with the docs example as well. I just had to click on the StackBlitz icon in the example. :)

After short debugging, I may see the root cause of this. The new changes made 3 month ago, checks that the last overlay is NOT a toast. And just in case the last overlay is NOT a toast the aria hidden attribute is set to false AND the backdrop-no-scroll is removed from body tag.
Before these changes, both is done for every overlay.

When I got it right, only the aria hidden attribute should not be set to false in case the last overlay is a toast, but the backdrop-no-scroll, should be removed anyway. Right?

tobiloeb added a commit to tobiloeb/ionic-framework that referenced this issue Jan 9, 2025
In case last overlay is a toast, the backdrop-no-scroll css class is removed from body.

closes ionic-team#30112
@thetaPC
Copy link
Contributor

thetaPC commented Jan 10, 2025

@tobiloeb Please provide the playground link that showcases the issue. I'm still unable to reproduce it and that might due to us not looking at the same playground.

@tobiloeb
Copy link
Contributor Author

Sure: https://stackblitz.com/edit/v9suj8rk (I used the link from the ionic docs for controller toast with angular)

I wrote a short unit test to reproduce the issue, its included in my PR. :)

@ivevangenechten
Copy link

I was facing the same problem. I believe the main issue is that a toast shouldn’t have a focus trap and shouldn't block the body. Instead of fixing the backdrop-no-scroll class removal on dismiss, I think it shouldn’t be added on present in the first place.

Looking at the code:
present: https://github.com/ionic-team/ionic-framework/blob/main/core/src/utils/overlays.ts#L521
dismiss: https://github.com/ionic-team/ionic-framework/blob/main/core/src/utils/overlays.ts#L668

It looks like the document.body.classList.add(BACKDROP_NO_SCROLL); line should be inside the (overlay.el.tagName !== 'ION-TOAST') condition on present. This would prevent the body from being unnecessarily blocked when a toast is displayed.

@tobiloeb
Copy link
Contributor Author

@ivevangenechten Good question, I don't know whats the desired behaviour of the ionic team. I just saw that the removal of "backdrop_no_scroll" class changed and does't work correctly anymore until this. Thats why I add the PR. 🙂

@henkkelder
Copy link

henkkelder commented Mar 21, 2025

I see the same behaviour. I have a ion-list showing calendar items. These are seminars, performances, etc, that take place at a big festival.
The app shows a [goto now] button. But when 'now' is before the actual start of the festival the list scrolls to a example day and time and shows a toast informing the user that the festival hasn't started yet.

After that the ion-list cannot be scrolled anymore.

Reading this I added code to remove that 'backdrop-no-scroll' class from the body after the toast is shown. And now scrolling works again.

public showMessage(message: string, color?: string, duration?: number): void {

    duration = duration || 2000;
    if (color === "danger") {
      duration = 5000;
    }
    this.showToast(message, duration, color).then(() => {

      // bug ionic. 21-03-2025
      const body = document.querySelector("body");
      body.classList.remove("backdrop-no-scroll");
    });
  }

  private async showToast(message: string, duration: number, color?: string): Promise<any> {
    const t: any = await this.toast.create({
      message: message,
      position: "bottom",
      duration: duration,
      color: color || "dark"
    });
    return await t.present();
  }

@thetaPC
Copy link
Contributor

thetaPC commented Mar 21, 2025

Apologies on the late response! I was able to replicate this issue. The cause of this comes from not removing the class at the right time. It should remove be removing it when the last overlay is dismissed, including toasts. We'll look into getting a solution released.

@thetaPC thetaPC added the type: bug a confirmed bug report label Mar 21, 2025
@ionitron-bot ionitron-bot bot removed the triage label Mar 21, 2025
@thetaPC thetaPC added triage package: core @ionic/core package labels Mar 21, 2025
@ionitron-bot ionitron-bot bot removed the triage label Mar 21, 2025
@ivevangenechten
Copy link

@thetaPC , thank you for looking into this! As mentioned earlier, I don’t believe removing the class is the root issue. In my view, the class shouldn’t be added in the first place. I understand the logic behind this for other overlays, but toasts are intended to be subtle notifications that shouldn’t interrupt the user.

For reference, please see the following comments, which further support this approach:

/**
* Due to accessibility guidelines, toasts do not have
* focus traps.
*
* All other overlays should have focus traps to prevent
* the keyboard focus from leaving the overlay.
*/
if (overlay.el.tagName !== 'ION-TOAST') {
setRootAriaHidden(true);
}
document.body.classList.add(BACKDROP_NO_SCROLL);

Additionally, this aligns with the documentation, which states that toasts should not block user interaction:
https://ionicframework.com/docs/api/toast#dismissing

I hope this clarification helps, and I look forward to the final solution!

@thetaPC
Copy link
Contributor

thetaPC commented Mar 25, 2025

@ivevangenechten I've looked into this further and agree that the class should never be added when using toast. I've updated the PR that @tobiloeb submitted to take that into account.

github-merge-queue bot pushed a commit that referenced this issue Apr 1, 2025
…ed (#30123)

Issue number: resolves #30112 

---------

<!-- Please do not submit updates to dependencies unless it fixes an
issue. -->

<!-- Please try to limit your pull request to one type (bugfix, feature,
etc). Submit multiple pull requests if needed. -->

## What is the current behavior?

When toast is presented, the `backdrop-no-scroll` class is added to the
body when using Frameworks like Angular. It should not add this class as
toast does not be setting focus trap as mentioned in the
[comments](https://github.com/ionic-team/ionic-framework/blob/1cfa915e8fe362951c521bce970a9f5f10918ab2/core/src/utils/overlays.ts#L514-L520).

## What is the new behavior?

- Class is only added when the overlay that is presented is not a toast
component.
- Test was added.

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!--
  If this introduces a breaking change:
1. Describe the impact and migration path for existing applications
below.
  2. Update the BREAKING.md file with the breaking change.
3. Add "BREAKING CHANGE: [...]" to the commit description when merging.
See
https://github.com/ionic-team/ionic-framework/blob/main/docs/CONTRIBUTING.md#footer
for more information.
-->


## Other information

N/A

---------

Co-authored-by: Maria Hutt <[email protected]>
@thetaPC
Copy link
Contributor

thetaPC commented Apr 1, 2025

Thanks for the issue! This has been resolved via PR #30123 and will be available in an upcoming release of Ionic.

@thetaPC
Copy link
Contributor

thetaPC commented Apr 2, 2025

This issue was fixed in v8.5.3! Please update to the latest version to receive the fix.

Copy link

ionitron-bot bot commented May 2, 2025

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.

@ionitron-bot ionitron-bot bot locked and limited conversation to collaborators May 2, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
package: core @ionic/core package type: bug a confirmed bug report
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants