0

Trying to position a dropdown behind the top navigation bar so that, when the animation of the dropdown dropping down occurs, it doesn't appear to come from over the top of the navigation bar but underneath it.

I've tried (tried being the operative word) to resolve this myself, and I've looked at stacking orders and contexts, and tried various combinations of positioning and z-index combinations in an attempt to achieve the desired result but none have the expected result.

Please review the code below or the codepen here!

.l-topbar {
  height: 50px;
  width: 100%;
}

#nav-primary {
  background-color: #008ed0;
  background-image: linear-gradient(
    to bottom right,
    rgb(0, 114, 167),
    rgb(0, 149, 219)
  );
  left: 0;
  position: fixed;
  top: 0;
  z-index: 3;
}

.l-top-list > li {
  color: white;
  display: inline-block;
  position: relative;
  vertical-align: middle;
}

.l-top-list > li > a {
  display: flex;
  position: relative;
}

.l-list > .btn:hover {
  background-color: #d50f67;
  color: #fff;
  cursor: pointer;
  transition: none;
}

.account {
  display: block;
  float: right;
  height: 100%;
}

.account > .btn {
  z-index: 3;
}

.account:hover .dropdown,
.account:focus .dropdown {
  opacity: 1;
  visibility: visible;
  z-index: 1;
  transform: translateY(0%);
  transition-delay: 0s, 0s, 0.3s;
}

.dropdown {
  background-color: #fff;
  box-shadow: 0 12px 8px 0 rgba(0, 0, 0, 0.2), 0 12px 20px 0 rgba(0, 0, 0, 0.19);
  color: #d50f67;
  opacity: 1;
  position: absolute;
  right: 0;
  transform: translateY(-10em);
  transition: all 0.3s ease-in-out 0s, visibility 0s linear 0.3s,
    z-index 0s linear 0.01s;
  visibility: visible;
  z-index: -2;
}

.dropdown > li > a {
  line-height: 50px;
  padding: 0 10px;
}

.icon {
  display: block;
  fill: white;
  height: 1.5em;
  padding: 13px;
  width: 1.5em;
}

.identity {
  float: left;
  height: 100%;
}

.logo {
  display: block;
  height: 2.5em;
  width: 2.5em;
  padding: 5px;
}

.l-list-info {
  float: left;
  padding: 16px 0 18px 10px;
}
<div id="nav-primary" class="l-topbar">
  <ul class="l-top-list identity">
    <li><img class="logo" alt="Logo" src="https://images.unsplash.com/photo-1561346120-851ea1e8776b?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ"></img>
    </li>
    <li>
      <p class="l-list-info">Cartoon</p>
    </li>
  </ul>
  <ul class="l-list l-top-list account">
    <li class="btn">
      <p class="l-list-info">Donald Duck</p><svg class="icon" width="24" height="24" viewBox="0 0 24 24">
  <path d="M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z"></path>
</svg>
      <ul class="l-list dropdown">
        <li class="btn"><a href="#">donald.duck@cartoon.co.uk</a></li>
        <li class="btn"><a href="#">Control Panel</a></li>
        <li class="btn"><a href="#">Change Cartoon</a></li>
        <li class="btn"><a href="#">Switch User</a></li>
        <li class="btn"><a href="#">Log Off</a></li>
      </ul>
    </li>
  </ul>
</div>

I obviously appreciate all and any help but, if possible, please explain to me why it went wrong (stack order/context, improper use of CSS attributes, etc.) and how I can identify the cause in the future.

I also appreciate that this type of question has been asked many times before it many variations. I have read many of them and tried to apply the fix to my code but to no avail.

Edit: I just thought to mention the following: I know that if I remove the z-index from the #nav-primary element, and give it a position of absolute, and leave the negative z-index on the dropdown element that it disappears behind the #nav-primary element. The problem is that I need the #nav-primary to have a fixed position so that, when content is added below and the user scrolls, the #nav-primary stays on top of everything but the dropdown needs to appear below the #nav-primary until the dropdown is activated

Ubi
  • 83
  • 7
  • there are typos in your code: there are not tags in HTML – DaFois Jun 27 '19 at 14:18
  • `img` cannot have a closing tag. – connexo Jun 28 '19 at 08:35
  • @connexo thank you for pointing this out, I just chucked the in there quickly to more closely mimic my current set up. But, since it has no relevance to the problem, I have changed my codepen to only show the relevant elements. – Ubi Jun 28 '19 at 08:37

2 Answers2

1

.l-topbar {
  height: 50px;
  width: 100%;
}

.content {
  background-color: tomato;
  position: absolute;
  top: 100px;
  left: 200px;
  height: 1000px;
  width: 600px;
  z-index: -1;
}

#nav-primary {
  background-color: #008ed0;
  background-image: linear-gradient(
    to bottom right,
    rgb(0, 114, 167),
    rgb(0, 149, 219)
  );
  left: 0;
  position: fixed;
  top: 0;
}

.l-top-list > li {
  color: white;
  display: inline-block;
  position: relative;
  vertical-align: middle;
}

.l-list > .btn:hover {
  background-color: #d50f67;
  color: #fff;
  cursor: pointer;
  transition: none;
}

.account {
  display: block;
  float: right;
  height: 100%;
}

.account:hover .dropdown,
.account:focus .dropdown {
  opacity: 1;
  visibility: visible;
  z-index: 3;
  transform: translateY(0%);
  transition-delay: 0s, 0s, 0.3s;
}

.dropdown {
  background-color: #fff;
  box-shadow: 0 12px 8px 0 rgba(0, 0, 0, 0.2), 0 12px 20px 0 rgba(0, 0, 0, 0.19);
  color: #d50f67;
  opacity: 1;
  position: absolute;
  right: 0;
  transform: translateY(-10em);
  transition: all 0.3s ease-in-out 0s, visibility 0s linear 0.3s,
    z-index 0s linear 0.01s;
  visibility: visible;
  z-index: -2;
}

.dropdown > li > a {
  line-height: 50px;
  padding: 0 10px;
}

.icon {
  display: block;
  fill: white;
  height: 1.5em;
  padding: 13px;
  position: relative;
  width: 1.5em;
  z-index: 3;
}

.l-list-info {
  float: left;
  padding: 16px 0 18px 10px;
}
<div id="nav-primary" class="l-topbar">
  <div id="nav-primary" class="l-topbar"></div>
  <ul class="l-list l-top-list account">
    <li class="btn">
      <svg class="icon" width="24" height="24" viewBox="0 0 24 24">
  <path d="M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z"></path>
</svg>
      <ul class="l-list dropdown">
        <li class="btn"><a href="#">donald.duck@cartoon.co.uk</a></li>
        <li class="btn"><a href="#">Control Panel</a></li>
        <li class="btn"><a href="#">Change Cartoon</a></li>
        <li class="btn"><a href="#">Switch User</a></li>
        <li class="btn"><a href="#">Log Off</a></li>
      </ul>
    </li>
  </ul>
</div>
<div class="content">
</div>
You can't put a child behind his parent, here nav is the parent of the drop-down list that's why z-index won't work here. so what i did i added a new sibling for drop-down same as nav and now it should work!
adel
  • 3,436
  • 1
  • 7
  • 20
  • Thank you so much for pointing this out, it sounds kind of obvious now you mention it but I hadn't thought about that at all (children not being able to appear behind the parent). The ONLY other way I had found to achieve this was to use nav-primary::before and basically replicate the nav-primary resulting in a fair amount more CSS. Your solution does feel a bit more of a "hack" though (no offense) as I'm duplicating HTML that creates a completely redundant div, but maybe I can repurpose it later >: ) – Ubi Jun 28 '19 at 12:17
0

The z-index is not enough. Both elements must have position defined and it should be absolute and / or relative. Check more for reference.

Matt Komarnicki
  • 5,198
  • 7
  • 40
  • 92
  • What about `fixed` and `sticky`positions? Can you not use `z-index` with those? :) – Morpheus Jun 27 '19 at 15:11
  • Hi Matt, I appreciate the help, but I've tried a combination of absolute and relative positioning, coupled with Z-Index, but still had no success. I also read that Z-Index worked with any position other than static, is this not the case? – Ubi Jun 28 '19 at 07:05