原文转自:http://www.w3cplus.com/css3/flexbox-basics.htmlcss
在不少方面HTML和CSS是一个强大的内容发布机制——易学、灵活和强大。但复杂的布局是他不擅长的。若是你想建立一个简单的图片与文本的布局,那么还算简单,可是制做一个复杂的多列布局,要作的众多浏览器的兼容一致那仍是很复杂的。咱们一般都是使用浮动或者其余方法来实现这个目的,而其中出现的bug和浏览器的差别性使用对布局失去兴趣。html
为了应对这种状况,CSS3包含了许多模块,使用不一样的布局更加容易。咱们已经在其余文章中看到多栏布局和媒体生成的内容分页,如今咱们将注意力转向CSS3的 Flexbox布局模块。node
有关于多栏布局和flexbox的基础知识除了上面的英文教程以外还能够参阅下面的中文教程:css3
- CSS3 Multi-columns 之跨列
- CSS3 Multi-columns 之column-gap column-rule
- CSS3 Multi-columns 之列数和列宽
- CSS3 Multi-columns 之跨列
- 深刻了解 Flexbox 伸缩盒模型
- CSS 伸缩盒布局模组
——大漠web
Flexbox一般能让咱们更好的操做他的子元素布局,例如:chrome
听起来至关有用,不是吗?接下来让咱们更详细的探索它。浏览器
注:这篇文章使用的是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都使用的老语法。Chris Coyie有一篇文章《“Old” Flexbox and “New” Flexbox》,这篇文章能更好的告诉你如何阅读一个过期的文章。app
flexbox的术语
在详细阅读这篇文章以前,咱们颇有必要先了解flexbox的几个经常使用术语,这样有助于你们对后文的理解。布局
- 伸缩容器:一个设有“display:flex”或“display:inline-flex”的元素
- 伸缩项目:伸缩容器的子元素
- 主轴、主轴方向:用户代理沿着一个伸缩容器的主轴配置伸缩项目,主轴是主轴方向的延伸。
- 主轴起点、主轴终点:伸缩项目的配置从容器的主轴起点边开始,往主轴终点边结束。
- 主轴长度、主轴长度属性:伸缩项目的在主轴方向的宽度或高度就是项目的主轴长度,伸缩项目的主轴长度属性是width或height属性,由哪个对着主轴方向决定。
- 侧轴、侧轴方向:与主轴垂直的轴称做侧轴,是侧轴方向的延伸。
- 侧轴起点、侧轴终点:填满项目的伸缩行的配置从容器的侧轴起点边开始,往侧轴终点边结束。
- 侧轴长度、侧轴长度属性:伸缩项目的在侧轴方向的宽度或高度就是项目的侧轴长度,伸缩项目的侧轴长度属性是「width」或「height」属性,由哪个对着侧轴方向决定。
下图是一个row伸缩容器中各类方向与大小术语的示意图:flex
上图以及术语介绍来自于:http://www.w3.org/html/ig/zh/wiki/Css3-flexbox/zh-hans
——大漠
在制做flex例子开始,先让咱们考虑一个简单的示例来讲明flexbox布局的容易性。咱们来看一个“内容布富”的页脚,这个页脚包含了三个子元素,这种而脚的类型也是至关的典型。让咱们去接触细节,这个页脚包含了连接、联系信息和版权声明。咱们想把这三个元素显示在一个水平线上,而且但愿连接部分的宽度是其余两个内容宽度的两倍。今天以前咱们经常经过浮动子元素,设置子元素宽度,并使用不一样的margin或padding来调整对齐。在全部的维度,没有固定的宽度值,这样每每是不许确的,也让事情变得更僵化。但Flexbox在这里就能够帮助咱们实现须要的效果。
我制做的flexible例子。例子很简单,除了页脚,还有一个包含三个盒子的flexible布局。
注:看看我最终实现的例子(如上图所示)。你能够看到一个美丽的设计,主内容一列和页脚经过“position:fixed”固定在页面底部。布局灵活,页面的页脚子元素比例能够根据主要内容列的百分比进行调整。您还会注意到,我用了一些媒体查询来转变小屏幕宽度的布局。
咱们如何开始使用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-flow属性是同时设定“flex-direction(伸缩流的方向)”和“flex-wrap(伸缩行换行)”属性的缩写,两个属性决定了伸缩容器的主轴与侧轴。此属性主要适用于伸缩容器。在这篇文章的例子中,主要是“footer”元素。
有关于flex-direction
flex-direction属性能够用来设定伸缩容器的主轴的方向,这也决定了用户代理配置伸缩项目的方向。主要适用于伸缩容器,主要包括如下几个值:
- row:flex-direction的默认值,表示伸缩容器的主轴与当前书写模式的行内轴(文字布局的主要主向)。主轴起点与主轴终点方向分别等同于当前书写模式的始与结方向。
- row-reverse:表示的是除了主轴起点与主轴终点方向交换之外同row属性值的做用。
- column:表示的是伸缩容器的主轴与当前书写模式的块轴(块布局的主要方向)同向。主轴起点与主轴终点方向分别等同于当前书写模式的前与后方向。简单的能够理解为列布局。
- column-reverse:表示的是除了主轴起点与主轴终点方向交换之外同“column”的属性值做用。
关于flex-wrap
flex-wrap属性主要用来控制伸缩容器是单行仍是多行,也决定了侧轴方向一新的一行的堆放方向。主要适用于伸缩容器,主要包括如下几个值:
- nowrap:flex-wrap的默认值,表示的是伸缩容器为单行。侧轴起点方向等同于当前书写模式的起点或前/头在侧轴的那一边,而侧轴终点方向是侧轴起点的相反方向。
- wrap:表示的是伸缩容器为多行。侧轴起点方向等同于当前书写模式的起眯或前/头在侧轴的那一边,而侧轴终点方向是侧轴起点的相反方向。
- wrap-reverse:除了侧轴起点与侧轴终点方向交换之外同wrap所起做用相同。
注:以上内容来自于Css3-flexbox/zh-hans
——大漠
关键词“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
能够用来设置伸缩容器中包括匿名伸缩项目的全部项目的对齐方式。
为了更形像的理解"align-items"各个属性值对应在侧轴上的效果,能够参考下图:
——大漠
这些都是术语解释,只有动手去尝试,调整不一样的值,才能知道各个属性值所表明的运行效果,你们能够看看下图所运行的效果。对于这个例子,我采用的是“stretch”属性值。
footer { display: flex; flex-flow: row wrap; align-items: stretch; }
上图是align-items各个属性值运行后的效果,从上至下依次是:flex-start、center、flex-and和stretch。
每每全部列表项的内容没法填满父元素的整个高度,特别是在不知道宽度和高度的视窗变化之下。不少状况之下为了让这些列实现等高效果,是一件多么可怕的事情,并且不少时间都浪费在一些呆反的解决方案和处理兼容上,好比说设置一个等高的效果,使用假的列?
若是你执着于等高的解决方案,你不仿移步看看这篇教程《八种建立等高列布局》。
——大漠
还有一个主要属性“justify-content”使用的也比较多,这个属性主要用来设置伸缩项目沿主轴的对齐方式,从而调整伸缩项目之间的间距。设置了这个属性,在主轴方向上设置的任何margin都不会起做用。所以我特地建立了一个例子来证实这点。
在这个例子中,我为伸缩项目设置了一个百分比宽度:
#first { width: 25%; } #second { width: 40%; } #third { width: 25%; }
而后在伸缩容器设置了一个值,证实伸缩项目在主轴方向的margin不起做用:
footer { display: flex; flex-flow: row wrap; align-items: stretch; justify-content: space-around; }
这个值至关的不错,伸缩项目会平均地分布在行里,两端保留一半的空间。其余可用的值以下:
经过伸缩容器中的三个不一样颜色的项目,展现五种「justify-content」关键字的效果。
你也能够在实例中本身动手尝试一下,这几个值给伸缩项目在主轴上会带来什么样的变化,下图是示例中五种不一样属性值效果的截图:
上图是“justify-content”五种属性值的效果,从上到下依次是:flex-start、center、flex-end、space-between和space-around。
您还能够调准伸缩行在伸缩容器里的对齐方式。不过他会更改flex-wrap的行为,好比说:“wrap”。align-content和align-items类似,可是不是对齐伸缩项目,它对齐的是伸缩行,其主要包括如下几个值:
align-content」各关键字对多行的伸缩容器的效果。
传统上不改变元素的结构要改变元素的布局顺序一直是一个痛苦的事情。不过在Flexbox中,你能够经过“order”属性来修改伸缩项目的布局顺序(在不调整结构前提之下)。这个属性一直接受的整数值——称为系数集——也称为排序组,会出如今伸缩项目中。拿前面的例子来讲,默认状况连接块是第二个子元素,以下图所示:
默认状况footer子元素排序是:contact、links、copyright。
默认状况之下,全部的伸缩项目的顺序组都是“0”。咱们能够很容易的给每一个伸缩项目设置不一样的顺序值。更高的值会排在后面,而原来的HTML结构并不会有任何变化。因此在个人示例中,我将连接块设置了order值为“1”
#second { order: 1; }
页脚已作出新的排序:contact、copright、links。
关于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属性能够用来指定伸缩长度的部件:扩展比率flex-grow,收缩比率flex-shrink以及伸缩基准值flex-basis。当一个元素是伸缩项目时,flex属性将代替主轴长度属性决定元素的主轴长度。若元素不是伸缩项目,则flex属性没有效果。
- flex-grow:此属性值为正数值,用来设置扩展比率,也就是剩余空间是正值的时候此伸缩项目相对于伸缩容器里其余伸缩项目能分配到空间比例。若省略则会被设置为“1”。
- flex-shrink:此属性值为正数值,用来设置收缩比率,也就是剩余空间是负值的时候此伸缩项目相对于伸缩容器里其余伸缩项目能收缩的空间比例。若省略则会被设置为“1”,在收缩的时候收缩比率会以伸缩基准值加权。
- flex-basis:与width属性使用相同的值,能够用来设置flex-basis长写并指定伸缩基准值,也就是根据可伸缩比率计算 出剩余空间的分布以前,伸缩项目主轴长度的起始数值。若在flex缩写省略了此属性设置,则flex-basis的指定值是“0”,若flex-basis的指定值是“auto”,则伸缩基准值的指定值是元素主轴长度属性的值。
上图是一个显示「绝对」伸缩(以零为基准值开始)与「相对」伸缩(以项目的内容大小为基准值开始)差别的图解。这三个项目的伸缩比例分别是「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 0 10rem;