set all nested li's to be width of widest li

后端 未结 6 1629
情书的邮戳
情书的邮戳 2021-01-13 21:30

How do I make nested li\'s the same width?

When I use the below code each nested li is only as wide as it\'s text + margin.

I\'d like all of the li\'s to be

相关标签:
6条回答
  • 2021-01-13 21:41

    To make all of the list items the same length as the longest, you will need to manually set the widths. There is no pure CSS method of achieving this automatically as far as I know.

    li{width:100%} Will make the list items fill the width of their container. If that is not set, then it will be the width of the user's browser window.

    0 讨论(0)
  • 2021-01-13 21:43

    You'll need to use JavaScript to set all LIs the same width as the widest LI. Here's the code if you want to use the jQuery library:

    $(document).ready(function(){
      $("#menu > li > ul").each(function() { // Loop through all the menu items that got submenu items
        var Widest=0; // We want to find the widest LI... start at zero
        var ThisWidth=0; // Initiate the temporary width variable (it will hold the width as an integer)
    
        $($(this).children()).each(function() { // Loop through all the children LIs in order to find the widest
          ThisWidth=parseInt($(this).css('width')); // Grab the width of the current LI
    
          if (ThisWidth>Widest) { // Is this LI the widest?
            Widest=ThisWidth; // We got a new widest value
          }
        });
    
        Widest+='px'; // Add the unit
    
        $(this).parent().css('width',Widest);
        $(this).children().css('width',Widest);
      });
    });
    

    CSS change:

    #menu li ul li {
      padding: 0 9px;
      background: #BDCCD4;
      padding: 0 20px;
    }
    

    Check it out at JSFiddle.

    Edit: Fixed my misunderstanding. :)

    0 讨论(0)
  • 2021-01-13 21:43

    I used following CoffeeScript to achieve described behavior:

    $ ->
        menu_toggle = (e, show) ->
            ul = $(e).find('ul')
            ul.toggle()
    
            computed = ul.hasClass 'computed_width'
            if show && !computed
                ul.width 2000 # enormous with to be sure that li’s’ texts are not wrapped
                max_width = 0
                ul.find('li').each ->
                    li = $(this)
                    width = li.width()
                    max_width = width if width > max_width
                ul.width max_width + 30 if max_width # 20 is 2 * padding + some reserve
                ul.toggleClass 'computed_width' # no need to compute every time
    
        $('li').has('ul').hover ->
            menu_toggle this, true
        , ->
            menu_toggle this, false
    
    0 讨论(0)
  • 2021-01-13 21:47

    There would be a very simple dynamic solution. To your CSS, as you posted it in the Question, just add

    #menu ul {
        display: inline-block;
        min-width: 100px;
    }
    
    #menu ul li, #menu ul li a{
        width: 100%;
        display:block;
    }
    

    and then it will be exactly as you want it to be.

    You can see how it looks here:

    <style type="text/css" media="all">
    * {
        padding:0; 
        margin:0;
    }
    body, html {
        width: 100%;
        height: 100%;
    }
    #wrapper {
        width: 800px;
        height: 100%;
        margin: auto;
    }
    #menu {
        margin: 0 0 0 8px; 
        padding: 0;
        font-size: 14px; 
        font-weight: normal;
    }
    
    #menu ul {
        list-style-type:none; 
        list-style-position:outside; 
        position:relative; 
        z-index:300; 
        height: 32px;
        font-weight:bold; 
        white-space: nowrap;
        padding:0;
    } 
    #menu a {text-decoration:none; 
        line-height: 32px;
    } 
    #menu a:hover {
    
    } 
    #menu li {
        float:left; 
        position:relative; 
        display: inline; 
        height: 100%; 
        list-style-type: none; 
        padding: 0 20px;
        background: #ccc;
    } 
    #menu ul {
        position:absolute; 
        display:none; 
        left:0px;
        background: #BDCCD4;
        width:100%;
    } 
    #menu ul a, #menu li a {
        display: block;
    }
    #menu li ul {
        background: #BDCCD4;
        display:block;
    }
    #menu li ul a {
        font-weight: normal;
        height:auto; 
        float:left;
    } 
    #menu ul ul {
        padding: 0 9px;
        display:block;
    } 
    #menu li ul li {
        padding: 0 9px;
        background: #BDCCD4;
    }
    #menu li:hover {
        background: #ffffd;
        height: 32px;
    }
    #menu li li:hover, #menu li li li:hover {
        background: #ffffd;
        height: 32px;
    }
    #menu li a:link, #menu li a:visited {
        text-decoration: none;
        color: #003E7E;
        margin: auto;
    }
    
    #menu ul {
        display: inline-block;
        min-width: 100px;
    }
    
    #menu ul li, #menu ul li a{
        width: 100%;
        display:block;
    }
    <ul id="menu">
        <li <a href="#" title="Menu a">Menu a</a></li>
        <li <a href="#" title="Menu b">Menu b</a></li>
        <li <a href="#" title="Nested Menu">Nested Menu</a>
            <ul>
                <li <a href="#" title="Menu Item">Menu Item</li>
                <li <a href="#" title="Long Menu Item">Long Menu Item</a></li>
                <li <a href="#" title="Longer Menu Item">Longer Menu Item</a></li>
            </ul>
        </li>
        <li <a href="#" title="Menu z">Menu z</a></li>
    </ul>

    0 讨论(0)
  • 2021-01-13 21:50

    Simply adding width: 100% for #menu li ul li works for me. To make it work for even longer items, use width: auto on #menu li ul. EDIT 2: Added padding workaround.

    The new CSS:

    <style type="text/css" media="all">
    * {
        padding:0;
        margin:0;
    }
    body, html {
        width: 100%;
        height: 100%;
    }
    #wrapper {
        width: 800px;
        height: 100%;
        margin: auto;
    }
    #menu {
        margin: 0 0 0 8px;
        padding: 0;
        font-size: 14px;
        font-weight: normal;
    }
    
    #menu ul {
        list-style-type:none;
        list-style-position:outside;
        position:relative;
        z-index:300;
        height: 32px;
        font-weight:bold;
        white-space: nowrap;
        padding:0;
    }
    #menu a {text-decoration:none;
        line-height: 32px;
    }
    #menu a:hover {
    
    }
    #menu li {
        float:left;
        position:relative;
        display: inline;
        height: 100%;
        list-style-type: none;
        padding: 0 20px;
        background: #ccc;
    }
    #menu ul {
        position:absolute;
        display:none;
        left:0px;
        background: #BDCCD4;
        width:100%;
    }
    #menu ul a, #menu li a {
        display: block;
    }
    #menu li ul {
        background: #BDCCD4;
        display:block;
        width: auto;
    }
    #menu li ul a {
        font-weight: normal;
        height:auto;
        float:left;
    }
    #menu ul ul {
        padding: 0 0 0 9px;
        display:block;
    }
    #menu li ul li {
        padding: 0 9px;
        background: #BDCCD4;
        width: 100%;
    }
    #menu li:hover {
        background: #ffffd;
        height: 32px;
    }
    #menu li li:hover, #menu li li li:hover {
        background: #ffffd;
        height: 32px;
    }
    #menu li a:link, #menu li a:visited {
        text-decoration: none;
        color: #003E7E;
        margin: auto;
    }
    

    The result is here: http://jsfiddle.net/y83zm/2/ EDIT 2 Added fix to solve a weird padding issue, see http://jsfiddle.net/y83zm/5/

    0 讨论(0)
  • 2021-01-13 21:55

    A simple jQuery solution worked for me:

    $(document).ready(function(){
        $('.sub-menu').each(function(){
            $(this).width(2000);
            var width = 0;
            $(this).children('li').each(function(){
                if ($(this).children('a').width() > width)
                    width = $(this).children('a').width();
            });
            $(this).width(width);
        });
    });
    
    0 讨论(0)
提交回复
热议问题