I'm building a custom dropdown. The real thing is going to have all the necessary ARIA attributes of course, but here's the barebones version:
[...document.querySelectorAll('.select')].forEach(select => {
select.addEventListener('click', function() {
select.nextElementSibling.classList.toggle('visible');
});
});
.dropdown {
position: relative;
width: 16rem;
margin-bottom: 2rem;
}
.select {
display: flex;
align-items: center;
height: 2rem;
background-color: #ccc;
}
.popup {
display: none;
position: absolute;
left: 0;
right: 0;
height: 10rem;
background-color: #eee;
box-shadow: 0 0 0.5rem red;
}
.popup.visible {
display: block;
}
<!doctype html>
<html>
<body>
<div class="dropdown">
<div class="select">Button 1 ▼</div>
<div class="popup">Popup 1</div>
</div>
<div class="dropdown">
<div class="select">Button 2 ▼</div>
<div class="popup">Popup 2</div>
</div>
</body>
</html>
The obvious issue is that, when you open the first dropdown, popup 1 appears behind button 2. The obvious solution would be to give .popup
a z-index
, and make it an absurdly large value like 999
to make sure it appears above other elements on the page as well.
However, in my case, I would also like the popup to appear behind its corresponding button (in order to hide its box-shadow
).
If I give the button a z-index
greater than the popup's, the original problem returns: popup 1 appears behind button 2. If I instead give the z-index: 999
to the entire .dropdown
and create a new stacking context, the same thing happens.
Is there any way I can meet my two requirements at the same time (popup behind its button, and only that one, but above everything else on the page)?