布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。
2009年,W3C提出了一种新的方案—-Flex布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能。
以下内容主要参考了:Flex 布局教程:语法篇
一、Flex布局是什么?Flex是Flexible Box的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。
任何一个容器都可以指定为Flex布局。
.box{ display: flex;}
行内元素也可以使用Flex布局。
.box{ display: inline-flex;}
Webkit内核的浏览器,必须加上-webkit前缀。
.box{ display: -webkit-flex; /* Safari,Chrome */ display: flex;}
注意,设为Flex布局以后,子元素的float、clear和vertical-align属性将失效。
采用Flex布局的元素,称为Flex容器(flex container),简称”容器”。它的所有子元素自动成为容器成员,称为Flex项目(flex item),简称”项目”。
容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。
项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。
Flexbox通常能让我们更好的操作他的子元素布局,例如:
除了display开启容器外,还有以下6个属性设置在容器上【老版本】。
定义一个Flex容器,根据其取的值来决定是内联还是块。Flex容器会为其内容建立新的伸缩格式化上下文。
.container { display: flex; /* or inline-flex */}
开启Flex容器:让一个元素变成伸缩容器
这是用来创建方轴,从而定义Flex项目在Flex容器中放置的方向。Flexbox是一种单方向的布局概念。认为Flex项目主要排列方式要么是水平排列,要么是垂直列排列。
.container { flex-direction: row | row-reverse | column | column-reverse;}
默认情况之下,Flex项目都尽可能在一行显示。你可以根据flex-wrap的属性值来改变,让Flex项目多行显示。方向在这也扮演了一个重要角度,决定新的一行堆放方向。
.container{ flex-wrap: nowrap | wrap | wrap-reverse;}
这是flex-direction和flex-wrap两个属性的缩写。两个属性决定了伸缩容器的主轴与侧轴。默认值是row nowrap(中间用空格隔开)。
flex-flow: ||
用于在主轴上对齐伸缩项目。这一行为会在所有可伸缩长度及所有自动边距均被解释后进行。当一行上的所有伸缩项目都不能伸缩或可伸缩但是已经达到其最大长度时,这一属性才会对多余的空间进行分配。当项目溢出某一行时,这一属性也会在项目的对齐上施加一些控制。
.container { justify-content: flex-start | flex-end | center | space-between | space-around;}
伸缩项目可以在伸缩容器的当前行的侧轴上进行对齐,这类似于justify-content属性,但是是另一个方向。align-items可以用来设置伸缩容器中包括匿名伸缩项目的所有项目的对齐方式。
.container { align-items: flex-start | flex-end | center | baseline | stretch;}
当伸缩容器的侧轴还有多余空间时,align-content属性可以用来调准伸缩行在伸缩容器里的对齐方式,这与调准伸缩项目在主轴上对齐方式的justify-content属性类似。
请注意本属性在只有一行的伸缩容器上没有效果。
.container { align-content: flex-start | flex-end | center | space-between | space-around | stretch;}
注意:只有多行的伸缩容器才会在侧轴上有多余的空间以供对齐,因为仅包含一行的伸缩容器中,唯一的一行会自动伸展填充全部的空间。
以下6个属性设置在项目上。
默认情况,Flex项目是按文档源的流顺序排列。然而,在Flex容器中可以通过order属性来控制Flex项目的顺序源。
.item { order: <integer>;}</integer>
根据order重新排序伸缩项目。有最小(负值最大)order的伸缩项目排在第一个。若有多个项目有相同的order值,这些项目照文件顺序排。这个步骤影响了伸缩项目生盒树成的盒子的顺序,也影响了后面的演算法如何处理各项目。
如果有必要的话,flex-grow可以定义一个Flex项目的扩大比例。它接受一个没有单位的值作为一个比例。它可以使用Flex项目完全占用Flex容器可用的空间。
如果所有Flex项目的flex-grow设置为1时,表示Flex容器中的Flex项目具有相等的尺寸。如果你给其中一个Flex项目设置flex-grow的值为2,那么这个Flex项目的尺寸将是其他Flex项目两倍(其他Flex项目的flex-grow值为1)。
.item { flex-grow: <number>; /* default 0 */}</number>
注意:flex-grow取负值将失效。
如果有必要,flex-shrink可以定义Flex项目的缩小比例。
.item { flex-shrink: <number>; /* default 1 */}</number>
注意:flex-shrink取负值将失效。
如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。
flex-basis属性定义了Flex项目在分配Flex容器剩余空间之前的一个默认尺寸。main-size值使它具有匹配的宽度或高度,不过都需要取决于flex-direction的值。
.item { flex-basis: <length> | auto; /* default auto */}</length>
如果设置为0,内容不在考虑周围额外空间。如果设置为auto,额外空间会基于flex-grow值做分布。如下图所示:
flex是flex-grow,flex-shrink和flex-basis三个属性的缩写。第二个和第三个参数(flex-shrink和flex-basis)是可选值。其默认值是0 1 auto。
.item { flex: none | [ ? || ]}
建议您 使用此简写属性,而不是设置单独属性。注意,如果flex取值为none时,其相当于取值为0 0 auto。
请注意flex-grow与flex-basis的初始值与他们在flex缩写被省略时的 默认值不同。这里的设计是为了让flex缩写在最常见的情景下比较好用。
flex常见值
flex: 0 auto,flex: initial与flex: 0 1 auto相同。(这也就是初始值。)根据width/height属性决定元素的尺寸。(如果项目的主轴长度属性的计算值为auto,则会根据其内容来决定元素尺寸。)当剩余空间为正值时,伸缩项目无法伸缩,但当空间不足时,伸缩项目可收缩至其最小值。网页作者可以用对齐相关的属性以及margin属性的auto值控制伸缩项目沿着主轴的对齐方式。
flex: auto与flex: 1 1 auto相同。根据width/height属性决定元素的尺寸,但是完全可以伸缩,会吸收主轴上剩下的空间。如果所有项目均为flex: auto、flex: initial或flex: none,则在项目尺寸决定后,剩余的正空间会被平分给是flex: auto的项目。
flex: none与flex: 0 0 auto相同。根据width/height属性决定元素的尺寸,但是完全不可伸缩。其效果与initial类似,但即使在空间不够而溢出的情况下,伸缩项目也不能收缩。
flex:
align-self则用来在单独的伸缩项目上覆写默认的对齐方式。(对于匿名伸缩项目,align-self的值永远与其关联的伸缩容器的align-items的值相同。)
.item { align-self: auto | flex-start | flex-end | center | baseline | stretch;}
若伸缩项目的任一个侧轴上的外边距为auto,则align-self没有效果。
如果align-self的值为auto,则其计算值为元素的父元素的align-items值,如果该元素没有父元素,则计算值为stretch。对齐属性值的定义如下:
注意:如果伸缩伸缩的高度有限制,此可能导致伸缩项目的内容溢出该项目。
flex 的行为是让盒子尽可能地填满一行,所以使用 flex 我们就有了让元素充满行的保障。但设置了 flex 的元素对 width 就不太买账了,于是要使用比它更严肃的 max-width 和 min-width 来设置。下面是效果:
在宽度足够时一行会显示更多元素,并且在确保元素尺寸在限制范围内的情况下尽可能地填满一行。下面是代码:
<style> ul { border:1px solid red; padding:0px; display:flex; list-style:none; flex-flow:row wrap; } ul li { flex:1; min-width:50px; max-width:80px; height:50px; background:#CCC; margin:4px; }</style><ul><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul>