Skip to content

bug(MatDrawer): Resizing drawer after 'mat-drawer-transition' class added causes animation lag #24119

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
1 task
andrewalderson opened this issue Dec 18, 2021 · 6 comments
Labels
area: material/sidenav needs: clarification The issue does not contain enough information for the team to determine if it is a real bug

Comments

@andrewalderson
Copy link

Is this a regression?

  • Yes, this behavior used to work in the previous version

The previous version in which this bug was not present was

No response

Description

Currently the MatDrawer component is able to resize the content when the size of the drawer changes. This works great unless you add an animation to the drawer's width after the 'mat-drawer-transition' class has been added to the drawer container. After the class has been added the animation for the drawer content lags behind the animation for the drawer width.

Currently all of the hacks and work arounds I have seen for this behavior don't take into account resizing after the drawer has been toggled open and closed. Toggling the drawer adds a class called 'mat-drawer-transition' to the drawer container in the _watchDrawerToggle method of MatDrawerContainer. This class adds the css transitions for the drawer content and backdrop and these animations seem to cause the issue. Also setting the autosize property on the drawer container does nothing in this instance.

In the sample I provided I use an inner component in the drawer to do the resizing. This encapsulates the behavior and causes the drawer itself to resize. I also use a ResizeObserver (because it is almost 2022 and we don't support IE anymore) to update the content margins continually during the width animation. I have also not used the autosize property on the drawer container because it doesn't do anything to fix the issue and the content margins are being updated during the width animation.

In my experiments removing the 'mat-drawer-transition' class after the drawer open/close animation completes fixes the issue.

Reproduction

Stackblitz of the issue is here: https://stackblitz.com/edit/angular-ivy-ftfajt?file=src%2Fapp%2Fapp.component.ts
Steps to reproduce:

  1. Launch the Stackblitz sample
  2. Toggle the size of the drawer with the arrow icon at the top of the drawer - Animation works correctly
  3. Toggle the drawer open and closed with the menu icon at the top of the content - Animation works correctly
  4. Repeat step 2 - Animation for the content left margin lags behind the animation for the drawer.

To see it working properly uncomment the code in the AppComponent openChanged method and run steps again.

Expected Behavior

The animation for the drawer should not lag behind the animation for the content.

Actual Behavior

The animation for the content lags behind the animation for the drawer when the 'mat-drawer-transition' class is present on the MatDrawerContainer.

Environment

  • Angular: 13.1.1
  • CDK/Material: 13.1.1
  • Browser(s): Edge (Chromium) 96.0.1054.57
  • Operating System: Windows 11
@andrewalderson andrewalderson added the needs triage This issue needs to be triaged by the team label Dec 18, 2021
@crisbeto
Copy link
Member

I also use a ResizeObserver (because it is almost 2022 and we don't support IE anymore) to update the content margins continually during the width animation.

I think that this is the problem. Since you're calling updateContentMargins on each resize callback, it'll trigger another resize callback and the subsequent transition which gets compounded over each animation frame and causes the slowdown. It might be better to do this once only when the sidenav is opened/closed.

@andrewalderson
Copy link
Author

@crisbeto I don't know what you mean by compounding the animations. The updateContentMargins just recalculates the margins of the content, it doesn't create animations. Could you explain what you mean a little more.

I have tried all different ways to get this to work correctly and I am not convinced that the api for autosizing the drawer works correctly or at least doesn't work correctly when an animation is applied to the drawer width. I would appreciate a little guidance from the team on whether this api is meant to be used like this.

@crisbeto
Copy link
Member

updateContentMargins changes the margin on the content element which has a transition on margin-left and margin-right. Furthermore, it causes it to resize which will fire the ResizeObserver again, causing another update in the margin.

@crisbeto crisbeto added area: material/sidenav needs: clarification The issue does not contain enough information for the team to determine if it is a real bug and removed needs triage This issue needs to be triaged by the team labels Dec 20, 2021
@andrewalderson
Copy link
Author

andrewalderson commented Dec 20, 2021

Okay, I understand this now. I misunderstood how this would work. I still don't understand why the public api updateContentMargins is needed. There seems to be a timing issue between the animation starting and updating the content margins to the correct value. I have yet to figure out the correct time to call updateContentMargins without resorting to adding what I consider unnecessary code.

That being said there is still an issue with adding an animation to the width of the drawer but after search some more I realize that this is a long-standing issue as seen here #9837 (comment)

As commented in that issue #9837 (comment) I am using the requestAnimationFrame hack to overcome this issue.

I am closing this as it is now a duplicate of another issue.

@crisbeto
Copy link
Member

For context, updateContentMargins was added so that consumers can update the margins themselves if the library isn't able to pick to do it automatically. Previously we would miss some updates, because catching them efficiently was difficult. Now that we can use ResizeObserver, most of these cases can be handled internally.

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Jan 21, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: material/sidenav needs: clarification The issue does not contain enough information for the team to determine if it is a real bug
Projects
None yet
Development

No branches or pull requests

2 participants