views:

166

answers:

2

Hi All,

I have built a persistent dropline menu with two levels using only CSS. It is pretty standard.

It is a nested set of UL's and the UL's :hover state is what shows and hides the sub menu levels.

Something like this:

| *Pets* | Colors | Cars |
| Cats | Dogs | Birds| Goats | Sheep | 


| Pets | *Colors* | Cars |
| Red | Orange | Green | Blue| Yellow |

I then added a 1px border at the bottom of the first level UL element. Like this:

| *Pets* | Colors | Cars |
--------------------------------------
| Cats | Dogs | Birds| Goats | Sheep | 

When I hover over a first level item (Pets), and then move the mouse down to the second level (Cats), the entire second level disappears.

I finally figured out that the UL's 1px border is not included in the hover area for the UL.

Can I add a border to the bottom of a dropline menu level without messing up the menu hovering?

Thanks!

+1  A: 

You can use a background and give it a 1px black line at the bottom, or you can add an element and position it absolutely with a 1px height and black background. I would go with the background option, because it´s much easier.

Jouke van der Maas
Thank you very much for you answer. I had thought about the background image solution too. I hadn't thought of the 1px height absolutely positioned block.
dbasch
+1  A: 

Since you're actually adding the :hover state to the <li>s within the <ul>, the border on the parent <ul> isn't included in the :hover area. It would solve your problem to add the border to each <li> instead of the parent <ul>. Make sure to add left and right margins of 0 to the <li>s and even if you do that you still might need to add a negative left margin or left position to remove any gaps in the border, as well as add override styles to the submenu <li>s if they end up with a bottom border as well.


EDIT: Ok, I've got a solution that will hopefully work for you, using the following HTML:

<ul>
    <li>Main1
      <ul><li>sub1</li><li>sub2</li><li>sub3</li></ul>
    </li>
    <li>Main2
      <ul><li>sub1</li><li>sub2</li><li>sub3</li></ul>
    </li>
    <li>Main3
      <ul><li>sub1</li><li>sub2</li><li>sub3</li></ul>
    </li>
    <li>Main4
      <ul><li>sub1</li><li>sub2</li><li>sub3</li></ul>
    </li>
</ul>

and this CSS:

ul { background:#ccc; border-bottom:5px solid #0c0; height:25px; }
ul li { cursor:pointer; display:inline-block; position:relative; height:30px; 
        zoom:1; _display:inline; }
ul li:hover ul { display:block; }
ul li ul { border:0 none; display:none; position:absolute; top:30px; }
ul li ul li { display:inline; padding:5px; }

​ ​The key parts here are:

  • Set height of ul to be smaller than the height of the main ul li by an amount equal to the border-width
  • Set display:inline-block on li so height attribute takes effect
    • (Note: zoom:1; _display:inline; for IE6)
  • Set position:relative on the main ul li and position:absolute on the sub 'ul li ul' with 'top' value of the main 'ul li' height

Tested and working: http://jsfiddle.net/TKrSM/1/ (may have to adjust height and top values for padding in your version)

mVChr
Thank you for your answer. I tried adding a border to the LI child elements but it raised a few problems. For instance some of the menu levels only have a few items. They are not wide enough to span the entire page width. Any borders on the LI are also not wide enough to span the whole page width.
dbasch
Try new solution, see edited answer.
mVChr
Wow! Awesome! That is exactly what I needed. Thanks for the answer.
dbasch
One more question. How can I get the sub UL elements to left align with the top level UL? They appear underneath the parent LI that is being hovered. Thanks!
dbasch