Dropdown Menu - Make the
    submenu 100% width

2019-02-15 00:29发布

问题:

I am going a bit crazy trying to achieve something my client wants. I could tell them it's not possible but I love a good challenge ;)

Basically, I'm trying to do a dropdown menu in which the dropdown <ul>, or:

ul.menu li ul

is surrounded by a div. Kind of:

<ul class="menu">
   <li>
       <a href="#">Item</a>
       <div class="submenu">
           <ul>.....</ul>
       </div>
   </li>
</ul>

I want that div to have width:100% and fill the whole width of the page but have the UL inside aligned to the appropriate <li>.

The problem is the <div class="submenu"> will be as wide as the relative container, be it the main <ul class="menu"> or a <div> wrapping the <ul class="menu">.

The website itself has 1000px width and is centered width margin:0 auto;

I hope I have explained myself properly :S Here is a link to a mock up I have put together: Dropdown Menu Mock up

Any help highly appreciated.

Thanks, Alex

回答1:

Old question, but hopefully answer will help someone. I had to work on something similar to this a month or so ago.

Here is a fiddle of what I basically did (note: you have to do some extra work for this to work the same in older IEs): http://jsfiddle.net/doubleswirve/xbLrW/2/

I didn't use a nested div and instead stuck with nested lists. With a basic markup like the following:

<div class="nav">
  <ul>

    <li>
      <a href="#">Products</a>
      <ul>
        <li><a href="#">Widget A</a></li>
        <li><a href="#">Widget B</a></li>
        <li><a href="#">Widget C</a></li>
      </ul>
    </li>

    <li>
      <a href="#">Locations</a>
      <ul>
        <li><a href="#">Location A</a></li>
        <li><a href="#">Location B</a></li>
        <li><a href="#">Location C</a></li>
      </ul>
    </li>

    <li>
      <a href="#">Staff</a>
      <ul>
        <li><a href="#">President</a></li>
        <li><a href="#">VP</a></li>
        <li><a href="#">Manager</a></li>
      </ul>
    </li>

  </ul>
</div>

You can use the following styling:

/* GENERAL */

body { overflow-x: hidden; } /* trick from css-tricks comments */

/* FIRST LEVEL */

.nav > ul > li { 
  display: inline-block; 
  position: relative; 
  padding: 3px 10px 3px 0;
  z-index: 100;
}

/* SECOND LEVEL */

.nav > ul > li > ul {
  position: absolute;
  left: 0;
  top: 100%;
  padding: 0 1000em; /* trick from css-tricks comments */
  margin: 0 -1000em; /* trick from css-tricks comments */
  z-index: 101;
  visibility: hidden;
  opacity: 0;
  background: rgba(255, 240, 240, 0.8);
}

.nav > ul > li:hover > ul {
  visibility: visible;
  opacity: 1;
}

.nav > ul > li > ul > li {
  padding: 3px 0;
}

If you wanted to get snazzy with the CSS, you could add this to the second level ul:

.nav > ul > li > ul {
  ...
  -webkit-transition: all 0.3s ease;
  -moz-transition: all 0.3s ease;
  -o-transition: all 0.3s ease;
  transition: all 0.3s ease;
}

If anyone is interested in making this work similarly in old IEs or wants deeper nested lists, let me know.

To give you a head start, here are some useful links that helped me:

  • Full browser width bars (CSS tricks article/comment)
  • Fixing z-index (helpful for IE7)

Chris Coyier really covers us at work lol.



回答2:

You're quite right, in that that box model doesn't work that way.

There is one thing I can think of, and that is to set your divs to

position:absolute

and use the top, left, right attributes to position them. But, as you say, that won't work if you have position: relative on a parent element.

To be honest, it'll be difficult to achieve this without a horrible mess of workarounds which will probably break between browsers. I've seen peers and colleagues spend ages trying to implement things like this, building more and more precarious code 'fixes' to get it to work cross-browser, receiving complaints from clients about it not working in IE6 and Firefox 1.5, only to give up on that 'feature' entirely.