While creating a drop-down menu and a confirmation dialog, I encountered the same issue of wanting to dismiss them when clicking outside.
After some trial and error, I came up with a final implementation that works perfectly, albeit requiring some CSS3 animations and styling.
Disclaimer: The code below has not been tested thoroughly, so there might be syntax issues that need to be fixed. Additionally, you will need to make adjustments based on your own project requirements!
Here's what I did:
I created a separate fixed div with dimensions set to 100% height and width, along with transform:scale(0)
. This serves as the background, which can be styled using
background-color: rgba(0, 0, 0, 0.466);
to indicate that the menu is open and can be closed by clicking on the background.
The menu was assigned a higher z-index than other elements, while the background div had a z-index lower than the menu but still higher than everything else. The background div also had a click event that closed the drop-down when triggered.
Below is the HTML part of it:
<div class="dropdownbackground" [ngClass]="{showbackground: qtydropdownOpened}" (click)="qtydropdownOpened = !qtydropdownOpened"><div>
<div class="zindex" [class.open]="qtydropdownOpened">
<button (click)="qtydropdownOpened = !qtydropdownOpened" type="button"
data-toggle="dropdown" aria-haspopup="true" [attr.aria-expanded]="qtydropdownOpened ? 'true': 'false' ">
{{selectedqty}}<span class="caret margin-left-1x "></span>
</button>
<div class="dropdown-wrp dropdown-menu">
<ul class="default-dropdown">
<li *ngFor="let quantity of quantities">
<a (click)="qtydropdownOpened = !qtydropdownOpened;setQuantity(quantity)">{{quantity }}</a>
</li>
</ul>
</div>
</div>
Additionally, here are the CSS3 styles for implementing simple animations:
/* ensure the menu/drop-down appears in front of the background */
.zindex{
z-index: 3;
}
/* make the background cover the entire page while sitting behind the drop-down, then
scale it to 0 to essentially remove it from view */
.dropdownbackground{
width: 100%;
height: 100%;
position: fixed;
z-index: 2;
transform: scale(0);
opacity: 0;
background-color: rgba(0, 0, 0, 0.466);
}
/* this class is added in the template when the drop down is opened
and includes animation rules - customize these based on your preferences */
.showbackground{
animation: showBackGround 0.4s 1 forwards;
}
/* animates the background to fill the page
you could opt for a transition instead if no visual effect is desired */
@keyframes showBackGround {
1%{
transform: scale(1);
opacity: 0;
}
100% {
transform: scale(1);
opacity: 1;
}
}
If you prefer minimal visual effects, a transition like the one below can be used:
.dropdownbackground{
width: 100%;
height: 100%;
position: fixed;
z-index: 2;
transform: scale(0);
opacity: 0;
transition all 0.1s;
}
.dropdownbackground.showbackground{
transform: scale(1);
}