Umair Khan Jadoon
Umair Khan Jadoon

Reputation: 2914

Issue with CSS/HTML sub level navigation

I have this HTML Code:

<div class="primaryNavigationContainer">
    <ul id="menu-menu-1" class="menu">
        <li id="menu-item-5" class="menu-item menu-item-type-custom menu-item-object-custom current-menu-item current_page_item menu-item-home menu-item-has-children menu-item-5"><a href="http://merrycode.com/cheekoo/wp/">Home</a>

            <ul class="sub-menu">
                <li id="menu-item-7" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-7"><a href="http://www.xyz.com">MerryCode</a>
                </li>
                <li id="menu-item-8" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-8"><a href="http://www.google.com">Google</a>
                </li>
            </ul>
        </li>
        <li id="menu-item-6" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-6"><a href="http://merrycode.com/cheekoo/wp/?page_id=2">Sample Page</a>
        </li>
    </ul>
</div>

And this CSS:

.menu a {
    font: normal 14px Helvetica, sans-serif;
    padding-left:5px;
    padding-top:5px;
    padding-right:5px;
    float:left;
    color:black;
}
.menu-item a {
    text-decoration:none;
}
.menu-item:hover ul {
    display:block;
}
.menu li ul {
    display:none;
}
.sub-menu {
    position: absolute;
    top:50px;
    width: 170px;
    height:auto;
    background: #edebeb;
    z-index: 100000;
    z-index: 99999;
    -moz-box-shadow: 1px 1px 30px rgba(0, 0, 0, 0.06);
    -webkit-box-shadow: 1px 1px 30px rgba(0, 0, 0, 0.06);
    box-shadow: 1px 1px 30px rgba(0, 0, 0, 0.06);
    list-style-type: none;
}
.sub-menu:after {
    display: block;
}
.sub-menu a {
    float: none;
}
.menu {
    width:100%;
    height:30px;
    background-color:#ebebed;
    float:left;
    display: block;
    list-style-type: none;
    -webkit-margin-before: 1em;
    -webkit-margin-after: 1em;
    -webkit-margin-start: 0px;
    -webkit-margin-end: 0px;
    -webkit-padding-start: 0px;
}

(Fiddle: http://jsfiddle.net/NjpNN/)

As you can see, I am trying to create a navigation menu. Sub menu is shown when I hover the main menu item "Home" but it disappears when I try to hover over the sub-menu area.

How can I make the sub-menu stay on screen unless I move the mouse out of sub-menu area? Please keep in mind that I can not make changes to HTML as it is generated by WordPress. I need to edit my CSS to achieve this.

Example: Something like this - http://jsfiddle.net/La2L8/ (Not my code).

Upvotes: 0

Views: 247

Answers (2)

Radley Sustaire
Radley Sustaire

Reputation: 3399

I would avoid using the answer which suggests wrapping the submenu in the <a> element. This poses an accessibility issue where any excess space not covered by a child <a> would link to the original menu item. Any borders, margins, or non-linked content within the submenu would instead link to the parent page. This is simply not what the user expects and will be confusing if they make a stray-click.

I will explain the issue with your current solution:

.menu-item:hover ul {
    display:block;
}

You are hovering over the <li class="menu-item"> element, which contains the link <a> and the submenu <ul class="sub-menu"> side-by-side (default of WordPress wp_list_pages()).

This is correct, however, since your <a> and <ul> elements within the parent are positioned using float and absolute positioning, the height of the menu item is not known. This is why moving your mouse below the <a> element closes the menu, there is nothing there but the background of the <ul>. That's how the system works, and that's what you need to learn before you can understand the reference you provided.

You can fix this with any of these options:

  1. Define a height for the <li> directly
  2. Clear the float using CSS: clear: left - which will calculate the height of sibling elements which were floated to the left.
  3. Stop using floats and instead use: display: inline-block
  4. Move the submenu up vertically so that it touches the <a> element. Due to font differences between browsers, this may not be reliable unless the <a> element has a fixed height as well.

Here is a solution that combines #2 and #3. Floats are used for the top-level menu items simply to remove the natural spacing between inline elements. However, the majority of the layout relies on display: inline-block. Using the child selector > we can determine the difference between top level elements and those child elements within the sub-menu. There are some colors and padding included which show you what you will want to edit.

ul.menu > li.menu-item {
    position: relative;
    float: left;
}
ul.menu > li.menu-item > a {
    display: inline-block;
    padding: 3px 5px;
    background: #dfdfdf;
}
.clear { clear: both; }

The key to this solution is to add an <li class="clear"></li>. If you cannot modify the HTML directly, you could try a pseudo-element:

ul.menu > li.menu-item:last-child:after { content: ' '; clear: both; }

Upvotes: 0

Make sure that you menu item (the <a> tag) goes all the way to the bottom of your menu, so when moving your mouse it won't actually leave the area of hovering.

add this to you .menu a css:

.menu a {
    font: normal 14px Helvetica, sans-serif;
    padding-left:5px;
    padding-top:5px;
    padding-right:5px;
    float:left;
    color:black;
    height:30px; // this here
}

See in this JSFiddle

Upvotes: 1

Related Questions