Dropdown Menu - Make the <ul> submenu 100% width

18,948

Solution 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:

Chris Coyier really covers us at work lol.

Solution 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.

Share:
18,948
elmediano
Author by

elmediano

Updated on June 04, 2022

Comments

  • elmediano
    elmediano almost 2 years

    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