本文由大漠根据Shock Family的《A Look at What’s Coming Up: CSS3 Flexible Boxes》所译,整个译文带有我们自己的理解与思想,如果译得不好或不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:http://www.onextrapixel.com/2013/04/23/a-look-on-whats-coming-up-css3-flexible-boxes,以及作者相关信息
——作者:Shock Family
——译者:大漠
设计一个网站,布局可能是最生要的元素之一。当你网站的用户理解你的布局和喜欢上你的网站布局,他们用起来很开心,这样用户会在你的站点呆的时间更长,甚至会定期访问你的网站。我们通过导航能浏览一些高质量的内容,但由于网站混乱的设计和完全乱套的布局,我们第一反应,那就是尽可能快的离开这个网站。
从小屏幕(240px)到超大的屏幕(1920px以上),没有一个标准的布局可以适合这些不同屏幕的尺寸。到目前为止,我们要么是使用inline-block,要么是使用浮动给一个网站进行布局。不管使用的是什么方法,要让网页在不同的区域得到响应式布局,我们需要大量的变通方法来进行检测。幸运的是,W3C意识到了这一点,实际上是给开发人员谋福利。这个就是我们关注的Flexible Boxes。
这篇文章是关于CSS3 Flexible Box布局模块,截至2013年1月10日支持的浏览器只有Chrome 21.0+和Opera 21.0+。
Flexible Boxes来了
老的和新的Flexible Boxes
Flexible Boxes是有点让人摸不到头脑,因为在几个浏览器中实现Flexible Boxes模块有好几个版本。CSS-Tricks在《"Old" Flexbox and "New" Flexbox》做了一个简短的解释,告诉我们不同的版本可用以及如何认出他们。特别声明:这篇文章是关于Flexbox的最新版本(使用的是"display:flex")。
Flexible Boxes是什么?
现在,最好的方法是通过实例来解释某些东西,所以,我们将使用flex来创建一个完整的布局。为了让我们避免任何阻碍级的事情,一切都会使用flex来创建伸缩容器和伸缩项目。
上图来自于W3C,有关于Flexible Boxes术语的标识。
首先,在这里你要有一些概念,我们将更好的理解:
<div class="flex-container"> <!-- 这个是伸缩容器 --> <div class="flex-item">1</div> <!-- 这个是伸缩项目 --> <div class="flex-item">2</div> <div class="flex-item">3</div> <div class="flex-item">4</div> </div>
这只是一个包含四个div标签的容器,为了让们能够灵活性适应宽度,我们需要添加一些CSS3样式:
.flex-container { /* Chrome下的写法 */ display: flex; } .flex-item { -webkit-flex: 1; flex: 1; }
正如您所看到的,当给一个容器设置了“display:flex”,这个容器就变成了伸缩容器,而这个容器的子元素就变成了伸缩项目。伸缩项目总是会尽量的配合伸缩容器,自动的适配伸缩容器的宽(如果是行的话)或者自动适配伸缩容器的高(如果是列的话)。你是否希望伸缩容器是一行或者一列,你可以使用“flex-flow:column”属性来设置。最后每一个伸缩项目具有一个弹性属性(上面的例子是flex:1)。有了flex属性可以让伸缩项目填补多余的空间(或收缩不足的空间)来填充整个伸缩容器。
每一个伸缩容器被定义为两个轴(主轴和侧轴),但仅这两个轴往往是不够的。为了更能准确性了解这些弹性盒子,我们创建一个完整的布局实例来说明,以及回答大多数大家想知道的问题。
使用Flexible Boxes创建一个完整的布局
这里使用了HTML5的结构
<div class="flex-container"> <header> Header </header> <div class="flex-area"> <section> <article class='featured-article'> First Article </article> <article> Second Article </article> <article> Third Article </article> </section> <aside> Sidebar <div class="box"></div> <div class="box"></div> <div class="box"></div> </aside> </div> <footer> Footer </footer> </div>
如果要将这个结构变成一个布局,我们需要添加一些CSS。我们将制作一个典型的布局,宽屏的页眉和页脚,一个中间容器,这个中间容器包括两列(主内容列和侧边栏列),并且主内容列将有特色的文章置顶,其他两篇文章放在下面分两列并排显示;侧边栏有三个box并列显示:
.flex-container { -webkit-flex-flow: column; display: flex; flex-flow: column; } header, footer { -webkit-flex: 0px 0px 100px; flex: 0px 0px 100px; } .flex-area { -webkit-flex-flow: row; -webkit-flex: 3 1 auto; display: flex; flex-flow: row; flex: 3 1 auto; } section { -webkit-flex-flow: row wrap; -webkit-flex: 4 1 auto; display: flex; flex-flow: row wrap; flex: 4 1 auto; } article { -webkit-flex: 1 35%; flex: 1 35%; } .featured-article { -webkit-flex: 2 1 100%; flex: 2 1 100%; } aside { -webkit-flex-flow: column; -webkit-flex: 0px 0px 240px; display: flex; flex-flow: column; flex: 0px 0px 240px; } .box { -webkit-flex: 1; flex: 1; }
上图就是这个布局示例的效果。
我们在示例中添加了少量的代码,比如说背景和间距等,使例子清晰一些。现在我们一步一步来分析这个CSS代码,让我们能更清晰的了解发生了什么:
- 首先我们需要将几个容器变成伸缩容器,我们的主容器是一个定义了类名为“flex-container”的div元素,因此我们使用前面介绍的方法,在这个元素中定义一个“display:flex”。这样一来,“div.flex-container”下的所有子元素(header、div.flex-area和footer)都变成了伸缩项目。然后我们想要伸缩项目从上到下的分几行排列,所以在这个伸缩容器中还定义了一个“flex-flow:column”。
- 给页眉和页脚设置一个固定的高度。通过“flex”属性我们决定他们按下面的形式来表现:第一个“0”意味着我们不想让它扩展(flex-grow:1),第二个“0”意味着我们不想让它收缩(flex-shrink:0),最后一个值“100px”是收缩基准值(flex-basis)。
- 接下来将“div.flex-area”元素设置为另一个收缩容器,所以我们也在这个元素上设置了“dislpaly:flex”。注意,这个非常好设置了“flex”属性后也变将对应的变成了伸缩容器,而其子元素也对应的变成了伸缩项目。在这个例子中,我们将其收缩基准值(flex-basis)设置为“auto”,因为我们希望它能在主内容区内扩展任何空间,在不收缩太多的情况下扩展足够大的空间,主要出发点他们是主要内容。
- flex-area伸缩容器具有两个伸缩项目:<section>和<aside>,我们希望他们能从左到右相互依靠在一起,因此我们在“flex-area”伸缩容器上设置了“flex-flow”的值为“row”。同时我们也希望侧边栏有一个固定的宽度“240px”,而<section>相对于剩余的空间进行扩展或者收缩填充。因此,我们为每个伸缩项目设置了一个明确的flex属性值。
- <section>伸缩项目也需要变成伸缩容器,因此我们也要将其设置为“display:flex”。这次我们希望他的伸缩项目能从左到右排列,但同时也希望他们超过一行时能自动换行,所以我们设置了“flex-flow”为“row wrap”。我们希望有“特色的文章(article.featured-article)”能置顶显示,而其他的两列等宽的显示,所以我们给所有的<article>设置了“flex”值为“1”(flex-grow),并且希望这两要大于33%,小于50%为基础。我们选择了35%,然后让余下的空间自己灵活处理。
- 对于特色文章,我们前面说了想置顶整行显示在主内容区域内,至于扩展还是收缩我们让用户来进行决定,所以我们把他的收缩基准值(flex-basis)设置为“100%”。
- 最后侧边栏应该保持为一组框,将做为一个主菜单,所以我们重复上述过程。这一次我们不希望使用一个基准收缩值,便是每个伸缩项目必须自动填充所有侧边栏空间。
这是一个非常简单的布局,适合屏幕提供适量的内容。尽管如此,在小型设备下浏览,侧边栏可能会导航一些不能看到的问题,所以我们需要借助媒体查询来使它得到充分响应。
Flexbox也可以通过一些参数设置伸缩项目是否在一行或一列。
媒体查询和Flexible Boxes响应不同尺寸
虽然我们的做了很多工作,但我们的布局还不是很友好,仍然需要添加几个媒体查询来适应不同设备。
首先我们想让侧边栏显示在页眉下面,然后是主内容,接着是页脚,同时减少页眉和页脚的高度,我们应该这样做:
@media only screen and (max-640px) { .flex-area { -webkit-flex-flow: column; flex-flow: column; } header, footer, aside { -webkit-flex: 0px 0px 50px; flex: 0px 0px 50px; } aside { -webkit-flex-flow: row; -webkit-order: 1; flex-flow: row; order: 1; } section { -webkit-order: 2; order: 2; } }
如果用户使用一个更小的设备,两列文章中部分将被丢失显示不出来,所以我们要添加另一个媒体查询,创建一个完全垂直站点,以适应420px或者更小的设备
@media only screen and (max-420px) { section { -webkit-flex-flow: column; flex-flow: column; } article { -webkit-flex: 1; flex: 1; } }
CodePen演示了一个响应式案例的布局。
Flexboxes充许响应式布局——来自于codepen
总结
这是一个很好的,只使用最新版本css3 flexible boxes模块制作一个充分响应简单布局。使用的代码数量远远少于类似网站使用的代码量。然而,最大的不足之处是其跨浏览器的兼容问题,因为到目前他只能在Chrome 21.0+和Opera 12.10+上得到友好支持。
不过Fiefox18、Safari和IE10支持这个模块的早期语法版本,将来也会慢慢支持这个最新语法,它使我们看到这个属性将来会经常的用于布局之中,也我们的布局更简洁,更容易。与此同时,继续观注这个模块给我们带来的惊喜。
译者手语:整个翻译依照原文线路进行,并在翻译过程略加了个人对技术的理解。如果翻译有不对之处,还烦请同行朋友指点。谢谢!
如需转载烦请注明出处: