CSS多列布局Multi-column、伸缩布局Flexbox、网格布局Grid详解

css属性为我们提供了更加便捷的网页布局方式。来自微软的thomas lewis将带你认识去Grid Alignment,Flexibox Box以及Multi-column Layout这三大领域。

这篇文章最早出现在the April 2012 issue (226)这期的.net杂志上-这杂志是面向网页设计者以及开发者,全球销量最高的杂志。

按照以往来说,用CSS来布局看起来总是一样非常繁杂的工作。然而,随着一个个新标准的推出,网页设计者已经能够实现非常轻松地进行布局工作了。

主流的浏览器,在W3C的推动下,已经开始实现多种新型的布局方式,而且我们现在已经可以开始使用了。举个例子,W3C开始把CSS3 Multicolumn Layout Module考虑进来。这就意味着W3C非常愿意看到浏览器在将来能够对上面的模块实现出来。

前缀(Vendor prefixes)

虽然一些浏览器对属性普遍的认知,但这并不代表着你就不能采用这些属性。在现在,我们可以通过添加前缀来获得一些主流浏览器对属性的支持,直到这些属性得到了稳定的支持,我们才有可能不用添加这些前缀。Jonathan Snook说,添加供应商前缀就相当于做了两件事情:

  • 让开发者在调试新功能的时候,不用担心转换浏览器有不兼容的情况。
  • 可以告诫网页开发者这些东西是不稳定的。

存在某些争议的前缀一文中人们在讨论是否需要添加前缀的时候,这个做法确实为人们在标准完全确定之前提供了一个提前体验这些属性的机会,当然了,人们在这时候使用这些属性都还需要小心翼翼的。下面我们会看到这些布局属性各种浏览器的使用范围,一般来说,你也许不需要这些浏览器都需要支持这些属性,但还是很有必要对这些有个宏观的了解。

CSS多列布局Multi-column、伸缩布局Flexbox、网格布局Grid详解

多列布局(Multi-column)

下面我来介绍第一个布局特征,让我们就从简单的开始,css的Multi-column布局模块。(下面统称Multi-column)你可能想得到,这个模块给予了我们脱离position和float这些属性,就能在网页栏目上布局的能力。

同样,根据容器的大小,就可以控制创建栏目的数量,这是非常了不起的一个特点。举个例子,如果你需要一个栏目宽度为13em(用ps作为长度单位也是可以的)的容器,并且根据这个容器的大小,创建数量适合的栏目数,上代码!

#mcexample {
column-width: 13ems;
}

看到了没,简单吧!你还可以自己定义栏目的数量,在这个时候,这些栏目就会自动平均分配栏目宽度,尽量充满容器的宽度。

#mcexample {
column-count: 3;
}

如果你想更具体地控制你的栏目,也行!举个例子,下面的代码,可以让你控制栏目的数目,栏目的自身宽度,栏目与栏目之间的间隔等样式。上代码!

#mcexample{
columns: auto 13em;/* column-count,column-width*/
column-gap: 1em;
column-rule: 1em solid black;/* width, style, color */
}

一些其他的属性有如下功能:

  • 定义栏目的最大限度
  • 定义在多栏目中的间隔大小
  • 在多个栏目中平均分配好显示内容

Multi-column好就好在能够自动为你安排好流体内容,你用不着计算确定栏目的数量,让他们排排站好就行了!

然而,在使用Multi-column的时候,你还是有东西要注意下的,你要注意设置栏目的高度,否则别人在访问网站的时候,就因为高高的栏目,看个栏目内容还要上拉下拉滚动条那么费劲,这用户体验那该有多不好。

大部分的桌面浏览器和移动浏览器都支持Multicolumn(对于IE来说,你现在只能在IE10的平台上来预览一下)。一个快速查询一个属性是否被浏览器支持的方法就是到caniuse.com查找主流的桌面和移动浏览器是否都支持这些属性。我们要记住的是,也许一个属性是被支持的,但是也是添加浏览器供应商前缀,有些浏览器也不完全对属性进行支持,总之,我们一定要多测试,这才能更好地解决问题,避免不必要的麻烦。

伸缩性布局(Flexbox)

Flexible Box 的css布局模块,在w3.org/TR/css3-flexbox中可以查得到。为了方便起见,下面这一模块统称 Flexbox。

Flexbox 赋予了我们能够对一个父级容器中子级元素进行水平以及垂直的定位,并且在这些子级元素的彼此之间都添加间距的能力。

举个例子,在IE10中使用Flexbox,首先就要用到display属性,看代码!

#fbexample {
display: -ms-flexbox;
background: black;
}

同样,我们还可以设置子级元素排列的方向,不过我们需要在添加相应的的浏览器供应商的前缀(对于IE10来说,我们需要在开头的地方添加-ms-flexbox),看代码!

#fbexample {
display: -ms-flexbox;
-ms-flex-direction: row;
}

Flexbox让我们能够以多种方式排列子级元素:从左到右,从右到左,从上到下,从下到上

在这时候我们或许需要定义子级元素的排列坐标轴方向。

下面的代码同样控制了每个子级元素都在父级容器中间显示,同样,对于每个子级元素来说上下的空间分配都是一样的

#fbexample {
display: -ms-flexbox;
-ms-flex-direction: row;
-ms-flex-align: center;
}

我们还可以用另一个属性flex-pack,这个属性控制子级元素如何分配剩余的空间。举个例子来说,首先我们要使得子级元素按照一定的方向在父级元素中排列:

#fbexample {
display: -ms-flexbox;
-ms-flex-direction: row;
-ms-flex-align: center;
-ms-flex-pack: start;
}

但是我们如果有过多的子级元素,而且我们不希望他们的尺寸被压缩到一个不是我们想要的情况的时候该怎么办呢?好吧,在这个时候我们采用flex-wrap把子级元素擦除之后,仍然可以让浏览器继续正常显示:

#fbexample {
display: -ms-flexbox;
-ms-flex-direction: row;
-ms-flex-align: center;
-ms-flex-pack: start;
-ms-flex-wrap: wrap;
}

现在我们知道怎么建立起容器了,那该怎么控制好我们的子级元素呢?首先我们要在html把这些元素设定成Flexbox元素的子级元素,代码如下:

CSS代码:

#fbexample {
display: -ms-flexbox;
}
#fbchild1 {
background: blue;
}
#fbchild2 {
background: green;
}
#fbchild3 {
background: red;
}

HTML代码:

<div id="fbexample">
<div id="fbchild1">1</div>
<div id="fbchild2">2</div>
<div id="fbchild3">3</div>
</div>

为了验证子级元素的自适应性。我们可以把flex的属性值设定为0,这代表着没有了自适应性,或者设定数值为1或2,代表着子级元素将要占据多少份额的空间.

CSS多列布局Multi-column、伸缩布局Flexbox、网格布局Grid详解

图解说明:

当Flexbox被运用到元素当中,很容易就对子级元素进行丰富多样的布局,在这里我们看得到的是一个水平布局和包围起来的布局。

举个例子来说,我们有三个子级元素,第一个子级元素的数值设定为0,第二个子级元素的数值设定为1,第三个子级元素的数值设定为2。

第一个子级元素将会保留原来的尺寸大小,也就是说他没有自适应性,第二个子级元素将会和第三个子级元素共同分享多出来的空间,第二个子级元素占据其中的3分之1长度,而第三个子级元素就占据其中的3分之2长度。其中最值得称道的就是,在这个过程当中浏览器将会自动为你计算当中的长度,妈妈再也不用担心我的计算了!

#fbchild1 {
background: blue;
}
#fbchild2 {
background: green;
-ms-flex: 1;
}
#fbchild3 {
background: red;
-ms-flex: 2;
}

在此时此刻,敏锐的你一定会发现,最新准则上面的一些属性不一定看起来完全正确,现在的Flexbox仅仅就是W3C所考虑的一个工作草图,这只是早期的一个标准。作为一个在发展的项目,经常变化是很正常的一件事情,下面,我们来看下最近准则的推出时间:

  • November 29, 2011
  • March 22, 2011
  • July 23, 2009

如果你在caniuse.com中查找 Flexible Box布局模块,你将会看到使用的Flexbox属性前面都会出现供应商的前缀。一些供应商依据的是2009年的准则(可以参考上面的例子)而不是最新的 2011年9月的那个。这就是为什么我们不仅仅要参考准则上是否支持,还要在实践当中理解这些属性是否真的支持。

然而让人欣慰的是,我们不用担心在面对更新准则带来的转变难以适应,举个例子,就像现在这样子,说明一个元素是Flexbox就可以了,看代码!

#fbexample {
display: -ms-flexbox; }

Grid Layout

按照以往来说,在对标准革新的支持方面,IE是公认的最迟钝的浏览器。但是在最新的版本更迭当中,IE一改以往反应慢的颓势,来了个华丽丽的逆袭。举个例子,在最新的IE10的平台当中,支持基于CSS 的网格布局。相关说明你可以在w3.org/TR/css3-grid-layout 中,而且该说明由微软在最近的四月份向W3C组织提交,截至到目前为止,IE10是唯一对该网格布局进行支持的浏览器。

CSS多列布局Multi-column、伸缩布局Flexbox、网格布局Grid详解

图例说明:

在网格系统当中,我们不再纠结定位(position)与浮动(float)的问题,而是以更加简单快捷的方式来设置rows和columns的方式进行表格布局。

网格布局是在网页设计之前就要考虑的基础,所以说,浏览器对 它的普遍支持仅仅是一个时间上的问题罢了。而它正是最有希望成为html中的table元素的终结者!这个标准将会能够让我们使用rows和 columns对页面进行布局而且在我们保持布局与内容相互独立的时候可以让内容跨越单位行来显示。首先, 我们在开始网格布局之前还是得添加供应商前缀,看代码:

#gridexample {
display: -ms-grid;
}

我们可以设定columns(列)和rows(行)的大小规格:

#gridexample {
display: -ms-grid;
-ms-grid-rows: 30px 5em auto;
-ms-grid-columns: auto 70px 2fr 1fr;
}

什么?那么多的属性值让你很头晕?好吧,我们来慢慢分析,一个一个地了解真相吧。上面的代码会向我们呈现四行三列的网格。

  • 第一行的高度将会是30px。
  • 第二行的高度将会是5em。
  • 第三行的高度根据剩下的空间大小自动调整
  • 第一列的宽度根据剩下的空间大小自动调整
  • 第二列的宽度是70px
  • 第三列的宽度将会是剩余宽度的三分之二
  • 第四列的宽度讲会是剩余宽度的三分之一

现在我们也可以在我们的网格中为子级定制特别的位置。如果我们希望我们的子级元素位于第一行,第二列,我们就可以这么干,看代码:

#griditem1 {
-ms-grid-row: 1;
-ms-grid-column: 2;
}

记住,这个跟Flexbox差不多,我们的子级元素需要被定义为网格元素的子级。还有,我们如果希望元素跨行显示,那么我们就可以使用grid-row-span,看代码!

#griditem1 {
-ms-grid-row: 1;
-ms-grid-column: 2;
-ms-grid-row-span: 2;
}

而且我们还可以通过使用grid-row-aligngrid-colum-align来排列元素。这些属性能够是你定义内容在行列当中居中显示,你还可以在水平或者垂直对其排列元素。举个例子吧,如果要使元素在栏目中居中显示,我们可以这样干:

#griditem1 {
-ms-grid-row: 1;
-ms-grid-column: 2;
-ms-grid-column-align: center;
}

在过去的日子当中,HTML的基于table的布局总会带来不少的麻烦,那是因为这些元素只会独来独往,这都导致了在面对不同显示设备时候所产生的 不稳定因素。但是在网格布局中,我们可以通过使用一些像Media Queries通过依据我们的设备宽度,高度,等等参数来为我们提供多种样式。

CSS多列布局Multi-column、伸缩布局Flexbox、网格布局Grid详解

图解:Griddle是一款来自微软的应用程序,这是一个运用了Multi-column,Flexbox和Grid Layout等技术与Dribble相联系的app。

总结

如果你更多地追求视觉上的享受,我建议你看看 Markus Mielke's presentation,在这里讨论了这篇文章提及或者没有提及的布局特点,而且讨论了他们是怎么同样运用在app上的。

在这篇文章当中,我们提及的布局特征都是被所有浏览器普遍支持的,而且一些仅仅刚刚成型。这些可能会让人感觉实用性不强,这种感觉或许在某一方面是对的,但是呢,作为设计师我们应该对这些东西都统统接受理解,我们要面对css的一切东西,而且那些天天被我们使用的css属性,不都是这样一步步发展过来的吗?

From:http://www.5icool.org/a/201308/a2080_2.html

上一篇:jQuery 网格布局插件


下一篇:为网格布局图片打造的超炫 CSS 加载动画