CSS3提供了个新属性columns用于多列布局。

兼容性

  • Internet Explorer 10 和 Opera 支持多列属性。

  • Firefox 需要前缀 -moz-。

  • Chrome 和 Safari 需要前缀 -webkit-。

  • Internet Explorer 9 以及更早的版本不支持多列属性。

1. 容器的属性

1.1 column-width

  • 语法:column-width: auto | < length >
  • 定义每一列最小宽度(min-width)。

1.2 column-count

  • 语法:column-count: auto | < integer >
  • 定义列的最理想的数量

1.3 columns

  • 语法:columns: < column-width > || < column-count >
  • 是 column-width 和 column-count 的简写。次序随意。
  1. columns: 120px; /* column-width: 120px; column-count: auto */
  2. columns: auto 120px; /* column-width: 120px; column-count: auto */
  3. columns: 2; /* column-width: auto; column-count: 2 */
  4. columns: 2 auto; /* column-width: auto; column-count: 2 */
  5. columns: auto; /* column-width: auto; column-count: auto */
  6. columns: auto auto; /* column-width: auto; column-count: auto */

1.3 column-gap

  • 语法:column-gap: normal | < length >
  • 定义列之间的水平间距

默认存在一定的间距。

1.4 column-rule

  • column-rule: < column-rule-width > | < column-rule-style > | < column-rule-color >
  • 定义列边框,实际上是一个缩写,还有 column-rule-widthcolumn-rule-stylecolumn-rule-color,形式规则什么的等同于border

它的中心线始终和列间距的中心线一样。换言之,它总处于两列的中间。和 border 类似。如果列边框大于列间距,并不会自动消失。列边框超出列间距的部分就像是沉在文字的下方一样(背景效果)。如果 列边框与列间距 一样时,会出现一定的缝隙(BUG)。

width 取值:

column-rule-width: | thin | medium | thick

  • :用长度值来定义边框的厚度。不允许负值
  • medium:定义默认厚度的边框。
  • thin:定义比默认厚度细的边框。
  • thick:定义比默认厚度粗的边框。

style 取值:

column-rule-style:none | hidden | dotted | dashed | solid | double | groove | ridge | inset | outset

  • none:无轮廓。column-rule-color与column-rule-width将被忽略
  • hidden:隐藏边框。
  • dotted:点状轮廓。
  • dashed:虚线轮廓。
  • solid:实线轮廓
  • double:双线轮廓。两条单线与其间隔的和等于指定的column-rule-width值
  • groove:3D凹槽轮廓。
  • ridge:3D凸槽轮廓。
  • inset:3D凹边轮廓。
  • outset:3D凸边轮廓。

1.5 column-fill

  • 语法:column-fill: auto | balance
  • 定义多列中每一列的高度是否统一

效果不明,不算常用。默认值是balance,表示对每栏进行协调。还可以使用值auto,表示每一栏按顺序填充。

2. 分栏的属性

  • 语法:column-span: none | all
  • 定义一个元素横跨多少列

如果我们常将标题横跨所有列。那么,column-span: all。其默认值是,column-span: none;表示不跨列。

3. column 的特性

3.1 margin 也在空间计算之列

比方说上面4栏的例子,如果我们把文字内容变少,会发现,可能就会这样,Chrome和IE浏览器下都是如此,看上去就好像只有3列显示了:
Column 多列布局 - 图1

实际上并不是只显示了三列,而是因为示意的HTML结构如下:

  1. <div class="box col4">
  2. <p>文字...</p>
  3. </div>

<p>默认上下有1emmargin间距的,于是乎,我们看上去好像是第四栏空缺,实际上被<p>元素的margin-bottom给占据了,如果我们使用下面的CSS重置掉<p>标签的margin值,会发现,如预期的4列显示了:

  1. .box p {
  2. margin: 0;
  3. }

Column 多列布局 - 图2

前面是 margin-bottom 影响最后一栏。

同时,第一栏元素设置了 margin-top,会导致第一栏下沉,而其他栏不会出现这种情况

3.2 column 布局高度也是重要限制

上面几个 column-count 示意都是定了个宽度 600px,高度是默认的 auto,因此,分栏的表现都很乖巧,反正高度是无限的,无论你设置多少栏,我都可以通过调整高度来实现。

但是,如果我们高度也设定了固定的值,例如高度 60px,则此时很多有意思的事情就会发生了。

如果说仅仅只是指定了column-count,至少在容器元素的可视尺寸范围内,还是设定的分栏数目,例如 column-count:3,虽然视觉上远不止 3 栏,但是容器可视尺寸范围就是 3 栏,如下截图示意:

Column 多列布局 - 图3

3.4 column-width 会让 column-count 打酱油

这是什么意思呢?比方说下面的CSS:

  1. .col4 {
  2. width: 600px;
  3. column-count: 4;
  4. column-width: 200px;
  5. }

显然这里有矛盾之处,每栏宽度 200px,总共要 4 栏,就算不考虑每栏之间的间隙,也至少需要 800px 的宽度,但是,我们容器设定的宽度只有 600px,怎么办呢?

那即是 column-count 忽略无效打酱油,不要觉得不合理,也不要抱不平说为什么牺牲的是 column-count,而不是其他属性?那是因为 column-count 天生注定就是要牺牲的命,因为其语义解释就是“最理想的分栏数目”,所谓最理想,就是你该牺牲的时候就要牺牲。

实际上这里最终的每栏每列宽度表现并不是 200px,如果我没算错的话,在没有样式重置的情况下,应该是 292px

3.5 高宽同时限制可以实现完美分页

如下CSS代码:

  1. .example {
  2. height: 120px;
  3. width: 100px;
  4. column-width: 100px;
  5. }

如果我们把100px*120px的这个名为.example的小容器看成是一页内容的话,则此时,我们容器中的所有内容,就被完美的分成了一页一页水平呈现的内容,如下截图:

Column 多列布局 - 图4

这里就是我们书籍水平滑动浏览的关键所在,此时,如果我们给父元素有个如下的 overflow 限制:

  1. .father {
  2. width: 100px;
  3. overflow: hidden;
  4. }

此时就形成了一个永远只会显示一页宽度的视窗,然后下面的事情就简单了,我们通过JS touch 相关的事件,控制我们的 .example 元素 translateX 位移,就可以实现一开始展示的水平滑屏浏览小说内容的效果了。

4. 实践

4.1 等分布局

  1. <div class="parent">
  2. <div class="column">
  3. <p>1</p>
  4. </div>
  5. <div class="column">
  6. <p>2</p>
  7. </div>
  8. <div class="column">
  9. <p>3</p>
  10. </div>
  11. <div class="column">
  12. <p>4</p>
  13. </div>
  14. </div>
  1. .parent {
  2. columns: 4;
  3. column-gap: 20px;
  4. }
  5. .column {
  6. background: red;
  7. }
  8. p {
  9. margin: 0; /* 去除 margin 的影响 */
  10. }

4.2 瀑布流

  • 垂直间距使用 margin-top,除了第一个元素外
  1. <ul class="parent">
  2. <li class="column">
  3. <img src="" alt="">
  4. </li>
  5. //...
  6. </ul>
  1. .parent {
  2. columns: 3;
  3. column-gap: 20px;
  4. column-rule: 2px solid #000;
  5. }
  6. .column + .column {
  7. margin-top: 10px;
  8. }
  9. img{
  10. width: 100%;
  11. }

5. 参考