Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In search for a perfect dropdown menu: stretching to full width, equal width items, pure CSS. Please help resolve a glitch

I'm trying to implement a menu with the following features:

  • horizontal;
  • equal width menu items;
  • menu items spread across the whole page width (not just crowd at the left side);
  • dynamic (css rules should not rely on predefined number of items);
  • drop-down second level with vertically aligned items;
  • pure CSS (no JS!).

This seems to describe a perfect menu as i see it.

I have almost succeded making it using the beautiful display: table-cell; technique ( tags are omitted for simplicity):

<ul>
    <li>Menu item</li>
    <li>
        Expandable ↓
        <ul>
            <li>Menu</li>
            <li>Menu item</li>
            <li>Menu item long</li>
        </ul>
    </li>
    <li>Menu item</li>
    <li>Menu item</li>
</ul>
ul {
    display: table;
    table-layout: fixed;
    width: 100%;
}

li {
    display: table-cell;
    text-align: center;    
}

li:nth-child(even){
    background-color: lightblue;    
}

li:nth-child(odd){
    background-color: lightskyblue;    
}

li ul { display: none; }

li:hover ul {
    display: block;
    position: absolute;
}

li:hover ul li {
    display: block;
}

The only problem is that submenu items appear full-page width and partially outside the browser window, forcing a horizontal scrollbar to appear:

Gah! StackOverflow won't let me post images. Test it out live on JSFiddle: http://jsfiddle.net/6PTpd/9/

I can overcome this by adding float: left; clear: both; to li:hover ul li. But when i do, submenu items have different widths:

Fiddle: http://jsfiddle.net/6PTpd/10/

...or width width: 15%;: http://jsfiddle.net/6PTpd/12/

Both fixes are ugly and resolve neither the equal width issue nor the horizontal scrollbar issue.

UPD While brushing up this post i've found some solution of the scrollbar problem: set li:hover ul width to 0. But this forces to spectify the width of submenu items in an absolute value. :( See http://jsfiddle.net/6PTpd/13/

Also, this solution may suck hard when the last menu item is expanded. Depending on the screen width, it may still blow the page wider than the window: http://jsfiddle.net/6PTpd/15/

Questions:

  1. How do i make submenu items appear same widths as their parent and without enabling the horizontal scrollbar?
  2. Is there another CSS technique that allows creating a menu with ALL the prerequisites described in the beginning of the post?

I've found a lot of examples, but each of them either is non-stretching (floats items to the left) or non-dynamic (uses sizes taken from a predefined number of items, e. g. width: 20% for each of five first-level items or, even worse, uses absolute sizes!).

like image 656
Andrey Mikhaylov - lolmaus Avatar asked Nov 04 '22 16:11

Andrey Mikhaylov - lolmaus


1 Answers

This isn't the best way to do this, but here's your solution: http://jsfiddle.net/6PTpd/17/

The funny thing about CSS is that even the masters are always finding new things that you can do with it. It's an amazing language in that way. Which is why I gave you that fiddle, so that you could learn what you were doing wrong (It was mainly the absolute positioning, BTW). BUT there are also some loopholes that you should be aware of.

So let me explain why you probably shouldn't use the code in that JSFiddle. The first problem is that it uses display: none. That's a problem because screen-readers don't read text that isn't displaying. (more on that over here: http://css-tricks.com/places-its-tempting-to-use-display-none-but-dont/)

The second problem is that it displays on hover. In a world where touch screens are becoming more and more prevalent, hover is no longer the best option.

You can still use it if you want to, just thought you should know about the drawbacks.

TL;DR: If screen-reader and touch screen support is an issue, then I would encourage you to search out another option.

like image 146
Timothy Miller Avatar answered Nov 08 '22 03:11

Timothy Miller