CSS3之美(六):多列

CSS3 原生支持多列布局,这不得不说是一大亮点,尽管现在浏览器还存在兼容性问题。

分列布局方法

指定分列:column-count

属性 column-count 可以用于把内容划分为均等分布的几列,其语法如下:

1
E { column-count: columns; }

其中,E 为要划分的内容的父元素,columns 为一个整数,用于设置分列的数量。

动态分列:column-width

属性 column-width 用于设定分列后的每列的宽度,其语法如下:

1
E { column-width: length; }

其中,length 用于设置分列后的每一列的宽度,其值可以是长度单位或者百分比值。

更好地可读性

在使用多列布局时,要注意外边距 marginpadding 仍然会应用到内容上,所以可能导致在分列的顶部或底部的段落和非固定文本行之间出现不必要的空行,二者都会影响到可读性。

为了在每个段落开始的时候缩进,段落之间不要留下边距。我们可以使用以下方式辅助多列布局:

1
2
3
4
5
.columns p {
margin-bottom: 0;
text-indent: 1em;
text-align: justify;
}

Firefox和Webkit中不同的分配方式

文本在各个浏览器中被划分到各列之中会有所不同。Firefox 的方法是让大多数的列有相同数量的行,最后一列比其他部分稍长或稍短一些。与此相反,Webkit会让所有列的高度尽可能均等。

之所以会出现这种情况,是因为以前的规范版本(从2001年到2005年)从来没有明确过排印材料应该如何在各分列之间进行平衡,所以浏览器厂商就会提出自己的解决方案。W3C 在后来的规范版本中通过使用 column-fill 属性解决了这个问题:

1
E { column-fill: value; }

其中,column-fill 的属性值取值如下:

  • auto: 各列高度自适应,像 Firefox 那样
  • balance: 默认值,所有列的高度以其中最高的一列统一,像 Webkit 那样

column-count和column-width的结合

我们可以在同一个元素上同时设置 column-countcolumn-width 属性,但是这样会有些冲突:如果两个属性应用到同一个元素上,并且将 column-count 属性写在前面的话,那么 column-count 值的作用就像是设置了最大值。

1
2
3
4
.columns {
column-count: 5;
column-width: 100px;
}

这段代码本质上的逻辑是:把文本划分为 100px 的列,如果会产生 5 个或 5 个以上的列,就生成有 5 个最小的宽度是 100px 的列。然而,Webkit 错误地实现了这一规则,它创建了 5 个 100px 的列,留下毫无意义的白色空间。

如果要同时使用这两个属性,我们可以像下面这样使用简写属性 columns

1
E { columns: column-width column-count; }

列间隔与分界线

在使用动态布局的时候,浏览器应该会在每一列之间放入默认的 1em 的间隔(在使用动态布局的时候,1em是最小的宽度)。不过,我们可以使用两个新的属性 column-gapcolumn-rule 去修改默认的值并指定自己的间隔距离。

  • column-gap: 用于设置各个列之间的缝隙空间,语法如下:
1
E { column-gap: length; }

其中,length 值可以是带有标准 CSS 长度单位的任何数字。

  • column-rule: 使用这个属性相当于画了一条线,类似于一条边界,等距离地位于各列之间。column-rule 实际上是以下三个独立属性的简写形式:

    • column-rule-width
    • column-rule-style
    • column-rule-color

这三个属性使用的值与 CSS2 中 border-* 属性是一样的。其语法如下:

1
2
3
4
5
6
7
8
E {
column-rule-width: length;
column-rule-style: border-style;
column-rule-color: color;
/* 简写方式 */
column-rule: length border-style color;
}

跨越多列的元素

为了处理那些需要横跨不止一列进行显示的元素,模块引入了 column-span 属性,它的语法是:

1
E { column-span: value; }

在这里,value 只能是以下两个可能值之一:

  • 1: 默认值,让元素保持在分列流中
  • all: 将在流中出现中断——所有在元素(E)之前的内容将会分配在各列当中,所有在元素之后的内容也会被分配到各列之中,但元素本身则不会。

打破多列的元素

对于其他的非文本元素,比如子标题或者列表,它们不应该出现在各列之中被拆分,这些又该如何处理呢?一列结束而下一列开始的点被称为断行,我们可以使用 break-after break-before break-inside 属性来处理断行产生新列的方式。

1
2
3
4
5
6
7
8
E { break-after: keyword; }
/* 设置元素之前的断行方式 */
E { break-before: keyword; }
/* 设置元素之后的断行方式 */
E { break-inside: keyword; }
/* 设置元素内部的断行方式 */

上面每个属性都接受一系列的关键字值,三个属性全部都接受 autoavoid 值,而 break-afterbreak-before 属性允许使用额外的值 columnalwaysalways 值可以保证总是断行并产生新列。 avoid 值可以保证没有中断紧挨在指定元素之前或之后发生(不论应用了哪个属性),而 column 值的作用则是相反的,它强制中断发生在元素之后或之前。所有这些属性的默认值都是 auto,它既不强制也不禁止中断的发生,让浏览器去决定中断是否应该发生在元素之前、之后或内部。

这些属性可以被应用到不突破一列的元素上,它们会命令浏览器在列的哪个地方应用中断。