Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS transition and z-index

I have a fixed top navbar with dropdowns. I want to slide the dropdown menus in on hover. I want that the menu is behind the navbar while sliding in. So I've simply tried to set the z-index of both elements which unfortunately did not work for me.

Here a simplified example (codepen)

html

<div class="fixed-top">
  <span class="trigger">hover me</span>
  <div class="menu"></div>
</div>

css

.fixed-top {
  background: #3b5999;
  height: 50px;
  width: 100%;
  padding: 0;
  top: 0;
  position: fixed;
  z-index: 2;
}

.trigger {
  z-index: 2;
  font-size: 33px;
  color: white;
  margin-left: 50%;
}

.trigger:hover + .menu {
  margin-top: 0;
}

.menu {
  z-index: 1;
  height: 300px;
  background-color: #1c7754;
  width: 400px;
  margin: auto;
  margin-top: -400px;
  transition: all 0.75s ease-out;
}

In case it's not clear what I want to do here a simple mspaint sketch ;)

mspaint skills confirmed

like image 602
boop Avatar asked Nov 25 '15 04:11

boop


People also ask

Does transition work on Z index?

So remember: z-index is indeed one of the properties you can apply a transition to, but the transition has to happen in full steps, not necessarily as gradually as you might imagine it in your head.

Can you animate Z Index CSS?

Yes, you can animate z-index ! It's not visually apparent in this demo, but seeing the interpolated values go from 1 to 5 confirms it.

What is Z Index 9999 in CSS?

In CSS code bases, you'll often see z-index values of 999, 9999 or 99999. This is a perhaps lazy way to ensure that the element is always on top. It can lead to problems down the road when multiple elements need to be on top. Most of the time you'll find that a z-index of 1 or 2 will suffice for your needs.

What is a Z index in CSS?

The z-index property in CSS controls the vertical stacking order of elements that overlap. As in, which one appears as if it is physically closer to you. z-index only affects elements that have a position value other than static (the default).


1 Answers

This is an extremely common error when beginning to work with stacking contexts in CSS. Basically, you just have to remember that a child cannot exist in a different stacking context from a parent.

So if I have a non-static element (meaning an element with position: anything-but-static [fixed, relative, absolute]), and if that element has no non-static parent element, then it will be at stacking context level 1, no matter where it is in the DOM. Now if that element has a non-static child element, that child will be at stacking context level 2. It cannot be on the same level (level 1) as its parent element. z-index can only affect elements on the same stacking context level, it has nothing to do with elements on different stacking context levels.

The solution is to restructure your HTML, or just use a :before or :after pseudo-element, thus:

.fixed-top {
    height: 50px;
    width: 100%;
    padding: 0;
    top: 0;
    position: fixed; /* The parent: stacking context level 1 */
}
.fixed-top:before {
    background: #3b5999;
    content:'';
    position: absolute; /* stacking context level 2 */
    top: 0; right: 0; bottom: 0; left: 0;
    z-index: 1;
}
.trigger {
    color: white;
    font-size: 33px;
    margin-left: 50%;
    position: relative; /* also stacking context level 2 */
    z-index: 2;
}
.trigger:hover + .menu {
    margin-top: 0;
}
.menu { /* bottom layer -- no stacking context necessary */
    z-index: 0;
    height: 300px;
    background-color: #1c7754;
    width: 400px;
    margin: auto;
    margin-top: -400px;
    transition: all 0.75s ease-out;
}

Note the comments denoting the stacking context levels.

And here's a JSFiddle for an example.

like image 117
bowheart Avatar answered Sep 20 '22 17:09

bowheart