I have an animation which works well in Chrome but not in IE. I expect to slide a panel in from outside the browser window into view and then once the exit button or <div>
which covers the rest of the page is clicked, the panel will animate off the screen and out of view. However, the actual result is that the whole page is transformed and not the specific element.
View demonstrations below:
Chrome (works fine; animation is smooth):
IE (bug; entire page is moved):
EDIT
So I have found the reason why this is happening and it is because of an *ngFor
when rendering HTML inside of the container
. If I remove the ngFor
completely and all other property bindings, the animation runs as expected (as demonstrated in the Chrome GIF).
I didn't add this code to the question initially because I wouldn't have thought that some *ngFor
logic would break the CSS.
So my question is, why is the *ngFor
breaking the animation and how do I fix it?
Code:
side-bar-component.ts:
animations: [
trigger('animateInOutTrigger', [
transition(':enter', [
style({ transform: 'translateX(0%)' }),
animate('0.3s', style({ transform: 'translateX(-100%)' }))
]),
transition(':leave', [
animate('0.3s', style({ transform: 'translateX(0%)' }))
])
]),
trigger('fadeScrim', [
transition(':enter', [
style({ transform: 'opacity: 0' }),
animate('0.3s', style({ opacity: '1' }))
]),
transition(':leave', [
animate('0.3s', style({ opacity: '0' }))
]),
]),
side-bar-component.html:
<div id="btn-scrim" *ngIf="windowWidth >= 768 && open" class="scrim" (click)="onCloseSideBar()" @fadeScrim></div>
<div *ngIf="windowWidth >= 768 && open" class="sidebar-wrapper">
<div @animateInOutTrigger class="container">
<div class="header">
<span class="text">Claim Details</span>
<span id="btn-close-sidebar-desktop" (click)="onCloseSideBar()">X</span>
</div>
<div class="claims claims-padding">
<hr-claim-detail [id]="'claim-scroller-' + element.claim_id" *ngFor="let element of group.data" [element]="element (update)="updateAndClose()" [windowWidth]="windowWidth" [token]="token [logConfig]="logConfig">
</hr-claim-detail>
</div>
</div>
side-bar-component.scss:
.sidebar-wrapper {
position: absolute;
width: 100%;
height: 100%;
top: 0;
right: 0;
transform: translateX(100%);
z-index: 2;
}
.container {
height: 100%;
position: absolute;
top: 0;
box-sizing: border-box;
background-color: white;
box-shadow: 0 8px 10px -5px rgba(0, 0, 0, 0.2), 0 6px 30px 5px rgba(0, 0, 0, 0.12), 0 16px 24px 2px rgba(0, 0, 0, 0.14);
z-index: 2;
display: flex;
flex-direction: column;
transform: translateX(-100%);
}
.scrim {
width: 100%;
height: 100%;
background: rgba(0, 0, 0, .32);
position: absolute;
z-index: 1;
top: 0;
left: 0;
}
.header {
height: 56px;
background-color: #333333;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24px;
color: white;
position: relative;
z-index: 2;
}
.text {
font-size: 16px;
font-weight: 500;
}
.claims {
height: 100%;
overflow-y: scroll;
-ms-overflow-style: none;
box-sizing: border-box;
flex: 1;
}
.claims-padding {
padding-bottom: 25vh;
}
STACKBLITZ RECREATION: https://stackblitz.com/edit/angular-ven7eu
I've tried:
state
to control the transition instead of using :enter
and :leave
Other information:
The problem was fixed by using fixed
positioning and then programmatically setting the margin-top
equal to getBoundingClientRect().top
of the main content container.
I still do not understand why using absolute
positioning in this scenario won't work.