3

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

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

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

菜单的右端看起来很难看

忽略项目上的“文本”宽度相同。我只是画画很烂。想象一下,文本有不同的长度,但它们周围的填充相同。

使用棘手的边框(仅在项目左侧的边框)我可以将其隐藏一点,但可点击区域仍然与上图的白色部分相同。悬停效果也揭示了这个技巧。


然后我对 text-align justify 做了一些研究,并找到了这样的解决方案:“text-align: justify;” 内联块元素正确吗?

乍一看,这正是我想要的。元素对齐正确,它们一见钟情就填满了可用空间。但是有一个根本性的缺陷:它们之间存在差距:

有缝隙

这是意料之中的,因为这会将我的元素视为文本中的单词。我没有找到解决此问题的方法。


后来我开始在flexbox 领域四处寻找。这看起来很有前途的 flexbox 似乎是 css 的圣杯,但我还没有完全理解它。


基本上我想要的是这样的:

完美的

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

有没有办法做到这一点?

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


编辑

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

4

1 回答 1

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;
}

例子


由问题作者编辑:

我想我应该更新这个答案,因为我已经了解了一些关于 flexbox 的知识。

  1. 处理多行弹性盒,供应商前缀几乎没用。很难找到任何支持多行 flexbox 但带有供应商前缀的浏览器版本。通常供应商前缀指的是旧版本的 flexbox,其中多行的处理方式非常不同。

  2. 每个主流浏览器都支持这一点,除了 Firefox,但一个实现已经合并到 alpha 中,所以它会出现在Firefox 28中。大多数桌面用户会看到你的设计(仍然重要的是实现一个可用的后备)。

  3. 使用Modernizr测试多行弹性盒支持非常容易,因为弹性盒模型测试专门测试该flex-wrap属性,该属性仅存在于支持它的实现中。float: left为每个没有的浏览器实现基于后备的方法是非常干净的。

我的最终实现具有基于 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。这是因为以这种方式在回退中更容易将其浮动到右侧。

于 2013-11-11T08:59:33.857 回答