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 的简写。次序随意。
columns: 120px; /* column-width: 120px; column-count: auto */columns: auto 120px; /* column-width: 120px; column-count: auto */columns: 2; /* column-width: auto; column-count: 2 */columns: 2 auto; /* column-width: auto; column-count: 2 */columns: auto; /* column-width: auto; column-count: auto */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-width,column-rule-style,column-rule-color,形式规则什么的等同于border
它的中心线始终和列间距的中心线一样。换言之,它总处于两列的中间。和 border 类似。如果列边框大于列间距,并不会自动消失。列边框超出列间距的部分就像是沉在文字的下方一样(背景效果)。如果 列边框与列间距 一样时,会出现一定的缝隙(BUG)。
width 取值:
column-rule-width:
:用长度值来定义边框的厚度。不允许负值 - 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列显示了:
实际上并不是只显示了三列,而是因为示意的HTML结构如下:
<div class="box col4"><p>文字...</p></div>
<p>默认上下有1em的margin间距的,于是乎,我们看上去好像是第四栏空缺,实际上被<p>元素的margin-bottom给占据了,如果我们使用下面的CSS重置掉<p>标签的margin值,会发现,如预期的4列显示了:
.box p {margin: 0;}

前面是 margin-bottom 影响最后一栏。
同时,第一栏元素设置了 margin-top,会导致第一栏下沉,而其他栏不会出现这种情况
3.2 column 布局高度也是重要限制
上面几个 column-count 示意都是定了个宽度 600px,高度是默认的 auto,因此,分栏的表现都很乖巧,反正高度是无限的,无论你设置多少栏,我都可以通过调整高度来实现。
但是,如果我们高度也设定了固定的值,例如高度 60px,则此时很多有意思的事情就会发生了。
如果说仅仅只是指定了column-count,至少在容器元素的可视尺寸范围内,还是设定的分栏数目,例如 column-count:3,虽然视觉上远不止 3 栏,但是容器可视尺寸范围就是 3 栏,如下截图示意:

3.4 column-width 会让 column-count 打酱油
这是什么意思呢?比方说下面的CSS:
.col4 {width: 600px;column-count: 4;column-width: 200px;}
显然这里有矛盾之处,每栏宽度 200px,总共要 4 栏,就算不考虑每栏之间的间隙,也至少需要 800px 的宽度,但是,我们容器设定的宽度只有 600px,怎么办呢?
那即是 column-count 忽略无效打酱油,不要觉得不合理,也不要抱不平说为什么牺牲的是 column-count,而不是其他属性?那是因为 column-count 天生注定就是要牺牲的命,因为其语义解释就是“最理想的分栏数目”,所谓最理想,就是你该牺牲的时候就要牺牲。
实际上这里最终的每栏每列宽度表现并不是 200px,如果我没算错的话,在没有样式重置的情况下,应该是 292px。
3.5 高宽同时限制可以实现完美分页
如下CSS代码:
.example {height: 120px;width: 100px;column-width: 100px;}
如果我们把100px*120px的这个名为.example的小容器看成是一页内容的话,则此时,我们容器中的所有内容,就被完美的分成了一页一页水平呈现的内容,如下截图:

这里就是我们书籍水平滑动浏览的关键所在,此时,如果我们给父元素有个如下的 overflow 限制:
.father {width: 100px;overflow: hidden;}
此时就形成了一个永远只会显示一页宽度的视窗,然后下面的事情就简单了,我们通过JS touch 相关的事件,控制我们的 .example 元素 translateX 位移,就可以实现一开始展示的水平滑屏浏览小说内容的效果了。
4. 实践
4.1 等分布局
<div class="parent"><div class="column"><p>1</p></div><div class="column"><p>2</p></div><div class="column"><p>3</p></div><div class="column"><p>4</p></div></div>
.parent {columns: 4;column-gap: 20px;}.column {background: red;}p {margin: 0; /* 去除 margin 的影响 */}
4.2 瀑布流
- 垂直间距使用 margin-top,除了第一个元素外
<ul class="parent"><li class="column"><img src="" alt=""></li>//...</ul>
.parent {columns: 3;column-gap: 20px;column-rule: 2px solid #000;}.column + .column {margin-top: 10px;}img{width: 100%;}
