【问题标题】:CSS columns with left-right flow左右流的 CSS 列
【发布时间】:2013-02-02 05:25:09
【问题描述】:

假设我有一个div,它将包含一组元素 (div),它们可能具有不同的高度,但它们都将具有相同的宽度。

我目前已经通过同位素 + masonry 实现了这一点,但由于一些浏览器已经支持 CSS3 多列,我希望为这些浏览器提供一个纯 CSS 的解决方案,其余的则回退到 Javascript。

这是我一直在尝试的 CSS:

.div-of-boxes {
  -webkit-column-count: 3;
  -webkit-column-gap:   10px;
  -moz-column-count:    3;
  -moz-column-gap:      10px;
  column-count:         3;
  column-gap:           10px;
}

但是,这使得元素的流动是自上而下从左到右。我想要一个左右自上而下的流程。这是我想要的一个例子:

1 2 3
4 5 6
7 8 9

但这就是我得到的:

1 4 7
2 5 8
3 6 9

Flow multi-column elements left-right before top-down 中询问了类似的问题,但我对答案不满意,并且它不适用于不同高度的元素。这对于 CSS 列是否可行,还是有限制?

【问题讨论】:

    标签: css css-multicolumn-layout


    【解决方案1】:

    多列规范不提供更改列之间元素分布的属性:http://www.w3.org/TR/css3-multicol/。这样的属性似乎违背了模块的设计目的(重新创建报纸或杂志文章的布局方式)。

    其他纯 CSS 解决方案都无法让您达到您想要的效果。

    【讨论】:

    • 这就是我所怀疑的......我将保留我的 javascript 实现,如果未启用 javascript,则回退到 CSS-only,用户会看到图片之间存在一些差距,那就是权衡。感谢您的确认!
    【解决方案2】:

    如果您的布局总是 3 列宽,您可以尝试在内部 div 上使用 nth 选择器。
    您可以通过清除第 4 项来做到这一点。

    #container {
        overflow: hidden;
        width: 440px;
    }
    #container div {
        background-color: gray;
        width: 110px;
        margin: 5px;
        float: left;
    }
    #container div:nth-child(4) {
        clear: both;
    }
    <div id="container">
        <div id="widget1">1</div>
        <div id="widget2">2</div>
        <div id="widget3">3</div>
        <div id="widget4">4</div>
        <div id="widget5">5</div>
        <div id="widget6">6</div>
        <div id="widget7">7</div>
        <div id="widget7">8</div>
    </div>

    JS Fiddle

    【讨论】:

    • 如果我正确理解了 OP 的问题(特别是因为他们表示他们想用 CSS 重新创建 Masonry),问题是元素 2 的高度会导致元素 1 和 4 以及 3 和6. 列给出了他们正在寻找的效果,只是顺序错误。
    • @cimmanon 你是对的。我想念这个问题。我会留下它,以防万一它是其他人的可行选择。我会关注未来可能出现的任何答案。
    • 不错的...欣赏它!
    【解决方案3】:

    这里是a link 解决方案!仅使用 flex。

    html

    - var n = 0;
    ul
      while n < 40
        li= n++
      li
    
    

    css

    ul {
        list-style: none;
        padding: 30px;
        background: #28285e;
        
        li {
            padding: 20px;
            margin: 6px;
            background: white;
            width: calc(50% - 52px);
            height: 100px;
            display: inline-block;
            border: {
                radius: 4px
            }
            
            &:nth-child(3n) {
                height: 40px;
            }
            
                
            &:nth-child(2n + 1) {
                height: 80px;
            }
            
            &:nth-child(even) {
                float: right;
            }
            
            &:nth-child(odd) {
                float: left;
            }
            
            &:last-child {
                clear: both;
                float: none;
            }
        }
    }
    

    【讨论】:

    • 欢迎来到 Stack Overflow。 Stack Overflow 上不鼓励仅使用代码的答案,因为它们没有解释它是如何解决问题的。请编辑您的答案以解释此代码的作用以及它如何回答问题,以便对其他有类似问题的用户有用。
    【解决方案4】:

    有一个使用 flexbox:nth-child()order 的纯 CSS 解决方案,如 blog post by Tobias Ahlin 中所述。

    这个想法很简单。 flex-flow: columnwrap 可以做 column-count 所做的事情。你需要两个条件才能让它工作: 1. flexbox 容器需要有一个固定的高度,并且它需要比你的最高列高。 2.flex children需要宽度,2列布局50%,3列布局33%等

    .flex-container {
      display: flex;
      flex-flow: column wrap;
      height: 600px; /* You'll need to play with this value to distribute items correctly */
    }
    
    .flex-child {
      width: 33%; /* Creates 3-column layout */
    }
    

    这种方法与column-count 存在相同的问题:元素按列排序,自上而下。但是由于我们使用的是 flexbox,现在我们可以访问 order 属性。

    使用:nth-child()order 我们可以覆盖默认顺序。

    .flex-child:nth-child(3n+1) { order: 1; }
    .flex-child:nth-child(3n+2) { order: 2; }
    .flex-child:nth-child(3n)   { order: 3; }
    

    带有order: 1 的项目将位于第一列,order: 2 将位于第二列,order: 3 位于第三列。

    (an + b) 公式中,a 表示循环大小,n 是计数器(从 0 开始),b 是偏移值。所以(3n+1)第一个 开始每隔三个选择一次。 (3n+2) 选择每第三个项目,但从 第二个 项目开始。并且(3n) 选择从third 项目开始的每三个项目,因为索引 0 处没有任何内容。

    在某些布局中,列可能会合并。为了解决这个问题,Tobias 在列之间插入了伪元素:

    /* Force new columns */
    .flex-container::before,
    .flex-container::after {
      content: "";
      flex-basis: 100%;
      width: 0;
      order: 2;
    }
    

    我不会在这里解释这是如何工作的,但你可以read more about it here

    这是 Tobias 的 CodePen 用于 3 列布局。如果您使用的列超过三列,请read how to make adjustments here

    【讨论】:

      【解决方案5】:

      您可以使用 jQuery 重新排列列中的项目。如果是 2 列,则为:

      $('.your-columns-container .your-item:nth-child(even)').appendTo('.your-columns-container');
      

      https://jsfiddle.net/hzvp7sgf/

      还有一些更复杂的 3 列:

      $('.your-columns-container .your-item:nth-child(3n - 1)').addClass('container-col2');
      $('.your-columns-container .your-item:nth-child(3n)').addClass('container-col3');
      
      $('.container-col2').appendTo('.your-columns-container').removeClass('container-col2');
      $('.container-col3').appendTo('.your-columns-container').removeClass('container-col3');
      

      https://jsfiddle.net/d4LeLyu5/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-05
        • 1970-01-01
        • 1970-01-01
        • 2015-06-17
        • 1970-01-01
        • 1970-01-01
        • 2012-10-13
        相关资源
        最近更新 更多