63

我正在构建一个以多列格式呈现给用户的菜单系统。CSS3 中的column-count属性让我完成了 90% 的工作,但在 Chrome 下对齐时我遇到了困难。

菜单比较简单:

  • 由column-count 属性划分为多列的无序列表
  • 列应按顺序填充,因此column-fill: auto
  • 菜单项表示为列表项
  • 每个列表项都有一个可点击的锚标签,通过display: block完全扩展

我遇到的对齐问题最明显的是每个列表项的顶部边框和一些背景颜色。在 Firefox 中,列表项总是在每一列中整齐地对齐,不会渗入上一列/下一列。在 Chrome 中,对齐是一个废话,随列表项的数量和任何填充/边距属性而变化。

我在这里发布了一个简单测试用例的代码:http: //pastebin.com/Ede3JwdG

问题应该立即显而易见:在 Chrome 中,第二列中的第一个列表项会渗入第一列。当您删除列表项(单击它们)时,您可以看到对齐方式进一步分解。

我尝试调整列表项的填充/边距,但无济于事:Chrome 似乎有一个有缺陷的算法,用于在多列布局中流动内容。

我没有完全放弃列数(支持手动生成/列生成器等)的主要原因是菜单系统还涉及跨多个子菜单的拖放功能,并布置了菜单数据作为一个有凝聚力的基于列表的层次结构使得代码干净。

有没有办法解决 Chrome 中的对齐问题,还是我现在应该放弃列数

添加:

4

11 回答 11

88

您需要将列中的每个项目显示为“inline-block”。这将解决您的问题,而无需使用 jQuery。

此外,可以指定每个元素具有width: 100%以使它们使用行的完整宽度。

这是一个工作示例:

$(document).ready(function() {
    for( var i = 0; i < 24; i++ ) {
        $("ul.newslist").append("<li><a href='#'>Item</a></li>");
    }
    $("ul.newslist > li").click(function() {
        $(this).remove();
    })
});
ul.newslist {
    columns: 5;
    background-color: #ccc;
    padding: 16px 0;
    list-style: none;
}

ul.newslist > li {
    display: inline-block;
    width: 100%;
    border-top: 1px solid #000;
}

ul.newslist > li > a {
    display: block;
    padding: 4px;
    background-color: #f6b;
    text-decoration: none;
    color: inherit;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="newslist"></ul>

于 2017-02-20T16:22:22.627 回答
23

margin-*通过将属性应用于多列容器内的元素,我设法平衡了不均匀的垂直对齐列。

.content {
  column-width: 15em; /* or could be column-count, however you want to set up multi columns */
}
.content > section {
  -webkit-margin-before: 0;
  -webkit-margin-after: 0;
}
于 2012-03-06T11:02:54.203 回答
17

至于垂直边距泄漏。您可以用伪元素替换边距。然后将其高度设置为所需的边距值。您还需要对-webkit-column-break-inside: avoid;包含伪元素的元素进行设置,使其不会移动到另一列。仅在 css-hack(不推荐)或js-detection(最佳方式)的帮助下为 webkit 执行此操作。这是CSS:

.element {
  -webkit-column-break-inside: avoid;
}
.element:after {
  content: '';
  display: block;
  height: 20px;
}
于 2015-10-11T23:27:42.473 回答
16

我也玩过,我在网上看到的几个来源使它似乎是 webkit 的一个已知问题。可以在这里找到一个很好的细分:http: //zomigi.com/blog/deal-breaker-problems-with-css3-multi-columns/

有一天,CSS 3!

也许尝试像http://welcome.totheinter.net/columnizer-jquery-plugin/这样的 jQuery 插件?

于 2011-03-15T16:46:35.347 回答
7

我在多列列表上的垂直对齐时遇到了问题。原来问题在于我在列表 li 上使用了底部填充——我将 li 样式更改为使用底部边距,并且列再次与顶部对齐。

于 2015-03-13T23:38:25.393 回答
3

我想要的结果是想要获得一个大的链接列表以显示在 3 列中。简单地column-break-inside:avoid;单独使用在 webkit 中是行不通的。

HTML

<div class="links">
  <ol>
    <li><a>link</a></li> <!-- x 50 -->
  </ol>
</div>

CSS:

.links ol {
  -webkit-column-count: 3;
  -moz-column-count: 3;
  column-count: 3;
}

.links li {
  display: block;
  border: 1px solid $background-colour; //to appear invisible
  -moz-column-break-inside:avoid;
  -webkit-column-break-inside:avoid;
  column-break-inside:avoid;
}

.links a {
  display: block;
  margin-bottom: 10px;
}

解决方案(如果你愿意的话,怪癖)

我在列表项周围添加了一个 1px 边框,该边框似乎包含其子项的边距,然后每列与顶部对齐。

编辑:这似乎只有在您使用全局时才需要border-box

html {
  box-sizing: border-box;
}
*, *:before, *:after {
  box-sizing: inherit;
}
于 2016-11-18T09:22:27.650 回答
2

我通过删除子元素上的垂直边距来解决这个问题,然后增加子元素的行高以复制所需的间距。

我还注意到我可以通过删除子边距并将其转换为孙子填充来解决此垂直对齐问题。

于 2016-12-19T22:14:49.710 回答
0

我也在为此苦苦挣扎,对于一个包含许多数据和标题的报告系统,我需要在多个列上流动以获得更宽的屏幕。

我已经解决了我的第一个大问题,即初始标题元素的填充,使用:first-child伪类(这包含在此处未显示的宽屏幕的@media 规则中):

列定义:

.dimSlider .multicol {
  -moz-columns: 4;
  -webkit-columns: 4;
  columns: 4;
}

取消填充时在顶部.multicol

.dimSlider .multicol h3 {
  padding-top: 0;
}

取消第一个元素的填充和边距(color: blue;以便我查看规则是否捕获):

.dimSlider .multicol .criteria:first-child h3 {
  padding: 0 2%;
  margin: 0;
  color: blue;
}

到目前为止,这在我的 Firefox 中看起来要整洁得多。我会看看是否还有更多的修改要做,但目前在 Firefox 中,文本看起来在顶部对齐,这是最重要的。

编辑:确实,基于 webkit 的浏览器的问题似乎更糟。为了彻底解决这个问题,我修改了模板,以便<div></div>在所有标题部分周围都有一个,这样我就可以在 div 的末尾而不是标题的开头添加填充/边距。现在在 webkit 浏览器中它看起来也很好。

顺便说一句,在多列中使用百分比测量非常棘手,因为百分比似乎是根据列的宽度而不是父元素的全局宽度计算的。我通过在列的父元素中添加填充来改变这一点。

但最大的困难是 Firefox 不支持任何 column-span 或 break-inside 属性,所以当我的内容很少时,它仍然分布在列上,就像每列一两行一样。再次,Smarty 进行救援:

{if $element|@count <= 10}
<div class="nocol"> 
{/if} 

到目前为止,它现在对我有用......

于 2016-10-26T09:53:26.533 回答
0

在搜索有关此的信息时,我遇到了您的问题,今天我一直在检查列表的元素。

我发现 UL 元素仅在第一列上应用边距。

只需在 css 中应用 0 填充和边距,它们就会对齐

margin:0;
padding:0;

希望能帮助到你

于 2020-07-05T12:26:53.133 回答
0

我有一个两列的有序列表,默认情况下左列被向下推 - 所以它没有与右列对齐。

这解决了它。

ol > :first-child {
    margin-top: 0;
}
于 2021-10-26T19:47:18.623 回答
-2

这是多列空间问题的解决方案

ul li { line-height:40px; }
于 2017-07-20T12:25:09.323 回答