【前瞻】CSS布局的未来

【本文系外部转载,原文地址: http://www.netmagazine.com/features/future-css-layouts
 

原文地址:http://www.netmagazine.com/features/future-css-layouts
对比起那么多精妙的特性,CSS竟然在最基本的布局上做得如此令人不悦。但是,一些更丰富的、更具活力的页面布局方案正在来临。——Peter Gasston 如是说。

经过多年的允诺,CSS3终于降临了并改变我们的页面风格。它给我们前端的工具箱增加了一系列的新成员,赋予了我们圆角、渐变、透明度、变形、过渡、动画以及更多更多的选择。但是,当我们有了这些有趣的工具,养眼的效果,下一步呢?

CSS3该关注的下一个问题将会是布局。直至现在,我们都凭着浮动、相对定位以及负边距的小把戏勉强混过来。但是,除了做规规矩矩的二到三栏布局外,我们仍然会感觉很困难去再做出其他的布局。

W3C和浏览器提供商们都知道这个问题,并且正在做出一系列的解决方案。他们中领头的是IE团队(你一定会很惊讶),IE10看上去正预示着开启一个全新的CSS布局的时代,让那些之前我们不能触及的丰富的、充满活力的、引人注目的网站变得可能。

在这篇文章里我将会带你们看看现今正在不同发展程度里的布局方案,从已经能良好实现的到纯理论的。或许其中不是所有的这些方案都能在未来应用于实践,但是,我们还是值得去看看这些未来的展望。如果你想去知道更多关于这些方案的细节,以及CSS3所带来的更多工具,我诚挚地向你推荐我的书,The Book of CSS3

列布局Columns

把内容划分成多列是一种很基本的印刷手法,现在,CSS多列布局把这种在印刷中的灵活布局也带到了网页上。我们有两种方式去进行列布局,两种方式会用到针对父元素的不同属性。

第一种方式是指定列的数目。以下的代码会在父元素下生成3个等宽的列并一同填充父元素的宽度。
div { column-count: 3; }

第二种方式是指定列的宽度,列将会是指定值并且这个宽度的单位列将会重复扩展直到匹配父元素的宽度。在这个例子里我回设置列的宽度为140px,所以在一个700px宽的父元素里会产生5列。
div { column-width: 140px; }

默认下在每一列之间都会有1em的间隙,但是你可以通过设置column-gap的长度值去改变它。同样你也可以通过设置column-rule的值去在列与列之间设置边界,设置它的方法与设置border的方法一样。下面这段代码将会生成2px宽的点状分界线,并且把间隔设为28px——它将会被均等划分于边界的两侧:
div {
column-gap: 28px;
column-rule: 2px dotted #ccc;
}

如果你想要看看结果,请打开这个例子,你需要使用Firefox,Chrome,Safari,Opera11.1,或者IE10 Platform Preview (‘IE10PP’) 去查看,如果你没有这些浏览器,请参考以下图片:

其实我们使用列布局还可以做出更多的事,但是我们位置有限。如果你想要看这种布局的实际例子,看看维基百科里的”参考部分”,它就是使用了column-count属性去把文段分为了三列。多列布局可以通过加上-moz-前缀使在Firefox中生效,Chrome和Safari需加上-webkit-前缀,而对于Opera11.1+和IE10PP 不必加前缀。

灵活的盒子模型Flexible box

灵活的盒子布局模型提供了一种可以免于计算宽高、自动在父元素内调整自身尺寸的方法。我们来做一个简单的例子,假设你有两个子元素,并且你想要去让它们等宽并且充满父元素(父元素宽度可变),你可以通过设置百分比去实现,但是当边框、内边距、外边距存在时就会变得很复杂。但是灵活盒模型可以很简单地解决这个问题
.parent { display: box; }
.child-one, .child-two { box-flex: 1; }

这段代码把两个子元素水平地放置在它们的父元素中,并且它们都有一样的宽度。box-flex属性实际上就扮演着比例的角色,取得父元素可用的宽度并且在子元素中重新根据box-flex的比例值进行重新分配,为了说明我的意思,我们看看下面的代码:
.child-one { box-flex: 1; }
.child-two { box-flex: 2; }

当两个子元素在其父元素内得到空间的分配时,child-two的宽度会和child-one的宽度呈2:1的比例增长,每当child-one扩大1个像素,child-two就会扩大2个。所以,如果它们的父元素是260px,而设置每个子元素为100px,那么就会剩下60px由该模型分配,于是child-two就会得到其中的40px而child-one会得到其中的20px。

给出再多的描述也比不上一个例子,所以你可以在这个CSS灵活盒模型的例子中看得更清楚(你需要Firefox,Chrome,Safari,或者IE10PP)。尝试去改变窗口的宽度去看看它尺寸的改变。
在可以动态改变一个元素的尺寸的同时,灵活盒模型同样可以对父元素设置属性去控制把空白的位置分配在哪里,设置子元素的位置。box-align属性是作用于子元素的水平位置,而box-pack则作用于子元素的垂直位置。我们看看它是如何工作的:
.parent {
box-align: center;
box-pack: center;
display: box;
height: 200px; width: 200px;
}
.child {
box-flex: 0;
height: 100px; width: 100px;
}

类名为child的元素的box-flex的值被设为0,于是它不会自动动态地调整尺寸,并且,它的宽度和高度都是父元素的一半,而父元素的box-align以及box-pack属性都被设为了“center”,所以该子元素将在父元素中水平并垂直居中。

你可以在这里读到更详细阐述灵活盒模型的文章。现在,你可以通过加入对应的前缀(-moz,-webkit,和-ms-)来让Firefox,Chrome,Safari,和IE10PP实现这种布局。你也可以在这里进行测试。注意它的语法可能在不断改变,在W3C Flexible Box规范草案可以获得更多的细节。

网格布局Grid

IE10PP带来了让人兴奋的网格布局。要使用它的第一步是要你用行与列去定义你的网格。你可以使用长度值,auto关键字,以及一个新的长度单位–fr,它表示的是片段、部分的意思。我们来看看例子:
div {
display: grid;
grid-columns: 1fr 3fr 1fr;
grid-rows: 100px auto 12em;
}

这段代码会生成一个3行3列网格,而其中中间列的宽度为左右列宽度的3倍,而第一行的高度为100px,最后一行的高度是12em,中间行的高度根据内容的多少而变化。
现在我们已经做好了我们的网格,我们可以把内容定位到它上面,使用HTML5的标签我们可以做出一个非常简单的常见页面布局:
header { grid-column: 1; grid-column-span: 3; grid-row: 1; }
nav { grid-column: 1; grid-row: 2; }
article { grid-column: 2; grid-row: 2; }
aside { grid-column: 3; grid-row: 2; }
footer { grid-column: 1; grid-column-span: 3; grid-row: 3; }

根据代码你能看见我使用grid-columngrid-row属性把不同的元素分别放置在网格中。例如article元素,我把它放置在第二行第二列——即是在我3*3网格的中心位置。而我也对headerfooter元素设置column-span,让它们跨越3列放置。(对于row-span也是同样道理,但我这里没有用到)
我使用这些元素做出了一个演示例子,你可以在这个CSS网格布局实例中看见效果,但是你得用IE10 Platform Preview(IE10PP)去看,如果你没有IE10PP,你可以在下面这幅截图看一下它的效果:

一个纯CSS网格布局属性控制的标准的3列布局
上述的属性都在IE10PP中得到实现,所以你可以现在就去尝试一下。事实上在规范中还有更多的属性尚未得到实现,所以我们可以继续期待它的发展。

基于模板布局Template

另一种可以得到网格布局效果的方法是使用模板布局。这种布局方式使用了一些稍微有些不同的语法,第一步是用顺序的英文字母设置position属性,分配position值。
header { position: a; }
nav { position: b; }
article { position: c; }

当我们分配好position值后,我们可以使用字母串的组合去做出布局。每一个字符串代表一行,而其中的每个字母代表一列。例如,要做出一个一行三列的布局,你可以这样做:
div { display: 'abc'; }

这段代码可以在一行里显示3个元素,并且平均分配空间。但你也可以通过重复某个字母去让它跨越多个列,而在不同的字符串中的同一个位置使用同一个字母可以让它跨越多行。在下面得例子中,nav元素跨越了2行,而headerarticle跨越了两列:
div {
display:
'baa'
'bcc';
}

这种模板布局现时尚未在任何浏览器上得到实现,但是Alexis Deveria所做出的一个很强大的JQuery插件可以让你试验一下这种布局。我在这个使用CSS模板布局的例子里使用到了这个插件。它看上去和我刚刚使用网格布局的例子完全一样,但是实现的代码却完全不同。
这个例子使用了JavaScript去实现,所以它在现时流行的浏览器中都可以实现,但是如果你看不见效果的话,你可以看看在我讲述网格布局部分的那张图片——它们看起来完全一模一样!并且,记得我说过网格布局还将有更多的属性待实现吗?在其中也包含有一些采纳了模板布局的语法的属性,像下面的这个例子:
header { grid-cell: a; }
article { grid-cell: b; }
div {
display: grid;
grid-template: 'a' 'b';
}

这些其实和使用模板布局的属性实现方式都一样,而它们同样都尚未得到实现(当然,它们可能永远都得不到实现)

被定位的浮动Positioned floats

现今的浮动属性让我们可以把文本浮在一个元素的左侧或者右侧,但是IE10PP所赋予我们的一个扩展属性让我们向前迈进了一步,现在我们可以把一个浮动元素定为到任何一个未知,而它附近的其他内容会始终在它周围浮动。实现它所需要的只是float属性的一个新的值,以及一些用于定位的属性:
div {
float: positioned;
left: 200px; position: absolute; top: 100px; width: 250px;
}

这段代码会生成一个250px宽的元素,距离父元素左边距200px、上边距100px。在默认情况下,在父元素内任何其它的内容都会浮动在这个定位元素的四周,但是,你可以通过改变wrap-type属性去改变这种现象,例如可以这样设置去让文字仅仅浮动与元素的上方和下方:
div { wrap-type: top-bottom; }

你也可以把定位浮动以及网格布局结合在一起,把一个元素定位在网格里,然后让其它内容包围在四周
div {
float: positioned;
grid-column: 2;
grid-row: 2;
}

定位浮动在IE10PP里已经得到实现,所以你可以现在就试一试,如果你有IE10PP的话你可以在这里看见例子,如果没有的话你可以预览一下以下的图片:

W3C浮动与定位说明文档中已经发展到超越了我这里所说的内容,它们阐述了更多的属性,包括可定形的浮动之类,但这些都尚未得到实现。

环绕Exclusion

现时定位浮动让你可以使内容包围在一个盒状元素的四周,但是在W3C文档中同样提到了可定形的浮动。这个想法来自于Adobe的CSS Exclusions模块,这个模块有两个核心属性:第一个是wrap-shape,它允许你去生成椭圆形、长方形以及多边形,而它将会指引内容流的布局;例如:
div { wrap-shape: circle(50%, 50%, 100px); }

这样的代码会生成一个半径为100px的圆形,圆心与父元素的中心重合,同样,你可以使用polygon()去定义你所想要的任何形状,使用用空格隔开的坐标定位,例如这个三角形:
div { wrap-shape: polygon(0,100px 100px,100px 50px,0); }

当你做出你想要的形状后,你可以使用wrap-shape-mode属性去让同一父元素内的其他行内元素浮动于它的周围,像这样:
div {
wrap-shape: circle(50%, 50%, 100px);
wrap-shape-mode: around;
}

如果把wrap-shape-mode设为content,内容流将被置于圆形内。

你可以在adobe实验室下载css exclusion的原型样本(点击我),这个文件包含了详细的文档以及一些很好的例子。
包括如下效果的一个实现:

多区域分布内容流Regions

Adobe同样提出了另一种先行布局方案,CSS Regions,它提供了一种方式可以让内容流分布在几个不同的元素里。要实现这个效果,需要首先通过flow属性定义内容会放置在哪个元素里,然后通过content属性使用from()方法设置内容流将在哪些区域中流动。
.content { flow: foo; }
.target1, .target2 { content: from(foo); }

实现起来很简单,这些代码把.content元素里的文字取出,然后首先放在.target1中,如果内容溢出,那么将放在.target2中。我们要清楚的事,它不会在两个target中重复显示同样的内容,内容事实上从第一个target开始,然后溢出时继续在target2中显示:

值得一提的是,两个target(目标容器)在DOM中或布局中不一定相邻,你可以把它放在页面的两侧。
Region和Exclusion模块尚未在任何浏览器得到实现,但你可以在adobe实验室下载原型并尝试一下它。

总结。

除了FlexBox(灵活盒子模型)和Columns(列布局)之外,我们始终很难确定哪种新式布局可以跨什么浏览器工作。我个人觉得Positioned Floats和Exclusions是很相似的而已可以很容易地被合在一起。而Grid布局会包含Template布局将会在IE10里实现。Region布局在Webkit的一些前沿产品里已经得到实现,所以在以webkit为内核的浏览器中应该也将会得到支持。
所以我会预测随着这些变化,你们将会看见这些新技术将会随着CSS3来到现实中。如果真是这样的话,我相信会是个好现象,这些新技术是互补而不是互斥的,而我们可以在未来几年内使用它们通过少量的工作量就可以构造去很多布局巧妙的网站。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值