列表项的CSS多列布局在Chrome中无法正确对齐

时间:2011-03-15 16:24:08

标签: css css3 alignment css-multicolumn-layout

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

菜单相对简单:

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

我所拥有的对齐问题最明显,每个列表项都有一个顶部边框和一些背景颜色。在Firefox中,列表项始终在每列中干净地对齐,从不会流入上一列/下一列。在Chrome中,对齐是一个废话,根据列表项的数量和任何填充/边距属性而变化。

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

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

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

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

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

增加:

10 个答案:

答案 0 :(得分:53)

您需要将列中的每个项目显示为“内联块”。这将解决您的问题,而无需使用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>

答案 1 :(得分:19)

我设法通过将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;
}

答案 2 :(得分:16)

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

有一天,CSS 3!

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

答案 3 :(得分:13)

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

.element {
  -webkit-column-break-inside: avoid;
}
.element:after {
  content: '';
  display: block;
  height: 20px;
}

答案 4 :(得分:6)

我在多列列表上遇到垂直对齐问题。原来问题是我在我的列表中使用了底部填充 - 我改变了li样式而不是使用底部边距,并且列再次对齐顶部。

答案 5 :(得分:2)

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

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

答案 6 :(得分:1)

我希望获得的结果是希望获得一个包含三列显示链接的大量链接。仅仅使用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;
}

答案 7 :(得分:0)

我也在努力解决这个问题,因为报告系统包含许多数据和带有填充/边距的标题,我需要在多个列上流动以获得更宽的屏幕。

我已经解决了我的第一个重大突破,初始title元素的填充,: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浏览器中,它看起来也很好。

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

但最大的困难是Firefox不支持任何列跨度或内部属性,因此当我的内容非常少时,它仍会分布在列上,就像每行上有一两行一样。再次,Smarty救援:

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

到目前为止,它现在适用于我...

答案 8 :(得分:0)

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

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

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

margin:0;
padding:0;

希望有帮助

答案 9 :(得分:-2)

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

ul li { line-height:40px; }