flex
全称 Flexible Box
模型,顾名思义就是灵便的盒子,不过个别都叫弹性盒子,所有 PC
端及手机端古代浏览器都反对,所以不必放心它的兼容性,有了这玩意,妈妈再也不必放心咱们的布局。
先简略介绍一下,要应用 flex
布局,须要先给一个容器元素设置 display:flex
让它变成 flex
容器,而后其所有的间接子元素就变成 flex
子元素了,在 flex
里存在两根轴,叫主轴和穿插轴,相互垂直,主轴默认程度,flex
子元素默认会沿主轴排列,能够管制 flex
子元素在主轴上伸缩,主轴方向能够设置,相干的 css
属性分为两类,一类是给 flex
容器设置的,一类是给 flex
子元素设置的,本文在介绍一些典型场景实现的同时也会顺带解说局部属性,当然更具体的内容能够浏览 MDN 上的教程。
单列布局
单列布局是最简略的布局了,从上到下排列,如图:
能够应用三个 div
来示意头、内容和尾,而后把外层容器,即 body
设为 flex
容器,因为 flex
默认的主轴是程度的,咱们须要把它设置为垂直的,而后再设置元素在穿插轴居中即可:
当然更常见的状况是内容高度不确定,这样咱们往往会心愿在内容高度不满一屏时底部内容挨着底边,超过一屏时跟在最初,这首先须要容器元素有固定的高度,否则何来底边,咱们能够把 html
和body
的高度都设为 100%
,而后去掉给content
元素设置的高度,并给它增加一个带高度的子元素:
接下来须要应用到 flex-grow
属性,这个是 flex
子元素上的属性,用来管制容器还有空间残余时,flex
子元素怎么进行扩大,默认值是0
,也就是不扩大,子元素会显示为它们默认的大小,这个所谓的默认大小分几种状况:
1. 如果子元素的另一个属性 flex-basis
设置了不为 auto
的具体数值,那么无论元素有没有设置具体大小都显示为该属性定义的尺寸;
2. 如果子元素的 flex-basis
的值为auto
(默认值),那么如果元素设置了具体的大小那么显示为该设置的尺寸;
3. 否则取决于元素内容的 max-content
大小;
当 flex-grow
设为一个负数时,那么各个子元素会按设置的份数来按比例调配残余可用的空间,比方残余空间为90px
,三个子元素该属性值都设为1
,那么每个元素将在原来大小的根底上加上90/3=30px
。
根据上述原理,咱们只须要给 content
元素的 flex-grow
属性设为 1
即可,其余都是 0
,所以残余空间将全给content
元素:
这样内容有余时底部就能够挨着底边了,然而当内容过多,超过一屏时:
能够看到头和尾都没了,这是因为 flex-shrink
的起因,这个也是 flex
子元素上的属性,用来管制当子元素的尺寸之和曾经超过容器了要怎么膨胀元素,默认值为1
,就是按比例减去要膨胀的空间,实践上是这样,但实际上并没有这么简略,接下来简略测试一下:
容器元素 body
为800px
高,上中下高度别离为 100+1000+100=1200px
,依据1:1:1
的flex-shrink
计算总权重为1*100+1*1000+1*100=1200
,子元素总高度超过容器400px
,这多出的要按的比例从各自高度中减去,具体为:
(400*1*100)/1200=33.33px
(400*1*1000)/1200=333.33px
(400*1*100)/1200=33.33px
,也就是别离都减去上述值,减完后实践上各自的高度变成了66.67px、666.67.67px、66.67px
,然而实际上:
能够看到头和尾都变成了 0
,内容高度没有变,这是为啥呢?下面咱们提到了max-content
,同样,这里对应着min-content
的概念,尽管失常来说应该变成咱们计算出的尺寸才对,然而缩小到元素内容的 min-content
后它就不会再变小了,content
元素有个高度为 1000
的子元素,这个高度就是它的 min-content
,所以它不会放大,它一个元素就比容器元素高了,再加上头和尾因为都没有内容,所以尽管实践上它们不是为0
的,然而为了更好的显示成果,浏览器就间接把它们缩小到 0
了,咱们能够轻易给头和尾加一点文字,文字的高度就会变成它们的min-content
,它们的高度也就不会变成0
:
所以这就意味着不要想着去准确计算,把它交给浏览器,浏览器会给你以最好的形式出现。
那么解决头和尾不要隐没的问题很简略,能够给它们也加个固定高度的子元素,然而最简略的办法是把它们的 flex-shrink
设为0
,也就是不膨胀:
这样就实现咱们的需要了。
经典导航栏
如图所示是一个经典的网站导航栏的布局,logo
和导航在左,用户信息在右,不必 flex
可能会应用浮动,上图应用浮动还好,然而如果左边是两个块,那么左边浮动的元素的显示程序和书写程序要不统一才行,或者再用一个元素包裹一下,应用 flex
则没有这种懊恼。
该场景能够应用一个容器来包裹右边的 logo
和导航,再设置 justify-content:space-between
来实现,然而有个小技巧能够不必这个包裹元素,就是利用 margin
的auto
值,回顾一下咱们以前程度居中都是怎么做的,是不是这样 margin:0 auto
,margin-left
和margin-right
的默认值是 0
,如果设置为auto
,将会依据残余可用空间来计算,这也是为什么能程度居中,因为左右都想尽量多,那么就只能平分了,对于本示例,咱们只给用户名flex
子元素设置margin-left:auto
,那么残余空间将全副给它,也就相当于把用户块挤到左边去了:
隔行穿插显示
有时候为了不让布局太枯燥,即便一个列表是同类数据,展现上也会做成上述隔行穿插的款式,这个应用 flex
能够轻松的做到,给 2n
的行设置 flex-direction: row-reverse
即可让偶数行的主轴方向由默认的从左向右变成从右向左:
此外也能够应用 order
属性,这个属性能够让 flex
子元素按 order
的数值大小来排序显示,咱们能够默认右边的设为2
,左边的设为3
,而后在偶数行再给左边的设为1
,天然就跑到后面去了:
网格布局
此网格非 grid
布局,尽管网格列表用 grid
是最好的,然而本文的配角是flex
,假如咱们要实现上面这样一个列表:
上述列表对 flex
来说是不善于的,因为要带间距,所以不能简略的把子元素宽度设为25%
,否则再加上外边距,一行必定显示不下四个,那你可能会想,那我宽度就少一点好了,比方设为20%
,而后容许扩大,即flex-grow:1
,那样不就能够把减去子元素宽度及外边距还剩下的空间再还给子元素了吗,试试看:
能够看到后面一切正常,然而最初一行因为只有一个元素,且设置了容许扩大,所以它被拉满整行了,这种成果显然不是咱们要的。
其实咱们能够应用内边距来做间距,设置一下子元素的 box-sizing:border-box
,让内边距蕴含在宽度内,这样就能够释怀的把子元素的宽度设为25%
了,当然这样的毛病是外面得再嵌套一个元素用来作为理论的内容容器。
圣杯布局
所谓圣杯布局如上所示,头尾高度固定,宽度占满,两头的内容局部分为三列,两侧宽度固定,高度占满,两头的内容局部随着浏览器宽度变动,其实就是咱们下面讲过的【单列布局】的两头局部变成三列而已,实现齐全没有啥特地的,以【单列布局】为根底,给 content
增加三个子元素,两侧定宽,并且不容许膨胀,两头容许扩大即可:
垂直居中
不晓得各位最开始用 flex
是为什么,反正笔者就是冲着垂直居中去的,用它切实是太简略了,之前还思考是不是定高呀,用什么定位呀,用 flex
就是两步,一让父元素变成弹性盒子,二设置穿插轴的元素排布形式为居中就完事了:
如果还须要程度居中的话就再给容器元素设置主轴的排列形式为 justify-content:center
,当初连让文字居中我都是用flex
,有情的摈弃了text-align
和line-height
。
高度主动对齐
有些时候同一列的元素为了好看咱们心愿他们的高度是一样的,如果内容固定不变当然能够间接写死高度,但如果可变的话就不能写死了:
这个场景应用 flex
齐全不须要额定设置什么属性,只有给容器元素设置 display:flex
即可,因为 flex
容器有个属性 align-items
,用来设置flex
子元素在穿插轴上如何对齐,默认值为 stretch
,即如果flex
子元素未设置高度,那么将占满整个容器的高度,因为咱们并没有给容器设置高度,所以容器的高度就是所有 flex
子元素里最大的高度。
小结
本文以题目党的名义总结了局部常见布局应用 flex
的实现,要灵便应用 flex
还是须要了解它的一些属性的意义,此外也须要晓得 flex
的边界在哪,哪些是它不善于的。
本文总结的难免会有不全,或者有更好的实现,欢送探讨。