Css 布局的未来

http://www.xxb.me/2011/08/css_layout/

By Peter Gasston on August 03, 2011

看原文,点这里

相对于其它精彩特性来说,CSS中最基本的页面布局功能显得很弱。但是更丰富更具有活力的页面时代即将到来……peter Gasston如是说。

在多年的许诺之后,css3终于快要即将来到我们的面前(你懂的)。她增加了一系列新的工具到我们的前端工具箱,例如圆角、渐变、半透明、变形、动画等等。但是我们有了这些好玩的华而不实的东东之后呢?

Css3需要解决的下一个问题是布局。现在,我们可以使用浮动,相对位置,和负边距的技巧来布局。但是面对任何超过规则的两到三列布局的时候,我们工作起来相当费力。

W3C和浏览器生产商们对这个问题已经有所察觉,并且致力于解决这个问题。他们当中的带头大哥就是IE团队(你是不是跟肖峰一样吃惊……)。IE10貌似预示着一个令人兴奋的css布局新时代。在那个世界里,比现在更加丰富的,灵活的,耀眼的页面布局,将成为可能。

在这篇文章中我们将会看到处于开发各个阶段的各种各样的布局方法。有些已经得到实施,有些还处于概念阶段。也许并不是所有的方法都能为我所用(至少 不是以现在的形态),但是至少可以看到未来的雏形。如果你想了解更多文中相关细节,以及更多css3的新功能,我推荐一下我的新书,the book of css3.

columns

内容的分栏呈现,在传统印刷中很常见,css分栏模块把这种灵活性带进web中。有两个不同的属性可以生成分栏效果。第一种是相对静态的,适用于当你明确知道需要把文字分为固定栏目数时使用。下面这段代码会生成三个相等宽度的栏,填满她的父级元素。

div { column-count: 3; }

第二种方式相对灵活,栏目的宽度是固定的,但是栏目的数量会随着父级元素宽度的改变而改变。栏目会自动重复,填满父级元素。下面的例子中我们设定一个宽为140px的栏,这样一个800宽的父级元素应该有五个栏目。

div { column-width: 140px; }

各个栏之间默认有1em的间隙,你可以通过column-gap属性来改变这个值。你也可以通过column-rule属性在各栏之间设置分隔线。下列代码会生成中间2px的点线,两边各14px的间隔:

div {

column-gap: 28px;

column-rule: 2px dotted #ccc;

}

如果你想看看最终效果,去demo页。前提是使用ff,chrome,safari,opaera11.1或者IE10才能正确显示。如果你没有安装这些浏览器,没有关系,下面有效果截图:

Css 布局的未来

columns布局效果

利用分栏你还可以做很多效果,不在这里一一展示,如果你想看一个真实的案例,看看demo,页面中使用分栏把注解分为三列。使用分栏的时候需要在ff中添加-moz-前缀,在chrome和safari中使用-webkit-前缀,opara11.1+和IE10不需要前缀。

flexible box

弹性盒子布局模块(FlexBox)提供了识别和生成父级中的子元素,而不需要制定高度和宽度值的方法。例如,你需要有两个充满其父级元素(父元素 宽度不固定)的子元素,并且两个子元素是等宽的,你可以通过百分比值的形式达到效果,但是如果同时存在边界,内边距和外边距,问题就会变得复杂。使用 FlexBox解决这个问题就很简单:

.parent { display: box; }

.child-one, .child-two { box-flex: 1; }

她会将两个子元素水平排列在父级元素中,同时保证宽度相同。这个box-flex属性有点像比例,取得父级元素的内部空间,然后按照属性值重新分配给每个子元素。看看下面这个例子,你们就会明白我的意思了:

.child-one { box-flex: 1; }

.child-two { box-flex: 2; }

当这两个元素开始在他们父级元素中分配空间时,子元素2会在子元素1增加1px同时增加2px。因此如果父级元素有260px宽,而且每个子元素的宽为100px,剩下的60px会分配40给子元素2,20px给子元素1。

demo才是王道,请看demo(需要浏览器支持),试试改变窗口大小,元素的宽度是如何变化的?

FlexBox不但能够动态改变元素大小,同时她还提供属性给父级元素确定从什么地方开始分配空间,通过这种方式设定子元素的位置。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;

}

子元素的box-flex值为0,这样它不会动态改变尺寸,她的高和宽都是父元素的一半。因为父级元素的的box-align和box-pack属性都是center,因此这个子元素会定位在中心位置。

有图有真相:

Css 布局的未来

flexBox布局效果

你可以在另一篇文章中了解到更多关于FlexBox的内容。她可以通过添加适当的前缀在ff,chrome,safari和IE中实现,你可以利用http://flexiejs.com/进行一些有趣的实验,模型发展方面的细节,可以查看http://www.w3.org/TR/css3-flexbox/

grid

全新的IE10中的网格布局系统是我最期待的(http://dev.w3.org/csswg/css3-grid-align/)。首先你需要定义你的网格的行和列。你可以传统长度值、auto或者新的长度单位fr(fraction的缩写)来定义。看看下面的代码:

div {

display: grid;

grid-columns: 1fr 3fr 1fr;

grid-rows: 100px auto 12em;

}

他会创建一个三行三列的网格,中间一列的宽度是左右宽度的三倍,第一行高100、第三行高是12em、中间的行高是自适应的。

有了网格以后,我们就可以通过她来定位内容。我用html5元素创建了下面一个简单页面:

1. header { grid-column: 1; grid-column-span: 3; grid-row: 1; }

2. nav { grid-column: 1; grid-row: 2; }

3. article { grid-column: 2; grid-row: 2; }

4. aside { grid-column: 3; grid-row: 2; }

5. footer { grid-column: 1; grid-column-span: 3; grid-row: 3; }

你可以发现哦我是通过grid-column和grid-row两个属性来放置元素的,我将article元素定位在了第二行的第二列—正好处于我 3行3列布局的中心。我还使用了column-span属性使得header和footer横跨3列。(从这里看有点像row-span属性)

你可以查看demo效果,但是只能使用IE10浏览器哦……(如果看到这里你还没去试试IE10,那……你就看下面的截图吧)

Css 布局的未来

grid布局效果

上面提到的属性IE10都支持,所以你现在就可以去体验她们,规范中还有更多属性即将被支持,让我们翘首以盼用IE的都不是笨蛋的那一天吧……

Template

另一种接近网格系统的东东是样板布局模块 Template Layout module。该模块使用不同的语法规则,首先以字母形式给position指定值。

1. header { position: a; }

2. nav { position: b; }

3. article { position: c; }

一旦指定了position值,我们可以使用字符串来布局,每个字符串代表一行,每个字符代表一列。例如,使用下面代码创建一行三列效果:

div { display: ‘abc’; }

这样的话三个元素会被排列在一行,平均的分配宽度。你也可以重复字符来横跨多列,用不同字符串的相同位置是使用相同字母来跨越多行。在下面的例子中,nav元素跨越两行,header和article跨越两列(我已经重排代码来让大家看得更清楚):

1. div {

2. display:

3. ‘baa’

4. ‘bcc’;

5. }

暂时还没有任何浏览器支持样板布局,但是Alexis Deveria的jQuery可以让你尽兴。这里我用她写了一个demo,样子虽然长得更网格布局一样,但是背后的代码不同。

这个demo使用js所以应该在多数现代浏览器中正确显示,如果你看到正确效果,那么请抬头,看看上面的网格布局中的截图,他们真的看起来一模一样。还记得我说的网格布局中会有更多属性吗?其中就有来自于样板模块的属性,看下面的例子:

1. header { grid-cell: a; }

2. article { grid-cell: b; }

3. div {

4. display: grid;

5. grid-template: ‘a’ ‘b’;

6. }

这个在功能上和样板布局属性一致,同样也没有被支持(很有可能,永远也不会)。

Positioned floats

现有的浮动属性可以围绕一个元素浮动一段文字,IE10的一个扩展属性,让我们前进了一大步,我们可以定位浮动元素到任何一个你喜欢的地方,其它兄妹元素会自动包围她。以上这些需要float的一个新值,和一些定位属性:

1. div {

2. float: positioned;

3. left: 200px; position: absolute; top: 100px; width: 250px;

4. }

上面的代码会穿件一个宽250px的元素,将它定位在距离父元素顶部100px,左边200px的地方。默认情况下周围所有同级元素都会围绕这个定位元素排布,但是你可以通过wrap-type属性来改变这一点,例如你想让上面和下面的元素围绕她流动:

div { wrap-type: top-bottom; }

你还可以结合使用定位浮动和网格布局模型,通过网格指定元素的位置,使其它元素围绕她排列:

1. div {

2. float: positioned;

3. grid-column: 2;

4. grid-row: 2;

5. }

IE10能很好支持定位浮动,所以你现在就可以开始去尝试,如果你已经能够安装IE10,你可以查看这个demo。如果没装,那么请看下面的截图,这使用现在的技术不可能实现的。

Css 布局的未来

position float布局效果

浮动和定位规范实际上有点离题了,还有很多属性,包括shaped floats,或者说是浮动产生图片遮罩,都没有被浏览器支持,但还是让我们先看看下面一节。

Exclusions

定位浮动允许内容围绕一个盒子的形状的元素排列,为什么不能围绕其它形状的浮动,这个想法来自于adobe的cssExclusion模块草案。在这个模块里面有两个重要属性:第一个是wrap-shape,允许你去创建一个决定内容包围方式的椭圆、方形或多边形。

div { wrap-shape: circle(50%, 50%, 100px); }

这段代码将会创建一个半径为100px的圆,该圆处于父元素的中心位置。可以通过ploygon()函数来创建任何你喜欢的形状,如下的三角形:

div { wrap-shape: polygon(0,100px 100px,100px 50px,0); }

当你定义好形状之后,你就可以使用第二个属性wrap-shape-mode让同级的内联元素沿该形状排列:

1. div {

2. wrap-shape: circle(50%, 50%, 100px);

3. wrap-shape-mode: around;

4. }

你可以下载http://labs.adobe.com/downloads/cssregions.html来运转css Exclusion。里面包含全部的文档和一些非常有趣的demo文件,下面的图片就是其中的一个:

Css 布局的未来

exclusion布局效果

如前所诉,Exclusion被建议包含到浮动模块中,所以很有可能作为一个子集被支持,而不是它本身。

Regions

另一个adobe的提议:css Regions,提供在多个不同元素中排布内容的方法。首先需要为内容容器声明一个flow属性独一无二的字符值,然后通过from()函数和内容的属性确定内容将会在哪些元素内排布:

1. .content { flow: foo; }

2. .target1, .target2 { content: from(foo); }

首先将内容容器中的内容放置到第一个元素target1中,如果有溢出,就将溢出的部分放在target2中显示。说得更明白一点,她不是在另一个target中重复内容,而是继续在第二个target中显示1中没有完全显示的内容。请看下面的例子:

Css 布局的未来

region布局效果

随便说一下,两个目标区域不需要在DOM或者布局中相邻,如果需要的话,她们完全可以是同一个页面的两个毫不相干的人或者仇人(但是这样的话会带来可及性问题)。

Regions和Exclusions一样还不被任何浏览器支持,但是你可以从adobe的实验室中下载它,亲自试一试。

小结

除了FlexBox和Columns,现在还不确定哪个新布局模块可以被完全跨浏览器支持。在我看来,positioned floats和Excls非常像,有可能会被合并。Grid布局已经并入了一些template布局的内容,肯定会出现在IE10中。Regions已经 被webkit的一个分支支持,所以应该很快会出现在webkit的浏览器中(safari,chrome等)。

所以我敢在这里做一个大胆的预测,除了一些语法的修改,你在这里看到的多数内容将来都会出现在css3中。我觉得这是一件好事,这些新方法是互补的,而不是相互竞争的,若干年后,在我们在构建精致的网页时,她们将会使我们的工作变得简单。

相关阅读:CSS3 Region:基于HTML和CSS3的富页面布局

相关推荐