I'm having a problem in a project I'm working on with z-index.
I have several components which all have a dropdown. The problem I have is that the dropdown from the first components goes under the dropdown button of the second and this makes the content partially hidden.
I basically need the first dropdown to have the highest z-index. But as I'm styling them all the same, they all have the same z-index.
I'd like to solve this without JavaScript where I have to dynamically change the z-index or the solution with flexbox that's attached to the code snippet.
const dropdowns = document.querySelectorAll('.app-item-dropdown');
dropdowns.forEach((item) => {
item.querySelector('button').addEventListener('click', function() {
this.nextElementSibling.parentNode.classList.toggle('expanded')
})
})
:root {
--z1: 1;
--z2: 2;
--z3: 3;
--z4: 4;
--z5: 5;
}
html {
box-sizing: border-box;
}
*, *:after, *:before {
box-sizing: inherit;
}
body {
background: lightgrey;
text-align: center;
}
ul {
margin: 0; padding: 0; list-style: none;
}
.container {
max-width: 960px; margin: 0 auto; border: 1px solid red;
padding: 24px;
}
.solution {
display: flex;
flex-direction: column-reverse;
}
.app-item {
border: 1px solid yellow;
min-height: 150px;
background: grey;
position: relative;
margin: 24px;
}
.app-item-dropdown {
position: absolute;
width: 272px;
top: 16px;
right: 16px;
background: white;
z-index: var(--z2);
}
.app-item-dropdown ul {
display: none;
position:relative;
z-index: var(--z4);
}
.app-item-dropdown ul li {
padding: 4px 8px;
}
.app-item-dropdown.expanded ul{
display: block;
}
.lightblue {
background: lightblue;
}
.lightsalmon {
background: lightsalmon;
}
<div id="wrapper" class="container problem">
<div class="app-item">
<h2>1</h2>
<div class="app-item-dropdown">
<button>click</button>
<div class="box">
<ul>
<li>hello</li>
<li>hello</li>
<li>hellohello</li>
<li>hello</li>
<li>hello</li>
<li>hello</li>
<li>hehellohellollo</li>
<li>hello</li>
<li>helhellolo</li>
<li>hello</li>
</ul>
</div>
</div>
</div>
<div class="app-item">
<h2>2</h2>
<div class="app-item-dropdown lightblue">
<button>click</button>
<div class="box">
<ul>
<li>hello</li>
<li>hello</li>
<li>hellohello</li>
<li>hello</li>
<li>hello</li>
<li>hello</li>
<li>hehellohellollo</li>
<li>hello</li>
<li>helhellolo</li>
<li>hello</li>
</ul>
</div>
</div>
</div>
<div class="app-item">
<h2>3</h2>
<div class="app-item-dropdown lightsalmon">
<button>click</button>
<div class="box">
<ul>
<li>hello</li>
<li>hello</li>
<li>hellohello</li>
<li>hello</li>
<li>hello</li>
<li>hello</li>
<li>hehellohellollo</li>
<li>hello</li>
<li>helhellolo</li>
<li>hello</li>
</ul>
</div>
</div>
</div>
</div>
<hr>
<h1>Solution</h1>
<h2>With <code>flex-direction: column-reverse</code> </h2>
<div id="wrapper2" class="container solution">
<div class="app-item">
<h2>1</h2>
<div class="app-item-dropdown">
<button>click</button>
<div class="box">
<ul>
<li>hello</li>
<li>hello</li>
<li>hellohello</li>
<li>hello</li>
<li>hello</li>
<li>hello</li>
<li>hehellohellollo</li>
<li>hello</li>
<li>helhellolo</li>
<li>hello</li>
</ul>
</div>
</div>
</div>
<div class="app-item">
<h2>2</h2>
<div class="app-item-dropdown lightblue">
<button>click</button>
<div class="box">
<ul>
<li>hello</li>
<li>hello</li>
<li>hellohello</li>
<li>hello</li>
<li>hello</li>
<li>hello</li>
<li>hehellohellollo</li>
<li>hello</li>
<li>helhellolo</li>
<li>hello</li>
</ul>
</div>
</div>
</div>
<div class="app-item">
<h2>3</h2>
<div class="app-item-dropdown lightsalmon">
<button>click</button>
<div class="box">
<ul>
<li>hello</li>
<li>hello</li>
<li>hellohello</li>
<li>hello</li>
<li>hello</li>
<li>hello</li>
<li>hehellohellollo</li>
<li>hello</li>
<li>helhellolo</li>
<li>hello</li>
</ul>
</div>
</div>
</div>
</div>
Set the z-index of the class you're adding on click higher than the z-index of the existing elements.
const dropdowns = document.querySelectorAll('.app-item-dropdown');
dropdowns.forEach((item) => {
item.querySelector('button').addEventListener('click', function() {
this.nextElementSibling.parentNode.classList.toggle('expanded')
})
})
:root {
--z1: 1;
--z2: 2;
--z3: 3;
--z4: 4;
--z5: 5;
}
html {
box-sizing: border-box;
}
*, *:after, *:before {
box-sizing: inherit;
}
body {
background: lightgrey;
text-align: center;
}
ul {
margin: 0; padding: 0; list-style: none;
}
.container {
max-width: 960px; margin: 0 auto; border: 1px solid red;
padding: 24px;
}
.solution {
display: flex;
flex-direction: column-reverse;
}
.app-item {
border: 1px solid yellow;
min-height: 150px;
background: grey;
position: relative;
margin: 24px;
}
.app-item-dropdown {
position: absolute;
width: 272px;
top: 16px;
right: 16px;
background: white;
z-index: var(--z2);
}
.app-item-dropdown ul {
display: none;
position:relative;
z-index: var(--z4);
}
.app-item-dropdown ul li {
padding: 4px 8px;
}
.app-item-dropdown.expanded ul{
display: block;
}
.lightblue {
background: lightblue;
}
.lightsalmon {
background: lightsalmon;
}
.expanded {
z-index: 5;
}
<div id="wrapper" class="container problem">
<div class="app-item">
<h2>1</h2>
<div class="app-item-dropdown">
<button>click</button>
<div class="box">
<ul>
<li>hello</li>
<li>hello</li>
<li>hellohello</li>
<li>hello</li>
<li>hello</li>
<li>hello</li>
<li>hehellohellollo</li>
<li>hello</li>
<li>helhellolo</li>
<li>hello</li>
</ul>
</div>
</div>
</div>
<div class="app-item">
<h2>2</h2>
<div class="app-item-dropdown lightblue">
<button>click</button>
<div class="box">
<ul>
<li>hello</li>
<li>hello</li>
<li>hellohello</li>
<li>hello</li>
<li>hello</li>
<li>hello</li>
<li>hehellohellollo</li>
<li>hello</li>
<li>helhellolo</li>
<li>hello</li>
</ul>
</div>
</div>
</div>
<div class="app-item">
<h2>3</h2>
<div class="app-item-dropdown lightsalmon">
<button>click</button>
<div class="box">
<ul>
<li>hello</li>
<li>hello</li>
<li>hellohello</li>
<li>hello</li>
<li>hello</li>
<li>hello</li>
<li>hehellohellollo</li>
<li>hello</li>
<li>helhellolo</li>
<li>hello</li>
</ul>
</div>
</div>
</div>
</div>
<hr>
<h1>Solution</h1>
<h2>With <code>flex-direction: column-reverse</code> </h2>
<div id="wrapper2" class="container solution">
<div class="app-item">
<h2>1</h2>
<div class="app-item-dropdown">
<button>click</button>
<div class="box">
<ul>
<li>hello</li>
<li>hello</li>
<li>hellohello</li>
<li>hello</li>
<li>hello</li>
<li>hello</li>
<li>hehellohellollo</li>
<li>hello</li>
<li>helhellolo</li>
<li>hello</li>
</ul>
</div>
</div>
</div>
<div class="app-item">
<h2>2</h2>
<div class="app-item-dropdown lightblue">
<button>click</button>
<div class="box">
<ul>
<li>hello</li>
<li>hello</li>
<li>hellohello</li>
<li>hello</li>
<li>hello</li>
<li>hello</li>
<li>hehellohellollo</li>
<li>hello</li>
<li>helhellolo</li>
<li>hello</li>
</ul>
</div>
</div>
</div>
<div class="app-item">
<h2>3</h2>
<div class="app-item-dropdown lightsalmon">
<button>click</button>
<div class="box">
<ul>
<li>hello</li>
<li>hello</li>
<li>hellohello</li>
<li>hello</li>
<li>hello</li>
<li>hello</li>
<li>hehellohellollo</li>
<li>hello</li>
<li>helhellolo</li>
<li>hello</li>
</ul>
</div>
</div>
</div>
</div>