flex布局整理
Flex布局,也就是Flexbox的俗称,是CSS提供的用于布局的一套新属性。这一套标准是由W3C于2009年提出并制定的。
———————————————————————————————————————————————————————————————
Flex相比其他传统的布局,能更简便、更完整,并且是响应式地实现各种布局(框架不能算里面,例如bootstrap,它可以响应式,并且可以自适应),
这里稍微扩充一下:
自适应网站是使用不同设备浏览时呈现不同的网页,网页内容及版式风格或相似或完全不同,和PC端属于不同的网站模板,数据库内容或相同一致,或独立不同,目的在于为了符合访客的浏览;
而响应式网站是使用不同的设备浏览网站时,网站样式风格、内容和网址都是完全一样的,PC端和移动端属于同一个网站模板,数据库完全一致,也非常符合搜索引擎的优化规则。
简而言之:自适应是网站模板不同,使用不同设备浏览时呈现不同的网页;而响应式是同一个网站模板,使用不同的设备时呈现相同的页面(只是大小的缩放)。
好了,回到正题,假如你碰到了行内块、浮动和表格格式让你觉得无从下手,那么Flex布局很适合你;而且从现在看来,由于IE10以上都能兼容Flex(IE10部分兼容),Flex布局不仅仅是应用于移动端了,可以更广泛的应用于PC端。
Flex布局这套属性它包含了针对容器(弹性容器,也就是父元素盒子)和针对其直接子元素(弹性项,也就是子元素)两类属性。Flex属性它可以控制弹性项的如下方面:
- 大小,基于内容和可用空间
- 流动方向,水平还是垂直,正向还是反向
- 两个轴向上的对齐与分布
- 顺序,与源代码中的顺序无关。
比如,在阮一峰的博客中就说到,通过一般的传统布局垂直居中就不容易实现。那么Flex布局属性有哪些??
已知的常用属性有flex-direction、flex-wrap、align-items、justify-content。
所有的属性有
- 侧轴类:align-content、align-items、align-self
- 主轴类:justify-content
- 位置类:order
- 其余类:flex、flex-basis、flex-direction、flex-flow、flex-grow、flex-shrink、flex-wrap,其中flex和flex-flow可以将几个属性合一起简写。
align-self、order、flex、flex-basis、flex-grow、flex-shrink都是给弹性项的(子元素),
剩下来的flex-direction、flex-grow、flex-flow、flex-wrap、align-content、align-items、justify-content就是给弹性容器的(父盒子)。
当使用display:flex开启Flex布局之后,子元素的float、clear和vertical-align属性将失效,此时可以无所顾虑的设置子元素的宽高,并不用在意是否存在垂直方向内外边距合并的风险。(注:行内元素也可以开启flex,使用display: inline-flex即可。)
当flex布局开启后,如果其他属性什么都不写,默认的flex属性为
flex:0 1 auto;
这里的三项,第一项是指flex-grow,第二项是指flex-shrink,第三项是指flex-basis。
flex-grow 指的是 弹性项的放大比例,0为不放大
flex-shrink 指的是弹性项的缩小比例,1为所有弹性项等比例缩小
flex-basis 指的是在主轴方向上,经过修正之前的“首选”大小(width 或 height)
··········································这里是分割线··········································
【图1】
可以看到box1我写了宽和高,box2我只写了宽,box3我只写了高。
在效果呈现中,box1和box2展现了出来,而box3并没有。
因为在Flex布局下,默认 弹性项不放大;超出弹性盒子等比例收缩;以及在主轴方向上,经过修正之前的“首选”大小为0,也就是在没有设置flex-basis的时候,会按元素默认设置的宽和高显示。
- box1 展现了出来,因为我给定了宽和高;
- box2 展现了出来,因为我给了宽,但是没有高它仍然显示出来了。这是因为如果弹性项没有设置高度或设为auto,那么它的父元素的align-items的属性为默认的stretch,也就是会沿着侧轴拉伸到至父元素的高度或者宽度,
如果我给父元素盒子设置align-item属性,只要不设置为stretch,那么box2一定会消失在屏幕上。
然后其实align-items的属性,和flex-direction的属性其实也是相对的。 - box3 没有展现, 因为在没有设置flex-direction的情况下,默认是水平方向flex,也就是flex-direction的默认值为row,所以自然它是不会显示出来的。
上面说到align-items和flex-direction的属性是相对的:在Flex布局中,主轴和侧轴是相对的概念,一个方向为主轴,那么另一个方向就为侧轴。
当未设置flex-direction的时候,flex-direction默认为row,此时主轴是水平轴,侧轴是垂直轴;但当flex-direction设置为column时,此时主轴为垂直轴,侧轴为则变为了水平轴。
在flex-direction设置改为column时,效果会截然不同。
在这里说一下,flex-direction的属性总共有4个,分别为:
row(默认值):主轴为水平方向,起点在左端。
column:主轴为垂直方向,起点在上沿。
row-reverse:主轴为水平方向,起点在右端。(从右往左排)
column-reverse:主轴为垂直方向,起点在下沿。(从下往上排)
【图2】
此时的情况下:
box1和box3展现了出来,而box2却没有。这是因为在flex-direction设置改为column后,垂直轴变成主轴,而水平轴成了侧轴,align-items是控制侧轴的属性,如果没有写,默认为stretch。
因为box2我只给了宽,没有给高度。此时水平轴为侧轴,在执行了侧轴方向align-items默认的stretch属性之后,还是没有高。 那么现在已经经过flex布局的调整,它还是只有宽,所以是无法显示出来的。
而box3我只给了高,此时水平轴为侧轴,在执行了侧轴方向align-items默认的stretch属性之后,它的宽度为弹性盒子(父元素)的宽度,因为box3我是给了高度的。在经过flex布局的调整后,它有宽有高,所以可以正常显示。
那么尝试加上align-items属性,效果如图3:
【图3】
可以看到,box3也消失不见了,原理是和图1一样的。
align-items的常用属性:
我不是特别明白start、end有什么作用,如果有知道的可以告诉我。
下面说justify-content,它是控制主轴方向的对齐方式,之前已经铺垫了相关知识,那么直接上代码
【图4】
没有问题,现在加上了justify-content,水平轴是主轴,因为align-items属性默认为stretch,所以box1,box2都能显示,而且居中,
box3虽然在侧轴方向上拉伸,但是我只给了高,相当于重复了,所以不会显示。
那么我们将主轴从水平轴更换至垂直轴,其他代码不变。
flex-direction: column;
这里不给图,也能知道结果。
结果就是:
box1,box3显示,box2不显示,效果和图2一模一样,justify-content和默认的布局方式重叠了。
但是如果给父盒子设置高度,便可以出现设置justify-conteng之后的效果(因为在之前父盒子box是没有高度的,是被里面的弹性项给撑开的)
效果如图5:
【图5】
这里是justify-content的常用属性:
讲了flex-direction、flex、align-items、justify-content,稍微提一下align-self属性(jusitfy-self属性有,但是并没有实装),align-self属性是让它自己和侧轴方向的其他弹性项排列方式不同,
其他弹性项设置为center,它自己可以被单独设置为flex-start,就是这个意思,如下图6:
【图6】
下面讲flex-wrap属性,我们回到图1的代码,在上面给他多添加几个弹性项:如图7,
【图7】
在弹性项成倍增加的情况下,因为Flex布局的特性(只开启Flex的情况下,flex-shrink的默认属性为1,这样使得所有弹性项可以等比例缩放,而且flex-wrap的默认属性是no-wrap),使得弹性项还是能稳稳当当的在一行里被装下。
那么如果我们不想这样,就可以加上这一行代码,
flex-wrap:wrap;
强制使其换行,虽然flex-shrink的默认属性仍然为1,但是因为强制换行,也就不会缩放了,会显示为默认的大小,如图8:
【图8】
看一下flex-wrap的所有属性:
wrap-reverse说明:
flex-wrap可以和flex-direction组合,两者能简写为flex-flow,
flex-flow: row wrap;
顺序没有要求。
这个flex-wrap属性比较简单,就介绍到这里。
这里由换行引出来了一个,平时不太会用到,但我自己觉得挺有用的一个属性,align-content。
align-content这个属性决定了侧轴方向上,弹性项的排列方式,这里非常容易出错,有一个前提,必须要在侧轴方向上,有多根轴线,如果在侧轴方向上只有一根轴线,align-content是不会起作用的。
换而言之,如果flex-wrap的属性不设置,让它默认,则此时使用align-content无效,因为弹性项都已经等比例缩小到可以容纳在一行内显示的大小。 ,轴线此时只有一根。
但如果我已经设置过flex-wrap的属性,弹性项大小还是默认的大小,使得弹性项被强制换行,不在都呆在一行中,那么此时,轴线就大于了1条,一旦大于1,align-content就可以生效。
看代码:
【图9】
MDN上的 align-content演示,往下拉能选择各种情况。
还有一点,非常容易出错的,当你把flex-direction改为column,此时垂直轴为主轴,乍一看看上去,排了好多行,那我是不是就能用align-content了?不对,只是视觉上的错觉而已,因为主轴改变,此时水平轴
成了侧轴,观察观察水平轴吧,不就孤零零的一根轴线么,肯定是无法使align-content生效的。
align-content的常用值:
order属性,这个属性是给弹性项设置的,如果你需要切换弹性项的顺序,但是又不想动html元素位置,就可以使用它。
order属性默认为0,数值越小,排列越靠前。order属性可以设置为负数。
还剩flex-basis,和flex-shrink没讲,用的非常少,就先略过了。