【问题标题】:CSS multi-column layout of list items doesn't align properly in Chrome列表项的 CSS 多列布局在 Chrome 中未正确对齐
【发布时间】:2011-07-15 22:38:30
【问题描述】:

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

菜单比较简单:

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

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

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

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

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

我没有完全放弃列数(支持手动生成/列生成器等)的主要原因是菜单系统还涉及跨多个子菜单的拖放功能,并且具有菜单以基于列表的层次结构的内聚形式布局的数据使代码更简洁。

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

添加:

【问题讨论】:

  • 很高兴您发布了一个指向您的代码的链接,但如果您在此处粘贴原型会更有帮助:jsfiddle.net 这样人们就可以玩弄您的代码并为您提供工作原型。欢迎来到!
  • 添加了 jsFiddle 和 JS Bin 链接。

标签: css alignment css-multicolumn-layout


【解决方案1】:

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

有一天,CSS 3!

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

【讨论】:

  • 在您链接的细分文章中找到了我的答案:display: inline-block 将该属性添加到我的菜单项以及固定宽度,并解决了列流错误。感谢一百万把我带到那篇文章!
  • @BenD。也许您可以将答案作为它自己的答案来回答这个问题?
【解决方案2】:

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

【讨论】:

  • 值得注意的是,您应该将这些规则添加到列包装器的内容中,而不是列包装器本身。非常适合我。
  • 长列项目的一个问题:如果一个列项目跨越两行或多行,并且该项目是该列的最后一个并且每列仅包含两个项目,则第二行在下一行结束列。
  • 对我没有帮助
【解决方案3】:

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

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

    • 这真的很有帮助!谢谢(仅限-webkit-column-break-inside:avoid
    • 移动边距+填充从<li><a>,然后将break-inside: avoid;应用于<li>对我有用。 css-tricks.com/almanac/properties/b/break-inside 真的很有帮助。
    【解决方案5】:

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

    我已经解决了我的第一个大问题,即初始标题元素的填充,使用 :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} 
    

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

    【讨论】:

      【解决方案6】:

      我想要的结果是想要获得一个大的链接列表以显示在 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;
      }
      

      【讨论】:

        【解决方案7】:

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

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

        【讨论】:

          【解决方案8】:

          您需要将列中的每个项目显示为“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>

          【讨论】:

          • 使用 display: inline-block;帮助我们在 Chrome (FF OK) 中解决了这个问题,但我们必须在孙元素上使用它才能让它工作。
          • 对于短 li 元素,使用 width:100% 中的 display:inline-block 以在列中每行保留 1 个项目。
          • 这对li 非常有效,但我无法让它为dd/dt 工作。
          • 更新:我今天重试了编辑,由于某种原因,它现在运行良好。非常感谢!
          【解决方案9】:

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

          ul li { line-height:40px; }
          

          【讨论】:

          • 这将使多行元素看起来像几个元素。
          【解决方案10】:

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

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

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

          margin:0;
          padding:0;
          

          希望对你有帮助

          【讨论】:

            【解决方案11】:

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

            这解决了它。

            ol > :first-child {
                margin-top: 0;
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2019-06-03
              • 2018-11-15
              • 2019-05-13
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多