弹性框布局 (flexbox) 添加了级联样式表级别 2 修订版 1 (CSS2.1) 中定义的四个基本布局模式:块布局、内联布局、表格布局和定位布局。使用弹性框布局功能,你可以更加轻松地设计复杂网页布局,并且可以在屏幕和浏览器窗口大小发生变化时进行调整以保持元素的相对位置和大小。 弹性框可减少对浮动和表格布局(难以正确定位和调节大小)的依赖。
弹性框布局的好处,例如:
注:这篇文章使用的是Flexbox最后语法,目前支持浏览器:Opera Mobile12.1+、Opera12.5+、Firefox18+(partial)和chrome。Chrome需要添加浏览器前缀“-webkit-”,Opera支持标准语法,不用添加任何前缀。Firefox有部分支持,也需要添加前缀“-moz-”,同时需要设置一个标志(到firefox浏览器地址栏中输入:about:config,搜索“flexbox”,找到之后双击“layout.css.flexbox.enabled”,设置他的“value”值为“true”)。注意,其他浏览器除了opera自2009年支持flexbox以来,都使用旧的语法规则,真的不应该使用这些过时的语法。一定要记住阅读和使用2012年以前有关于flexbox的文章和代码时,flexbox都使用的老语法。
在详细阅读这篇文章之前,我们很有必要先了解flexbox的几个常用术语,这样有助于大家对后文的理解。
下图是一个row伸缩容器中各种方向与大小术语的示意图:
我们如何开始使用Flexbox呢?大多数的Flexbox属性都应用于父容器的元素上。因为Flexbox,你可以指定你想要制定的一个容器,使用一个特殊的值显示属性,就像这样:
footer { display: flex; }
接下来你可以使用“flex-row”属性来指定子元素布局是在一行还是一列显示。如果你愿意,你可以定义关键词“wrap”,来指定内容容器在新的一行(当父元素容器太小,flexbox元素想在同一行显示)。在我们的例子中,我在footer中设置了“row wrap”
footer { display: flex; flex-flow: row wrap; }
flex-flow是用来伸缩行换行,flex-flow属性是同时设定“flex-direction(伸缩流的方向)”和“flex-wrap(伸缩行换行)”属性的缩写,两个属性决定了伸缩容器的主轴与侧轴。此属性主要适用于伸缩容器。在这篇文章的例子中,主要是“footer”元素。
flex-direction属性可以用来设定伸缩容器的主轴的方向,这也决定了用户代理配置伸缩项目的方向。主要适用于伸缩容器,主要包括以下几个值:
flex-wrap属性主要用来控制伸缩容器是单行还是多行,也决定了侧轴方向一新的一行的堆放方向。主要适用于伸缩容器,主要包括以下几个值:
关键词“wrap”明显的变得很有意义。
注:“flex-flow”在这里采用了缩写,他主要包括两个属性“flex-direction”(值为row、column、row-reverse和column-reverse,后面的两个属性值与row和column方向相反)和“flex-wrap”(值为:wrap、no-wrap和wrap-reverse)。
如果你要想flexbox工作正常,你有些概念必须得清楚,比如说让flexbox正常工作的主轴和侧轴,他们看上去有点像X轴和Y轴,但还是有所差别的。主轴的方向主要是用来确定flex的主方向,所以你子元素要么放置在一行,要么放置在一列。侧轴主要垂直于主轴运行,如下图所示:
flexbox的主轴与侧轴
Flexbox有一系列的方法来帮助你调整伸缩项目沿着主轴和侧轴的对齐。
第一个我们一起看看“align-items”属性,它充许您调整伸缩项目在侧轴的对齐方式,主要包括以下几个值:
可以用来设置伸缩容器中包括匿名伸缩项目的所有项目的对齐方式。
为了更形像的理解"align-items"各个属性值对应在侧轴上的效果,可以参考下图:
还有一个主要属性“justify-content”使用的也比较多,这个属性主要用来设置伸缩项目沿主轴的对齐方式,从而调整伸缩项目之间的间距。设置了这个属性,在主轴方向上设置的任何margin都不会起作用。
通过伸缩容器中的三个不同颜色的项目,展示五种「justify-content」关键字的效果。
您还可以调准伸缩行在伸缩容器里的对齐方式。不过他会更改flex-wrap的行为,比如说:“wrap”。align-content和align-items相似,但是不是对齐伸缩项目,它对齐的是伸缩行,其主要包括以下几个值:
align-content」各关键字对多行的伸缩容器的效果。
传统上不改变元素的结构要改变元素的布局顺序一直是一个痛苦的事情。不过在Flexbox中,你可以通过“order”属性来修改伸缩项目的布局顺序(在不调整结构前提之下)。这个属性一直接受的整数值——称为系数集——也称为排序组,会出现在伸缩项目中。
order属性是用来设置伸缩项的显示顺序,默认状态下,用户代理会用伸缩项目出现在源文档的次序配置这些伸缩项目。order属性透过将元素分到有序号的组以控制元素出现的顺序。在伸缩布局中,order属性控制伸缩项目在伸缩容器里的顺序。
order取值越大,越排在后面。并且order可以取负值。
Flexbox最强大的特性是能够通过“flex-flow”属性设置伸缩项目的流动方向,或者可以通过“flex”属性设置一个可用的空间。它的取值可以有三个部分(flex-grow、flex-shrink、flex-basis)。让我们一个一个来尝试,看看他们的影响。首先添加的是“flex-grow”:
#first { flex: 1; } #second { flex: 1; } #third { flex: 1; }
这些没单位的值是作为一个比例,他们决定于伸缩容器中有多少个伸缩项目。可以决定伸缩项目在伸缩容器中的空间大小。如果每个都设置为1,每个伸缩项目在伸缩容器内都相等。如果你给其中一个伸缩项目设置为2,那么这个伸缩项目会占用空间是其他伸缩项目的两倍。
#first { flex: 1; } #second { flex: 2; } #third { flex: 1; }
你也可以像下面一样设置flex-basis的值:
#first { flex: 1 200px; } #second { flex: 2 300px; } #third { flex: 1 250px; }
首先flex-basis的值主要取决于伸缩项目的width或者高,同时取决于流动方向。然后,剩下的空间根据flex-grow给伸缩项目最后宽度来划分。所以伸缩项目会沿着主轴线大小为200px、300px和250px,总共750px。如果伸缩容器沿主轴方向是950px,这样就会多出一个200px空间,那么这多出的200px空间将分配给伸缩项目。第一个和第三个伸缩项目将得到50px的空间,因为他的flex-grow值是“1”,他们最终的空间是250px和300px。第二个伸缩项目将获得100px空间,因为他的flex-grow值为“2”,他的最后空间大小为400px。
flex的第三部分很少使用,但我们可以看看他的使用方法,你也可以将flex-shrink像下面那样设置:
#first { flex: 1 1 400px; } #second { flex: 2 3 600px; } #third { flex: 1 2 400px; }
flex-shrink称为收缩比率。这个值只有伸缩项目在没主轴方向溢出伸缩容器才会发挥作用。他们充当比例值,但这回指的是溢出量,将这个溢出量按比例分配给每个伸缩项目,用于防止伸缩容器溢出。
比如说,我们伸缩容器沿主轴方向宽度是1100px,按照上面的示例代码计算,我们的伸缩项目会超出300px(伸缩项目沿主轴方向总值为1400px),这个时候通过flex-shrink收缩他们:
这样flex-shrink使用伸缩项目得到一个较小的宽度。
我的例子中最终将值设置成:
#first { flex: 1 0 7rem; } #second { order: 1; flex: 2 0 8rem; } #third { flex: 1.5 0 7rem; }
flex用来决定伸缩项目的伸缩性。一个伸缩容器会等比地按照各伸缩项目的扩展比率分配剩余空间,也会按照收缩比率缩小各项目以避免溢出。
flex属性可以用来指定伸缩长度的部件:扩展比率flex-grow,收缩比率flex-shrink以及伸缩基准值flex-basis。当一个元素是伸缩项目时,flex属性将代替主轴长度属性决定元素的主轴长度。若元素不是伸缩项目,则flex属性没有效果。
上图是一个显示「绝对」伸缩(以零为基准值开始)与「相对」伸缩(以项目的内容大小为基准值开始)差异的图解。这三个项目的伸缩比例分别是「1」、「1」、「2」。
在我的例子中结合一个多行flxbox(flex-flow:row wrap)和伸缩长度flex(如:flex:1 0 7rem)以及媒体查询实现了一个完美的效果。在不同视窗宽度下,伸缩项目在伸缩容器中可以平滑的进行变化。如图所示:
flexbox对应的响应式代码:
footer { display: -webkit-flex; -webkit-flex-flow: row wrap; -webkit-align-items: stretch; display: -moz-flex; -moz-flex-flow: row wrap; -moz-align-items: stretch; display: -ms-flex; -ms-flex-flow: row wrap; -ms-align-items: stretch; display: flex; flex-flow: row wrap; align-items: stretch; } #first { -webkit-flex: 1 0 7rem; -moz-flex: 1 0 7rem; -ms-flex: 1 0 7rem; flex: 1 0 7rem; } #second { -webkit-order: 1; -webkit-flex: 2 0 8rem; -moz-order: 1; -moz-flex: 2 0 8rem; -ms-order: 1; -ms-flex: 2 0 8rem; order: 1; flex: 2 0 8rem; } #third { -webkit-flex: 1.5 0 7rem; -moz-flex: 1.5 0 7rem; -ms-flex: 1.5 0 7rem; flex: 1.5 0 7rem; } @media screen and (max-width: 1000px) { body { width: 100%; } #fixed { left: 0%; right: 0%; } } @media screen and (max-width: 520px) { #fixed { position: static; } section { padding: 1rem 2rem; } body { padding-bottom: 0; background-image: none; background-color: white; } footer { padding: 0 1rem 0; } #first { -webkit-flex: 1 0 10rem; -moz-flex: 1 0 10rem; -ms-flex: 1 0 10rem; flex: 1 0 10rem; } #second { -webkit-flex: 1 0 10rem; -moz-flex: 1 0 10rem; -ms-flex: 1 0 10rem; flex: 1