gwb1231 gwb1231 - 5 months ago 10
CSS Question

How to prevent menu from closing when losing mouse focus?

I built a nice drop down menu using examples I had found on the web but my manager has run into the issue that the menu can be hard to use at times because if the mouse falls off of the menu it closes. I've read a few examples on how to get around it here, but my issue is that I can't get these solutions to work with my code.

Can someone give me a few pointers? My CSS code and a html example is included below:



#cssmenu ul,
#cssmenu li,
#cssmenu span,
#cssmenu a {
padding: 0;
position: relative;
margin-left:auto;
margin-right:auto;
text-align:center;
font-family: "charles modern"
}
#cssmenu {
line-height: 1;
background: #ffffff;
margin-left:auto;
margin-right:auto;
text-align:center;
}
#cssmenu .padding{
display: block;
position: absolute;
z-index: 78;

width: 100%;
height: 100%;

top: 0px;
left: 0px;
background: none !important;
}
/* Padding amount for first-level dropdown */
#cssmenu > li > .submenu > .padding{
width: 400%;
left: -30%;
height: 160%;
}

#cssmenu .buffer{
display: block;
position: absolute;
bottom: 0px;
right: 100%;

width: 100%;
height: 100%;
background: none !important;
}

#cssmenu .shadow{
display: none !important;
}
#cssmenu:after,
#cssmenu ul:after {
content: '';
display: block;
clear: both;
}
#cssmenu a {
background: #ffffff;
color: #00A0DF;
display: block;
font-family: "charles modern", "charles modern light", Calibri, sans-serif;
font-weight: bold;
padding: 19px 20px;
text-decoration: none;
margin-left:auto;
margin-right:auto;
text-align:center;
z-index:99999;

}
#cssmenu ul {
list-style: none;
}
#cssmenu > ul > li {
display: inline-block;
float: center;
margin:0 auto;
}
#cssmenu.align-center {
text-align: center;
}
#cssmenu.align-center > ul > li {
float: none;
}
#cssmenu.align-center ul ul {
text-align: left;
}
#cssmenu.align-right > ul {
float: right;
}
#cssmenu.align-right ul ul {
text-align: right;
}
#cssmenu > ul > li > a {
color: #ffffff;
font-size: 12px;
}
#cssmenu > ul > li:hover:after {
content: '';
display: block;
width: 0;
height: 0;
position: absolute;
left: 50%;
bottom: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-bottom: 10px solid #0fa1e0;
margin-left: -10px;
}
#cssmenu > ul > li:first-child > a {
border-radius: 5px 0 0 0;
-moz-border-radius: 5px 0 0 0;
-webkit-border-radius: 5px 0 0 0;
}
#cssmenu.align-right > ul > li:first-child > a,
#cssmenu.align-center > ul > li:first-child > a {
border-radius: 0;
-moz-border-radius: 0;
-webkit-border-radius: 0;
}
#cssmenu.align-right > ul > li:last-child > a {
border-radius: 0 5px 0 0;
-moz-border-radius: 0 5px 0 0;
-webkit-border-radius: 0 5px 0 0;
}
#cssmenu > ul > li.active > a {
color: #047aea;
text-align: center;
padding: 14px 14px;
font-size:150%;
font-style: bold;
background: #ffffff;
}

#cssmenu > ul > li:hover > a {
background-color: #00A0DF;
color: white;
}

#cssmenu .has-sub {
z-index: 1;
}
#cssmenu .has-sub:hover > ul {
display: block;
}
#cssmenu .has-sub ul {
display: none;
position: absolute;
width: 250px;
top: 100%;
left: 0;
font-size: 100%;
}
#cssmenu.align-right .has-sub ul {
left: auto;
right: 0;
}
#cssmenu .has-sub ul li {
*margin-bottom: -1px;
}
#cssmenu .has-sub ul li a {
background: #f2f2f2;
display: block;
line-height: 120%;
padding: 6px 6px;
color: black;
font-syle: bold;
font-size: 105%;
}
#cssmenu .has-sub ul li {
background: #f2f2f2;
}
#cssmenu .has-sub ul li:hover a {
background: #00A0DF;
}
#cssmenu ul ul li:hover > a {
color: #ffffff;
}
#cssmenu .has-sub .has-sub:hover > ul {
display: block;
}
#cssmenu .has-sub .has-sub ul {
display: none;
position: absolute;
left: 100%;
top: 0;
height: 250px;
overflow: auto;
}
#cssmenu.align-right .has-sub .has-sub ul,
#cssmenu.align-right ul ul ul {
left: auto;
right: 100%;
}
#cssmenu .has-sub .has-sub ul li a {
background: #f2f2f2;
}

#cssmenu .has-sub .has-sub ul li {
background: #f2f2f2;
}

#cssmenu .has-sub .has-sub ul li a:hover {
background: #00A0DF;
}
#cssmenu ul ul li.last > a,
#cssmenu ul ul li:last-child > a,
#cssmenu ul ul ul li.last > a,
#cssmenu ul ul ul li:last-child > a,
#cssmenu .has-sub ul li:last-child > a,
#cssmenu .has-sub ul li.last > a {
border-bottom: 0;
}

<div id='cssmenu'>
<ul>
<li class='active has-sub'><center>Image 1</center></a>
<ul>
<li class='has-sub'><a href='#'><span>Add New Item</span></a></li>
<li class='has-sub'><a href='#'><span>View Item</span></a></li>
<li class='has-sub last'><a href='#'><span>Item With Sub-Items:</span></a>
<ul>
<li><a href='#'><span>User 1</span></a></li>
<li><a href='#'><span>User 2</span></a></li>
</ul>
</li>
</ul>
<li class='active has-sub'><center>&nbsp;&nbsp;&nbsp;&nbsp;Image 2</center></a>
<ul>
<li class='has-sub'><a href='#'><span>Add New Item</span></a></li>
<li class='has-sub'><a href='#'><span>View Item</span></a></li>
</ul>
</li>
</ul>
</div>




Answer

EDIT: Now using a different (simpler) method involving borders and container divs. Just change the color of the border property of .level-2-menu, .level-3-menu from red to transparent in your actual code. The only issue is the level 3 menu blocking the bottom right corner of the previous level 2 item.

new jsFiddle


It sounds like what you need is some area around each menu where you can be off the visible menu but still keep the menu open. Here is some code to demonstrate the concept. You should be able to adapt the concept into your code and style it however you like.

jsFiddle

The background-color: red is just to make the extra hover area visible for demonstration purposes.

HTML:

<div class="cssmenu">
  <ul class="level-1-menu">
    <li class="level-1-item">
      <a href="#">Level 1 Item 1</a>
      <ul class="level-2-menu">
        <li class="level-2-item"><a href="#">Level 2 Item 1</a></li>
        <li class="level-2-item"><a href="#">Level 2 Item 2</a></li>
        <li class="level-2-item">
          <a href="#">Level 2 Item 3 with Sub-Items</a>
          <ul class="level-3-menu">
            <li class="level-3-item"><a href="#">Level 3 Item 1</a></li>
            <li class="level-3-item"><a href="#">Level 3 Item 2 longer</a></li>
          </ul>
        </li>
      </ul>
    </li>
    <li class="level-1-item">
      <a href="#">Level 1 Item 2</a>
      <ul class="level-2-menu">
        <li class="level-2-item"><a href="#">Level 2 Item 1</a></li>
        <li class="level-2-item"><a href="#">Level 2 Item 2 longer</a></li>
      </ul>      
    </li>
  </ul>
</div>

CSS:

.cssmenu {
  background-color: white;
}
.cssmenu ul {
  background-color: white;
  list-style: none;
  padding: 0;
}

.cssmenu li {
  padding: 20px 0;
  position: relative;
}

.cssmenu li:hover {
  background-color: lightblue;
}

.cssmenu li a {
  padding: 20px;
}

.level-1-menu {
  text-align: center;
}

.level-1-item {
  display: inline-block;
  text-align: left;
}

.level-2-menu,
.level-3-menu {
  display: none;
  position: absolute;
  white-space: nowrap;
}

.level-1-item:hover .level-2-menu,
.level-2-item:hover .level-3-menu {
  display: block;
}

.level-2-menu {
  left: 0;
  top: 100%;
}

.level-3-menu {
  left: 100%;
  top: 0;
}

.level-2-item {
  position: relative;
}

.level-2-item::after,
.level-3-item::after {
  background-color: red;
  bottom: 0;
  content: '';
  left: -30px;
  position: absolute;
  right: -30px;
  top: 0;
  z-index: -1;
}

.level-2-item:first-child::after,
.level-3-item:first-child::after {
  top: -30px;
}

.level-2-item:last-child::after,
.level-3-item:last-child::after {
  bottom: -30px;
}