CSS: Kiinteä vaakasuoralla valikossa, vaihtelevilla välilehdillä, ul

original title: "CSS: Fixed with horizontal menu, with variable width tabs, using ul"


Translate

I have a horizontal menu. The markup looks like this:

<ul class="menu">
   <li>Item 1</li>
   <li>Longer Item 2</li>
   <li>Item 3</li>
</ul>

Submenus and suckerfish dropdowns will come later.

The ul needs to span the width of the page (e.g. 100% or 1000px).

The lis should vary in width based on their content.

So the result would look like this:

-----------------100% of page------------
|--Item 1--|--Longer item 2--|--Item 3--|

Now it is easy to do this by fixing a width for each li tag, but because the menu will be CMS driven I need to allow the width of the tabs to vary automatically. With a table this would be trivial, but I can't think of a way to do it with a ul.



Minulla on vaakasuora valikko. Merkintä näyttää tältä: <ul class="menu"><li> Kohde 1 </li><li> Pidempi kohde 2 </li><li> Kohde 3 </li></ul> Alivalikko ...

Tämä on yhteenveto käännöksen jälkeen. Jos haluat tarkastella koko käännöstä, napsauta käännä-kuvaketta


Kaikki vastaukset
  • Translate

    This is a case for

    Display:Table-Man

    ul {
      display: table;
      width: 100%;
      table-layout: fixed;
    }
    li {
      display: table-cell;
    }
    

    Unfortunately, you should abandon the thought of supporting IEs 6 and 7, but else this is the way to go (or switching to HTML tables, which might or might not be so far away from the semantic content of the markup).


  • Translate

    Here's my jquery solution:

    var actualWidth = 1000;
    var totalLIWidth = 0;
    
    // Calculate total width of list items
    var lis = $('ul li');
    
    lis.each(function(){
        totalLIWidth += $(this).width();
    });
    
    // Work out how much padding we need
    var requiredPadding = Math.round(((actualWidth-totalLIWidth)/lis.length)/2);
    
    // To account for rounding errors, the error is going to be forced into the first tab.
    var roundingErrorFix = (requiredPadding*lis.length*2)+totalLIWidth-actualWidth;
    
    // Apply padding to list items
    lis.each(function(i) {
        if(i==0) {
            $(this).css('padding-left',requiredPadding-roundingErrorFix+'px')
                .css('padding-right',requiredPadding-roundingErrorFix+'px');
        }
        else {
            $(this).css('padding-left',requiredPadding+'px')
                .css('padding-right',requiredPadding+'px');
        }
    });
    

  • Translate

    If you're happy using JavaScript, jQuery could solve the issue as follows

    var $menu, totalwidth;
    
    $menu = $('ul.menu');
    totalwidth = ($menu.width()/100);
    
    $('ul.menu li').each(function(){
        this.css('width',String(Math.floor(this.width()/totalwidth))+'%');
    });
    
    $menu.css('width','100%');
    

    That's untested, but looks right to me. Comment if you've any questions at all.


  • Translate

    I reckon boldewyn's suggestion should work. I would use this approach for modern browsers and then use conditional comments to feed the following to ie6/7, so that the nav looks ok there , though won't span the 100% width.

    ul {
      width: 100%;
    }
    li {
      float:left; // or display:inline-block;
    }
    

  • Translate

    If you are trying to style the ul (such that it stretches across the entire page), your best bet is to wrap it in a div, and style the div, and then allow the ul to just stretch as far as its content carries it