javascript - 当父位置固定时 Z-index 不工作

标签 javascript html css

我正在做一个菜单,我需要它的 child 有一个大的 z-index,这样当它被打开时它就在模态的顶部。它工作得很好,但是当我将菜单设置为“位置:固定”并打开模式时, child 被保持在模式后面。这是代码,忽略 css 的最后一部分,这只是动画。感谢您的帮助。

const btn = document.querySelector('.btn'),
      overlay = document.querySelector('.menu-overlay'),
      menu = document.querySelector('.responsive'),
      close = document.querySelector('.close'),
      barTop = document.querySelector('#bar-one'),
      barMiddle = document.querySelector('#bar-two'),
      barBottom = document.querySelector('#bar-three');


btn.addEventListener('click', function(){
    overlay.classList.toggle('active');
    menu.classList.toggle('menuActive');
    barTop.classList.toggle('barTop');
    barMiddle.classList.toggle('barMiddle');
    barBottom.classList.toggle('barBottom');
})
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.menu-container {
  background: teal;
  padding: 10px 0;
  width: 100%;
  /* here is the issue i´m talking about */
  /* position: fixed; */
}

.menu {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 90%;
  margin: 0 auto;
}

.menu li {
  list-style: none;
  padding: 5px;
}

.menu li a {
  font-family: sans-serif;
  text-decoration: none;
  color: #fff;
}

.btn-container {
  z-index: 10000 !important;
}

.btn {
  text-decoration: none;
  display: flex;
  width: 22px;
  height: 18px;
  margin: 0 auto;
  flex-direction: column;
  justify-content: space-between;
}

.btn span {
  display: block;
  width: 100%;
  height: 2px;
  background: #fff;
  transition: all .3s;
}

.btn #bar-one.barTop {
  transform: translateY(8px) rotate(45deg);
}
.btn #bar-three.barBottom {
  transform: translateY(-8px) rotate(-45deg);
}
.btn #bar-two.barMiddle {
  opacity: 0;
}

.menu-overlay {
  position: fixed;
  width: 100%;
  top: 0;
  bottom: 0;
  background: rgba(0,0,0,.8);
  animation: fadeOverlay .3s linear;
  display: none;
  z-index: 99;
}
.menu-overlay.active {
  display: block;
}

@keyframes fadeOverlay {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 100%;
  }
}

.responsive {
  width: 100%;
  height: 100vh;
  position: fixed;
  top: 0;
  left: -100%;
  z-index: 100;
  transition: left .2s ease-in-out;
}

.responsive ul {
  display: flex;
  flex-direction: column;
  background: #000;
  width: 87%;
  height: 100%;
  padding: 20px;
}

.responsive ul li {
  padding: 5px;
}

.responsive ul li a {
  text-decoration: none;
  color: #fff;
}

.responsive.menuActive {
  left: 0;
}

.close {
  text-decoration: none;
  display: block;
  color: #fff;
  width: 10%;
  position: absolute;
  top: 0;
  right: 0;
  font-size: 40px;
  text-align: center;
  margin-top: 5px;
}

.close.closeActive {
  animation: fadeClose .4s linear;
}

@keyframes fadeClose {
  0%, 90% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Menu Celular</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>

  <div class="menu-overlay"></div>
  <div class="menu-container">
    <ul class="menu">
      <li><a href="#">Home</a></li>
      <li class="btn-container">
        <a href="#" class="btn">
          <span id="bar-one"></span>
          <span id="bar-two"></span>
          <span id="bar-three"></span>
        </a>
      </li>
    </ul>
  </div>
  <div class="responsive">
  <ul>
    <li><a href="#">Home</a></li>
    <li><a href="#">Exit</a></li>
  </ul>
  </div>



<script src="./js.js" charset="utf-8"></script>
</body>
</html>

最佳答案

position:fixed 创建一个堆叠上下文,强制将内部的所有元素绘制在内部。您的问题是,现在,叠加层覆盖了菜单容器,包括其所有元素,并且为内部元素设置更高的 z-index 将无济于事。在您的情况下,它是您不能再移出该堆叠上下文的按钮容器。

你必须增加容器的z-index

const btn = document.querySelector('.btn'),
      overlay = document.querySelector('.menu-overlay'),
      menu = document.querySelector('.responsive'),
      close = document.querySelector('.close'),
      barTop = document.querySelector('#bar-one'),
      barMiddle = document.querySelector('#bar-two'),
      barBottom = document.querySelector('#bar-three');


btn.addEventListener('click', function(){
    overlay.classList.toggle('active');
    menu.classList.toggle('menuActive');
    barTop.classList.toggle('barTop');
    barMiddle.classList.toggle('barMiddle');
    barBottom.classList.toggle('barBottom');
})
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.menu-container {
  background: teal;
  padding: 10px 0;
  width: 100%;
  /* here is the issue i´m talking about */
  position: fixed; 
  z-index:1000;
}

.menu {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 90%;
  margin: 0 auto;
}

.menu li {
  list-style: none;
  padding: 5px;
}

.menu li a {
  font-family: sans-serif;
  text-decoration: none;
  color: #fff;
}

.btn-container {
  z-index: 10000 !important;
}

.btn {
  text-decoration: none;
  display: flex;
  width: 22px;
  height: 18px;
  margin: 0 auto;
  flex-direction: column;
  justify-content: space-between;
}

.btn span {
  display: block;
  width: 100%;
  height: 2px;
  background: #fff;
  transition: all .3s;
}

.btn #bar-one.barTop {
  transform: translateY(8px) rotate(45deg);
}
.btn #bar-three.barBottom {
  transform: translateY(-8px) rotate(-45deg);
}
.btn #bar-two.barMiddle {
  opacity: 0;
}

.menu-overlay {
  position: fixed;
  width: 100%;
  top: 0;
  bottom: 0;
  background: rgba(0,0,0,.8);
  animation: fadeOverlay .3s linear;
  display: none;
  z-index: 99;
}
.menu-overlay.active {
  display: block;
}

@keyframes fadeOverlay {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 100%;
  }
}

.responsive {
  width: 100%;
  height: 100vh;
  position: fixed;
  top: 0;
  left: -100%;
  z-index: 100;
  transition: left .2s ease-in-out;
}

.responsive ul {
  display: flex;
  flex-direction: column;
  background: #000;
  width: 87%;
  height: 100%;
  padding: 20px;
}

.responsive ul li {
  padding: 5px;
}

.responsive ul li a {
  text-decoration: none;
  color: #fff;
}

.responsive.menuActive {
  left: 0;
}

.close {
  text-decoration: none;
  display: block;
  color: #fff;
  width: 10%;
  position: absolute;
  top: 0;
  right: 0;
  font-size: 40px;
  text-align: center;
  margin-top: 5px;
}

.close.closeActive {
  animation: fadeClose .4s linear;
}

@keyframes fadeClose {
  0%, 90% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Menu Celular</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>

  <div class="menu-overlay"></div>
  <div class="menu-container">
    <ul class="menu">
      <li><a href="#">Home</a></li>
      <li class="btn-container">
        <a href="#" class="btn">
          <span id="bar-one"></span>
          <span id="bar-two"></span>
          <span id="bar-three"></span>
        </a>
      </li>
    </ul>
  </div>
  <div class="responsive">
  <ul>
    <li><a href="#">Home</a></li>
    <li><a href="#">Exit</a></li>
  </ul>
  </div>



<script src="./js.js" charset="utf-8"></script>
</body>
</html>

这样做会使所有容器都在叠加层之上,这也不是所需的结果。

如果您希望叠加层像最初那样运行,唯一的方法是将其放在 position:fixed 元素内,并将 responsive 菜单移到那里, 所以你让所有的元素再次属于同一个堆叠上下文,你可以像你想要的那样调整 z-index

const btn = document.querySelector('.btn'),
      overlay = document.querySelector('.menu-overlay'),
      menu = document.querySelector('.responsive'),
      close = document.querySelector('.close'),
      barTop = document.querySelector('#bar-one'),
      barMiddle = document.querySelector('#bar-two'),
      barBottom = document.querySelector('#bar-three');


btn.addEventListener('click', function(){
    overlay.classList.toggle('active');
    menu.classList.toggle('menuActive');
    barTop.classList.toggle('barTop');
    barMiddle.classList.toggle('barMiddle');
    barBottom.classList.toggle('barBottom');
})
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.menu-container {
  background: teal;
  padding: 10px 0;
  width: 100%;
  /* here is the issue i´m talking about */
  position: fixed; 
}

.menu {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 90%;
  margin: 0 auto;
}

.menu li {
  list-style: none;
  padding: 5px;
}

.menu li a {
  font-family: sans-serif;
  text-decoration: none;
  color: #fff;
}

.btn-container {
  z-index: 10000 !important;
}

.btn {
  text-decoration: none;
  display: flex;
  width: 22px;
  height: 18px;
  margin: 0 auto;
  flex-direction: column;
  justify-content: space-between;
}

.btn span {
  display: block;
  width: 100%;
  height: 2px;
  background: #fff;
  transition: all .3s;
}

.btn #bar-one.barTop {
  transform: translateY(8px) rotate(45deg);
}
.btn #bar-three.barBottom {
  transform: translateY(-8px) rotate(-45deg);
}
.btn #bar-two.barMiddle {
  opacity: 0;
}

.menu-overlay {
  position: fixed;
  width: 100%;
  top: 0;
  bottom: 0;
  background: rgba(0,0,0,.8);
  animation: fadeOverlay .3s linear;
  display: none;
  z-index: 99;
}
.menu-overlay.active {
  display: block;
}

@keyframes fadeOverlay {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 100%;
  }
}

.responsive {
  width: 100%;
  height: 100vh;
  position: fixed;
  z-index:100;
  top: 0;
  left: -100%;
  z-index: 99;
  transition: left .2s ease-in-out;
}

.responsive ul {
  display: flex;
  flex-direction: column;
  background: #000;
  width: 87%;
  height: 100%;
  padding: 20px;
}

.responsive ul li {
  padding: 5px;
}

.responsive ul li a {
  text-decoration: none;
  color: #fff;
}

.responsive.menuActive {
  left: 0;
}

.close {
  text-decoration: none;
  display: block;
  color: #fff;
  width: 10%;
  position: absolute;
  top: 0;
  right: 0;
  font-size: 40px;
  text-align: center;
  margin-top: 5px;
}

.close.closeActive {
  animation: fadeClose .4s linear;
}

@keyframes fadeClose {
  0%, 90% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Menu Celular</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>

  <div class="menu-container">
  <div class="menu-overlay"></div>
    <ul class="menu">
      <li><a href="#">Home</a></li>
      <li class="btn-container">
        <a href="#" class="btn">
          <span id="bar-one"></span>
          <span id="bar-two"></span>
          <span id="bar-three"></span>
        </a>
      </li>
    </ul>
  <div class="responsive">
  <ul>
    <li><a href="#">Home</a></li>
    <li><a href="#">Exit</a></li>
  </ul>
  </div>
  </div>



<script src="./js.js" charset="utf-8"></script>
</body>
</html>

如果不能更改 HTML,就没有机会获得想要的内容。


获取有关堆叠上下文和绘画顺序的更多详细信息的相关问题:

Why elements with z-index can never cover its child?

How to z-index a repositioned div in css?

关于javascript - 当父位置固定时 Z-index 不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55069237/

相关文章:

javascript - 如何使用 javascript 并排创建两个标签

html - 带有文本的 Div 不会居中

基于 Python Web 的机器人

javascript - HTML5 翻译相对于页面

css - 如何制作添加按钮

css - 如果元素 B 包含某个类,则对元素 A 应用样式

css - 是否可以为单个装订线覆盖 grid-row-gap/grid-column-gap?

javascript - WebSQL 事务不会在 JS 回调函数中运行

javascript - Sencha 触摸2 : Creating a Nested List inside a tab panel

javascript - 使用纯 CSS,使一个 div 居中,直到它通过调整窗口大小进入侧边栏?