Kinz
Kinz

Reputation: 310

LI Visibility Not Tied to UL Height

I've got a website I'm building for personal use. This website has a dropdown menu that is animated by CSS3 animations. I quite enjoyed the look and feel of the result, until I realize that the List Items inside the Unordered List weren't visible/invisible relative to the dropdown's height. The information I seek is a method of resolving this. It's very annoying, especially given the time I've invested into something that seems so simple...

Pertinent HTML:

<ul class="dMaster">
    <li class="dChild"><a href="index.php" class="bItem" id="homeItem">Home</a></li>
    <li class="dChild" style="cursor: default;">About
        <ul class="dMaster2">
            <li class="dChild2"><a href="about.php" class="bItem" id="gAboutItem">General</a></li>
            <li class="dChild2"><a class="bItem" id="twItem" target="_blank">Twitter</a></li>
            <li class="dChild2"><a class="bItem" id="ytItem" target="_blank">YouTube</a></li>
        </ul>
    </li>
</ul>

Pertinent CSS:

@keyframes dropdown {
    from { height: 0px; }
    to { height: 77px; }
} @-webkit-keyframes dropdown {
    from { height: 0px; }
    to { height: 77px; }
}
.dMaster {
    margin: 0;
    padding: 0;
    text-align: center;
} .dChild {
    margin: 0;
    padding: 0;
    height: 19px;
    width: 60px;
    float: left;
    list-style: none;
} .dChild:hover {
    color: #000;
    background: #C60;
    border: 1px solid #FFF;
    border-top: none;
    text-shadow: 1px 1px 5px #FFF;
} .dMaster2 {
    padding: 0;
    position: absolute;
    min-width: 60px;
    text-align: center;
    background: #C60;
    border: 1px solid #FFF;
    margin: -2px 0  0 -1px;
    visibility: hidden;
} .dChild2 {
    opacity: 0.5;
    padding: 2px 5px;
    list-style: none;
    -webkit-transition: opacity 0.4s;
    -moz-transition: opacity 0.4s;
    -o-transition: opacity 0.4s;
} .dChild2:hover {
    opacity: 1.0;
} ul li:hover ul {
    color: #FFF;
    visibility: visible;
    animation: dropdown 0.2s ease-out;
    -webkit-animation: dropdown 0.2s ease-out;
}

I've tried for an hour or two with many different techniques without avail. If needed, there's a JSFiddle here. Any help is greatly appareciated!

Side note: The dropdown menu is on the About. It may not be apparent at first, but the List Items are quite visible when the UL is extending downward.

Upvotes: 5

Views: 1430

Answers (2)

Christoph
Christoph

Reputation: 51201

Just add one line to your code and you should be fine:

.dMaster2 {
    /*...*/
    overflow:hidden;
}

sidenotes:

For usabilities sake you should decrease the animation to max. 1 second. Users don't want to wait 2 seconds for a dropdown to unfold.

Also you don't need keyframes to do so, just animate the height property of the ul element.

.dMaster2 {
    /*...*/
    visibility:hidden; /* <- remove this line! */
    overflow:hidden;
    transition:height .3s; /*add height transition, use ~ .5s */
    /* if you add the transition to the root element both, mousein and mouseout
       will be animated, which is not the case if you put it on the :hover */
    height:0;              /*add height property */
}
ul li:hover ul {
    color: #FFF;
    visibility: visible;
    height:102px;        /*add height property */
    /* if you put the transition here, only the mousein will be animated */
}

Your modified fiddle

Upvotes: 4

Jerska
Jerska

Reputation: 12002

May that be what you're looking for ?

Basically it uses a different transition-delay for each line.

I put an effort to make everything clearer on this fiddle when I didn't in the last one. You should really check the second for a good point of vue.

The goal is to achieve to display them one at a time. Two solutions for that :

  1. An unique id per line
  2. Use the nth-child to get each-line.

Let's say we have 3 items to display in 3s. Here is our time line :

t      Action
_____________
0 | The rectangle begins to display.
  |
1 | Rectangle at 1/3 of its height. We display our item n° 1.
  |
2 | Rectangle at 2/3 of its height. We display our item n° 2.
  |
3 | Rectangle at 3/3 of its height. We display our item n° 3.
  v

Let's revue the code :

HTML

<a>Hover me</a>

<ul>
    <li>Hey</li>
    <li>Hi</li>
    <li>Ho</li>
</ul>

Our goal is simple :

We want that if we drag the mouse over the <a> tag, it displays progressively the <ul> and the different <li> elements. Moreover, we want that it stays if the mouse is over the menu, but vanishes instantly if the mouse goes out of the <a> or <ul>.

CSS

Basics

ul { /* Hidden and width no height */
    visibility: hidden;
    background-color: white;
    height: 0px;
    border: 1px solid black;
}

a:hover ~ ul { /* When the mouse goes over the <a> it becomes visible and begins the transition */
    visibility: visible;
    background-color: orange;
    height: 60px;
    transition: height 3s;
}

Now we get to the "tricky part" :

a:hover ~ ul li { /* Default behaviour for appearing */
    opacity: 1;
    transition: opacity 0.2s;
}

/* And now for each child, its custom delay :*/

a:hover ~ ul li:nth-child(1) {
    transition-delay: 1s;
}

a:hover ~ ul li:nth-child(2) {
    transition-delay: 2s;
}

a:hover ~ ul li:nth-child(3) {
    transition-delay: 3s;
}

And TADAAAAM ! Easy peasy !

In the other side, to avoid them to disappear progressively:

/* To make the depop instantly */

a ~ ul li {
    opacity: 0;
    transition-delay: 0s;
}

a ~ ul li:nth-child(1) {
    transition-delay: 0s;
}

a ~ ul li:nth-child(2) {
    transition-delay: 0s;
}

a ~ ul li:nth-child(3) {
    transition-delay: 0s;
}

And here you go. Of course, it's not very dynamic, and if you need to do this for each child, it will soon be boring. But you can use scripts to generate that code. :)

Hope it helped.

Upvotes: 2

Related Questions