Search code examples
htmlcssz-index

Is there a z-index alternative for elements without a fixed/relatic/absolute position?


I need to display one element on a higher "z-level". The problem is, that the element is inside a div with a "display: flex" and "justify-content: space-around". The normal z-index property is not working and I think that's because the element hasn't a fixed/relative/absolute position.
Is there a way to solve this problem and to give the element a higher z-value?

I need to see the hamburger, when the navigation is opened The code (css is looking weird because I use sass):

const welcomeText = document.querySelector('.welcome-text');
const logo = document.querySelector('.logo');
const hamburger = document.querySelector('.hamburger');
const arrow = document.querySelector('.down-arrow');
const navLinks = document.querySelector('.nav-links');

hamburger.addEventListener('click', () => {
    navLinks.classList.toggle('open');
    hamburger.classList.toggle('open');
})
@import url("https://fonts.googleapis.com/css?family=Montserrat:400,500&display=swap");
* {
  margin: 0;
  padding: 0;
  -webkit-box-sizing: border-box;
          box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

.introduction {
  width: 98%;
  margin: auto;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: justify;
      -ms-flex-pack: justify;
          justify-content: space-between;
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
  height: 90vh;
  -webkit-transform: translateY(10vh);
          transform: translateY(10vh);
}

.introduction .logo img {
  height: 10vh;
}

.introduction .hamburger {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  height: 8vh;
  width: 8vh;
  background: black;
  border-radius: 50%;
  z-index: 3;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
      -ms-flex-direction: column;
          flex-direction: column;
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
  -webkit-box-pack: space-evenly;
      -ms-flex-pack: space-evenly;
          justify-content: space-evenly;
}

.introduction .hamburger .bar {
  z-index: 3;
  margin: -10% 0;
  background: white;
  width: 70%;
  height: 1vh;
}

.introduction .welcome-text {
  font-family: 'Montserrat', sans-serif;
  text-align: center;
  font-size: 20px;
}

.introduction .welcome-text span {
  color: #d1a33f;
}

.nav-links {
  position: absolute;
  top: 0%;
  z-index: 1;
  height: 100vh;
  width: 100%;
  background: black;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
      -ms-flex-direction: column;
          flex-direction: column;
  -ms-flex-pack: distribute;
      justify-content: space-around;
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
  -webkit-clip-path: circle(0% at 98% 55%);
          clip-path: circle(0% at 98% 55%);
  -webkit-transition: all 1s ease-out;
  transition: all 1s ease-out;
}

.nav-links li {
  list-style: none;
}

.nav-links.open {
  -webkit-clip-path: circle(100% at 98% 55%);
          clip-path: circle(100% at 98% 55%);
}

.nav-link {
  color: white;
  text-decoration: none;
}

.down-arrow {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: center;
      -ms-flex-pack: center;
          justify-content: center;
  -webkit-box-align: center;
      -ms-flex-align: center;
          align-items: center;
  -webkit-animation-name: arrowAnim;
          animation-name: arrowAnim;
  -webkit-animation-duration: 2s;
          animation-duration: 2s;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
}

.down-arrow img {
  width: 15vh;
}

.down-arrow img:hover {
  width: 18vh;
}

@-webkit-keyframes arrowAnim {
  0% {
  }
  50% {
    -webkit-transform: translateY(-3rem);
            transform: translateY(-3rem);
  }
  100% {
    -webkit-transform: translateY(0);
            transform: translateY(0);
  }
}

@keyframes arrowAnim {
  0% {
  }
  50% {
    -webkit-transform: translateY(-3rem);
            transform: translateY(-3rem);
  }
  100% {
    -webkit-transform: translateY(0);
            transform: translateY(0);
  }
}

main {
  padding-top: 10vh;
}

main .roboter {
  text-align: right;
}
/*# sourceMappingURL=style.css.map */
<!DOCTYPE html>
<html lang="de">

<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">
    <link rel="stylesheet" href="./style.css">
    <title>Homepage | Team Jatrian</title>
</head>

<body>
    <header class="introduction">
        <div class="logo">
            <img src="./img/Logo.svg" alt="logo">
        </div>
        <div class="welcome-text">
            <h1>Willkommen auf der Homepage von <br /><span class="golden-text">Team Jatrian</span></h1>
        </div>
        <div class="hamburger">
            <div class="bar 1"></div>
            <div class="bar 2"></div>
            <div class="bar 3"></div>
        </div>
    </header>
    <nav>
        <ul class="nav-links">
            <li>
                <a href="#" class="nav-link">placeholder</a>
            </li>
            <li>
                <a href="#" class="nav-link">placeholder</a>
            </li>
            <li>
                <a href="#" class="nav-link">placeholder</a>
            </li>
        </ul>
    </nav>
    <div class="down-arrow">
        <a href="#team">
            <img src="./img/arrow.svg" alt="downArrow">
        </a>
    </div>
    <main>
        <div class="team" id="team">
            <h1>Das Team</h1>
            <p>...</p>
        </div>
        <div class="roboter">
            <h1>Der Roboter</h1>
            <p>...</p>
        </div>
        <div class="kontakt">
            <h1>Kontakt</h1>
            <p>...</p>
        </div>
    </main>
    <script src="script.js"></script>
</body>

</html>


Solution

  • First thing first: z-index only works on positioned elements, that is having a position attribute value other than the default (static). The display property is not relevant for that matter.

    Update: There is once exceptional here - z-index will work on flex item even if it's "unpositioned"

    The easiest way to "activate z-index" without breaking the current style would be to use position:relative, since by itself it will not change the UI behavior. That is, if you did not provide any offset attribute (top/bottom/left/right)

    Now for your specific situation - the problem is not only with the hamburger z-index activation, but rather the fact it's located in the header element, while the menu items (.nav-links) are in the nav element. Since header and nav elements are sibling here, you should choose which one should be above the other.

    You could give header heigher z-index value to achieve that, for example:

    header {
        z-index: 2; // higher than nav-links z-index (1)
        position: relative;
    }
    

    This will get the humburder to be on top, but also the entire header including the text Team Jatrian.

    Keep in mind z-index work in stacking-contexts:

    Every stacking context has a single HTML element as its root element. When a new stacking context is formed on an element, that stacking context confines all of its child elements to a particular place in the stacking order. That means that if an element is contained in a stacking context at the bottom of the stacking order, there is no way to get it to appear in front of another element in a different stacking context that is higher in the stacking order, even with a z-index of a billion!

    Meaning if header is to be above nav, it means all of header's children would be above nav as well, So you might consider to move the hamburger to be under a different element.