fix(popover): blur translucent popover in chromium (#27484)

Issue number: Resolves #22176

---------

<!-- 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?
<!-- Please describe the current behavior that you are modifying. -->
Translucent popovers do not get blurred in Chromium

## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->

- Translucent popover gets blurred in Chromium

Note: existing screenshot tests nicely show the change in behavior.

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->


## Other information 

Because of the [existing, apparently
intentional](https://bugs.chromium.org/p/chromium/issues/detail?id=1148826)
behavior in Chromium browsers with `backdrop-filter` and animation, we
need to either animate the arrow and content instead of the wrapper or
apply the filter to a different element. Here, I've animated the arrow
and content instead of the wrapper.

The fix only needs to apply in `ios` mode. The translucent option is not
supported in `md` mode.

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->

---------

Co-authored-by: ionitron <hi@ionicframework.com>
This commit is contained in:
Shawn Taylor
2023-05-18 09:02:52 -04:00
committed by GitHub
parent 995a848575
commit a59eefb6a3
6 changed files with 26 additions and 7 deletions

View File

@ -85,7 +85,7 @@ export const iosEnterAnimation = (baseEl: HTMLElement, opts?: any): Animation =>
const baseAnimation = createAnimation();
const backdropAnimation = createAnimation();
const wrapperAnimation = createAnimation();
const contentAnimation = createAnimation();
backdropAnimation
.addElement(root.querySelector('ion-backdrop')!)
@ -95,7 +95,15 @@ export const iosEnterAnimation = (baseEl: HTMLElement, opts?: any): Animation =>
})
.afterClearStyles(['pointer-events']);
wrapperAnimation.addElement(root.querySelector('.popover-wrapper')!).fromTo('opacity', 0.01, 1);
// In Chromium, if the wrapper animates, the backdrop filter doesn't work.
// The Chromium team stated that this behavior is expected and not a bug. The element animating opacity creates a backdrop root for the backdrop-filter.
// To get around this, instead of animating the wrapper, animate both the arrow and content.
// https://bugs.chromium.org/p/chromium/issues/detail?id=1148826
contentAnimation
.addElement(root.querySelector('.popover-arrow')!)
.addElement(root.querySelector('.popover-content')!)
.fromTo('opacity', 0.01, 1);
// TODO(FW-4376) Ensure that arrow also blurs when translucent
return baseAnimation
.easing('ease')
@ -141,5 +149,5 @@ export const iosEnterAnimation = (baseEl: HTMLElement, opts?: any): Animation =>
}
}
})
.addAnimation([backdropAnimation, wrapperAnimation]);
.addAnimation([backdropAnimation, contentAnimation]);
};

View File

@ -12,11 +12,14 @@ export const iosLeaveAnimation = (baseEl: HTMLElement): Animation => {
const baseAnimation = createAnimation();
const backdropAnimation = createAnimation();
const wrapperAnimation = createAnimation();
const contentAnimation = createAnimation();
backdropAnimation.addElement(root.querySelector('ion-backdrop')!).fromTo('opacity', 'var(--backdrop-opacity)', 0);
wrapperAnimation.addElement(root.querySelector('.popover-wrapper')!).fromTo('opacity', 0.99, 0);
contentAnimation
.addElement(root.querySelector('.popover-arrow')!)
.addElement(root.querySelector('.popover-content')!)
.fromTo('opacity', 0.99, 0);
return baseAnimation
.easing('ease')
@ -36,5 +39,5 @@ export const iosLeaveAnimation = (baseEl: HTMLElement): Animation => {
}
})
.duration(300)
.addAnimation([backdropAnimation, wrapperAnimation]);
.addAnimation([backdropAnimation, contentAnimation]);
};

View File

@ -89,6 +89,11 @@
transform: rotate(-90deg);
}
.popover-arrow,
.popover-content {
opacity: 0;
}
// Translucent Popover
// -----------------------------------------

View File

@ -19,3 +19,7 @@
.popover-viewport {
transition-delay: 100ms;
}
.popover-wrapper {
opacity: 0;
}

View File

@ -68,7 +68,6 @@
}
.popover-wrapper {
opacity: 0;
z-index: $z-index-overlay-wrapper;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 35 KiB