具有左右流的CSS列

时间:2013-02-17 19:31:08

标签: css css3 css-multicolumn-layout

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

我目前使用同位素+砌体实现了这一目标,但由于某些浏览器已经支持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列来说是否可行,或者它是一个限制?

5 个答案:

答案 0 :(得分:20)

多列规范没有提供更改列之间元素分布的属性:http://www.w3.org/TR/css3-multicol/。这样的财产似乎与该模块的设计背道而驰(重新创建报纸或杂志文章的布局)。

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

答案 1 :(得分:5)

如果您的布局总是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

答案 2 :(得分:0)

这里是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;
        }
    }
}

答案 3 :(得分:0)

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

这个想法很简单。 flex-flow: columnwrap 可以准确地完成 column-count 所做的事情。你需要两个条件才能让它工作: 1. flexbox 容器需要有一个固定的高度,它需要比你最高的列高。 2. flex子项需要宽度,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)first 开始选择每第三个项目。 (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 为 3 列布局编写的 CodePen。如果您处理的列数超过三列,请read how to make adjustments here

答案 4 :(得分:-1)

您可以使用jQuery重新排列列中的项目。在2个cols的情况下,它将是:

$('.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/