Search code examples
cssz-index

Z-index element isn't scrolling


I have an application where there's a container and inside that container a user can type a value inside an input, while he types an auto-complete box (an element with the z-index property) shows under the input and once he presses enter, the input value is saved inside a tag. A brief example of the html and css can be seen in this codepen (same code below)

.main {
  align-items: center;
  display: flex;
  height: 100vh;
  justify-content: center;
  width: 100vw;
}

.tag-container {
  align-content: flex-start;
  border: 1px solid black;
  display: flex;
  flex-direction: center;
  flex-wrap: wrap;
  gap: 5px;
  overflow-y: scroll;
  padding: 5px;
  height: 70px;
  width: 600px;
}

.tag {
  display: flex;
  justify-content: center;
  align-items: center;
  border: 1px solid black;
  height: 30px;
  width: 100px;
}

.input {
  height: 25px;
  width: 145px;
}

.auto-complete-box {
  background: #F6F2F2;
  border: 1px solid black;
  position: absolute;
  height: 150px;
  text-align: center;
  width: 150px;
  z-index: 1;
}
<div class="main">
  <div class="tag-container">
    <div class="tag">Tag</div>
    <div class="tag">Tag</div>
    <div class="tag">Tag</div>
    <div class="tag">Tag</div>
    <div class="tag">Tag</div>
    <div class="tag">Tag</div>
    <div class=input-container>
      <input
        class="input"
        type="text"
        placeholder="input"
      />
      <div class="auto-complete-box">
        Auto Complete Box
      </div>
    </div>
  </div>
</div>

The problem is when my container starts to scroll (more tags added), the z-index element doesn't seem to follow it. Like in this codepen example (same code below)

.main {
  align-items: center;
  display: flex;
  height: 100vh;
  justify-content: center;
  width: 100vw;
}

.tag-container {
  align-content: flex-start;
  border: 1px solid black;
  display: flex;
  flex-direction: center;
  flex-wrap: wrap;
  gap: 5px;
  overflow-y: scroll;
  padding: 5px;
  height: 70px;
  width: 600px;
}

.tag {
  display: flex;
  justify-content: center;
  align-items: center;
  border: 1px solid black;
  height: 30px;
  width: 100px;
}

.input {
  height: 25px;
  width: 145px;
}

.auto-complete-box {
  background: #F6F2F2;
  border: 1px solid black;
  position: absolute;
  height: 150px;
  text-align: center;
  width: 150px;
  z-index: 1;
}
<div class="main">
  <div class="tag-container">
    <div class="tag">Tag</div>
    <div class="tag">Tag</div>
    <div class="tag">Tag</div>
    <div class="tag">Tag</div>
    <div class="tag">Tag</div>
    <div class="tag">Tag</div>
    <div class="tag">Tag</div>
    <div class="tag">Tag</div>
    <div class="tag">Tag</div>
    <div class="tag">Tag</div>
    <div class="tag">Tag</div>
    <div class="tag">Tag</div>
    <div class="tag">Tag</div>
    <div class="tag">Tag</div>
    <div class="tag">Tag</div>
    <div class=input-container>
      <input
        class="input"
        type="text"
        placeholder="input"
      />
      <div class="auto-complete-box">
        Auto Complete Box
      </div>
    </div>
  </div>
</div>

Is there a way to achieve what I want with just CSS?

Thanks in advance!


Solution

  • enter code hereThis can not be done with z-index. This requires a scrolling event in JavaScript.

    let tagContainer = document.querySelector('.tag-container')
    let autoCompleteBox = document.querySelector('.auto-complete-box')
    let input = document.querySelector('.input')
    
    tagContainer.addEventListener('scroll', function (e) {
        if (e.target.scrollTop == e.target.scrollHeight - e.target.clientHeight) {
            autoCompleteBox.style.top = `${tagContainer.offsetTop + tagContainer.offsetHeight - 6}` + "px";
            autoCompleteBox.style.display= "block";
        } else if (e.target.scrollTop < e.target.scrollTop < e.target.scrollHeight - e.target.clientHeight) {
            autoCompleteBox.style.display= "none";
        } 
    })
    .main {
        align-items: center;
        display: flex;
        height: 100vh;
        justify-content: center;
        width: 100vw;
    }
    
    .tag-container {
        align-content: flex-start;
        border: 1px solid black;
        display: flex;
        flex-direction: center;
        flex-wrap: wrap;
        gap: 5px;
        overflow-y: scroll;
        padding: 5px;
        height: 70px;
        width: 600px;
    }
    
    .tag {
        display: flex;
        justify-content: center;
        align-items: center;
        border: 1px solid black;
        height: 30px;
        width: 100px;
    }
    
    .input {
        height: 25px;
        width: 145px;
    }
    
    .auto-complete-box {
        display: none;
        background: #F6F2F2;
        border: 1px solid black;
        position: absolute;
        top: 74px;
        height: 150px;
        text-align: center;
        width: 150px;
        z-index: 1;
    }
    <div class="main">
        
        <div style="position: relative;">
            <div class="tag-container">
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                <div class="tag">Tag</div>
                
                <div class=input-container>
                    <input class="input" type="text" placeholder="input" />
                    <div class="auto-complete-box">
                        Auto Complete Box
                    </div>
                </div>
            </div>
        </div>
    </div>