Johny P.
Johny P.

Reputation: 698

CSS transition ends too early when mouse leaves element

I'm working on a menu for my site. It's done already, there's just one little detail that keeps annoying me. Take a look at the snippet below. When I hover over the parent element the child slides down with transition. But once the mouse leaves the parent/child element, the child element will just disappear.

I have determined that when the mouse leaves the parent/child element, the child element quickly moves out of view (left: -9999px;), before the slide up transition starts.

How can I make it so when the mouse leaves the menu the item slides back up with the same transition type? Is there a CSS-only solution or do I have to use jQuery as well?

ul {
  list-style: none;
  padding: 0;
}

li {
  width: 180px;
}

#menu ul ul {
  left: -9999px;
  position: absolute;
  background: red none repeat scroll 0 0;
}

#menu li:hover>ul {
  left: auto;
}

#menu ul ul li {
  height: 0;
  transition: height 0.2s ease 0s;
}

#menu ul ul ul {
  margin-left: 100%;
  top: 0;
}

#menu ul li:hover>ul>li {
  height: 32px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav id="menu">
  <ul>
    <li>Parent Item
      <ul>
        <li>Child Item
          <ul>
            <li>Child Child Item</li>
          </ul>
        </li>
      </ul>
    </li>
  </ul>
</nav>

Upvotes: 2

Views: 124

Answers (3)

Xavier
Xavier

Reputation: 130

Take off the left property and use overflow: hidden Also, I don't think using "auto" with transition works. It'll automatically pop in using this attribute.

#menu ul ul {
  position: absolute;
  overflow: hidden;
  background: red none repeat scroll 0 0;
}

#menu li:hover>ul {
  
}

#menu ul ul li {
  height: 0;
  transition: height 0.2s ease 0s;
}

#menu ul li:hover>ul>li {
  height: 32px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav id="menu">
  <ul>
    <li>Parent Item
      <ul>
        <li>Child Item</li>
      </ul>
    </li>
  </ul>
</nav>

Upvotes: 1

sol
sol

Reputation: 22949

I would remove the left property, and only transition height. This will work if you also use the overflow property.

#menu li ul {
  height: 0px;
  overflow: hidden;
  background: red none repeat scroll 0 0;
  transition: height 0.2s ease 0s;
  position: absolute;
}

#menu ul li:hover>ul {
  height: 32px;
  overflow: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav id="menu">
  <ul>
    <li>Parent Item
      <ul>
        <li>Child Item</li>
      </ul>
    </li>
  </ul>
</nav>

Upvotes: 0

G-Cyrillus
G-Cyrillus

Reputation: 106008

You can add a transition-delay on the regular state .

example with 1s delay.

position:relative is added to parent li , so left:auto; can be turned into left:0; in order to apply transition.

#menu ul ul {
  left: -9999px;
  position: absolute;
  background: red none repeat scroll 0 0;
  transition:0s 1s;/* set a delay */
}
#menu ul li{
position:relative;
}
#menu li:hover>ul {
  left: 0;
  transition:0s 0s;/* reset delay */
}

#menu ul ul li {
  height: 0;
  transition: height 0.2s ease 1s;/* set a delay */
}

#menu ul li:hover>ul>li {
  height: 32px;
  transition: height 0.2s ease 0s;/* reset delay */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav id="menu">
  <ul>
    <li>Parent Item
      <ul>
        <li>Child Item</li>
      </ul>
    </li>
  </ul>
</nav>

Upvotes: 0

Related Questions