css多线菜单占据了整个宽度

时间:2013-11-06 13:02:31

标签: css menu

可能已有解决方案或示例,但我一直找不到。

我想创建一个菜单,其中包含不同数量的菜单项,每个菜单项都有不同的宽度(取决于它们的内容)。如果菜单项太多,我希望它们占用多行。

我的第一个解决方案是一个简单的浮动。一切都很好,但在行的末尾有一个不均匀的未占用空间:

The right end of the menu looks ugly

忽略项目上的“文字”宽度相同。我只是在画画。想象一下,文本的长度各不相同,但周围的填充方式相同。

有一个棘手的边框(边框只在项目的左侧)我可以隐藏一点,但可点击区域仍然与上图中的白色部分相同。悬停效果也无法解决问题。


然后我对text-align justify进行了一些研究,找到了这样的解决方案:"text-align: justify;" inline-block elements properly?

首先一瞥这就是我想要的。元素正确对齐,它们第一眼就填满了可用空间。但是存在一个根本性的缺陷:它们之间存在差距:

There are gaps

这是预期的,因为它将我的元素视为文本中的单词。我发现无法解决这个问题。


后来我开始在flexbox land环顾四周。这看起来很有前途的flexbox似乎是css的圣杯,但我还没能绕过它。


基本上我想要的是:

Perfect

按钮填满可用空间,菜单是多行的(当一行有太多元素时),整个菜单都是可点击的(具有可见的悬停效果)。

有办法做到这一点吗?

我对使用javascript驱动的解决方案犹豫不决(比如计算和调整元素的宽度)。但如果有一个非常干净的解决方案,我可能会最终使用它。


修改

菜单here看起来不错,但仅当菜单是单​​行时。这会通过将最后一个元素添加到不同的列表并通过添加大量空格和不可见的:after { content ". . ." }元素来破解最后一个元素。

1 个答案:

答案 0 :(得分:3)

如果您使用以下flexbox样式,它将在IE10和chrome中实现您想要的效果。但是我不认为这在所有浏览器中都完全支持。

<强> HTML

<ul>
    <li>test test</li>
    <li>test</li>
    <li>test testtest</li>
    <li>testtest</li>
    <li>test</li>
    <li>test test test</li>
    <li>test test</li>
    <li>test</li>
</ul>

<强>的CSS

ul {
    list-style:none; margin:0; padding:0; 
    display: -webkit-box;
    display: -moz-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;
    -webkit-flex-direction: row;
    -ms-flex-direction: row;
    -moz-flex-direction: row;
    flex-direction: row;
    -webkit-flex-wrap: wrap;
    -ms-flex-wrap: wrap;
    -moz-flex-wrap: wrap;
    flex-wrap: wrap;
    width: 300px; 
}

li {
     white-space:nowrap;  
     border:1px solid #cccccc; 
     padding:5px; 
    -webkit-flex: auto;
    -moz-flex: auto;
    -ms-flex: auto ;
    flex: auto;
}

Example


由问题作者编辑:

我想我应该更新这个答案,因为我已经学习了一些关于flexbox的东西。

  1. 处理多线Flexbox,供应商前缀几乎没用。很难找到支持多线Flexbox的任何浏览器的版本,但有一个供应商前缀。通常,供应商前缀是指older version的flexbox,其中多行的处理方式截然不同。

  2. 除了Firefox之外,每个主流浏览器都支持此功能,但实现已经合并为alpha,因此它将显示在Firefox 28中。大多数桌面用户都会看到您的设计(实现可用的回退仍然很重要)。

  3. 使用Modernizr测试多线Flexbox支持非常简单,因为 Flexible Box Model 测试专门测试flex-wrap属性,该属性仅存在于支持它的实现。为每个没有的浏览器实现基于float: left的回退非常干净。

  4. 我的final implementation具有基于Modernizr的后备功能,如下所示:

    ul {
        /* general */
        list-style: none;
        margin: 0;
        padding: 0;
        width: 100%;
    }
    .flexbox ul {
        display: flex;
        flex-flow: row wrap;
    }
    li {
        /* general */
        white-space: nowrap;
        border: 1px solid #555555;
    
        /* fallback */
        float: left;
    }
    .flexbox li {
        flex: auto;
    }
    li:first-child {
        /* general */
        text-align: right;
        order: 1;
    
        /* fallback */
        float: right !important;
    }
    

    它应该在每个浏览器中工作,尽管后备实现并不像flexbox那样整洁。

    另请注意,li:first-child是Flexbox的最后一个元素。那是因为order: 1属性。所有其他元素的默认值order为0.这是因为以这种方式将其浮动到右后方更容易。