flex 布局 初次接触这个好使又不是特别好用的布局方法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了flex 布局 初次接触这个好使又不是特别好用的布局方法相关的知识,希望对你有一定的参考价值。
刚开始学前端的童鞋们应该也是一样先学习的table然后再学习了盒子模型,感觉终于学会了简单的网页布局,使用各种display,float,position绞尽脑汁给页面布局成自己想要的页面样式,然而,当自己把页面放缩时。。。。画风就莫名其妙的变了,没错 ,就是变了,变得很乱很丑,再把网页放到手机上:卧槽这是哪个战斗力五颗渣的家伙写的啊,整个页面一坨一坨的堆积在一起。
然后就钻研js响应式布局,写着写着,哎呀我去,这是哪一个的宽啊,这是哪一个元素的高啊,这个比例等下设置为多少,跟上一个需不需要一样,会不会再放缩这个比例又会排乱,一些列计算之后,终于,写出了一个满意的响应式布局,再看看自己的代码,写了好多有木有。
这时CSS3里的flex布局方法就显得简单易用,大手一敲,啪啪啪,一行代码,自适应问题就解决了,不用float,不用position,不用JS去计算设置样式,麻麻再也不用担心我敲键盘时摔鼠标了。
当然了,对于我这样刚刚学了一点flex布局还没有太多实践运用的小菜鸟,随便布个局,就得绕着主轴交叉轴转半天,实在不行还得动手画,运用起来还真是闲的不是特好用。可能以后用多了就好用了。
好了,题外话不扯太多了,进入正题。首先看一下什么是flex布局的基本概念(概念参考引用来自于菜鸟教程)
1:容器:简单来说就是包含着要根据放缩页面大小自动布局元素的那个盒子,可以是body也可以是任何其他盒模型的父级元素,
再简单来书就是样式设置了display:flex的元素,这时你会发现 这个元素的宽默认可以填满整个页面。而且子元素再设置子元素的float、clear和vertical-align属性也是无效的。
2:项目:包含在容器内的所有成员,都是这个容器的项目,当然了项目同时也可以设置为display:flex做嵌套包含另一层项目。这样布局就可以根据你的不同需要,设置出不同的样式来。
3:轴 ——这里有两条轴,一条是样式里设置的主轴(不设置的话默认是水平向右方向),另一条就是与主轴垂直的交叉轴,主轴的起始位置(即主轴与边框的交叉点)称为main start,结束位置main end;交叉轴的起始位置cross start,结束位置叫做cross end。项目默认沿主轴排列。还有两个本文暂时用不到的概念:单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。
4:容器的属性:
①flex-direction主轴的方向(也就是默认项目排列的方向)取值有以下四个
a.默认row 水平方向,起点在左端 b. row-reverse 水平方向,起点在右端 c. column垂直方向 起点在上端 d.column-reverse垂直方向 起点在下端
②flex-wrap 是否换行,取值有以下三个
a.nowrap:默认值不换行 b.wrap:换行 按交叉轴的方向一行一行往下排 c. wrap-reverse:换行 按与交叉轴相反的方,向倒着一行一行的排列
③flex-flow 这是flex-direction和flex-wrap的简写 容器可以同时设置时建议使用此元素,否则,如果是给一类容器设置时,建议分开使用lex-direction和flex-wrap
④justify-content 项目在主轴方向的对齐方式 取值如下
a. flex-start 延主轴起始端对齐(类似于文本的左对齐) b.flex-end 延主轴结束端对齐(类似于文本右对齐) c.center 延主轴中点对齐(类似于文本的居中) d space-between 延主轴两端对齐项目两端距离相等 e. space-around 每个项目两侧的间隔相等。(类似于盒子模型的margin)项目之间的间隔比项目与边框的间隔大一倍,
⑤align-items 项目在交叉轴方向的对齐方式
a.flex-start 延交叉轴起始端对齐(类似于文本的顶端对齐) b.flex-end 延交叉点结束端对齐(类似于文本的低端对齐) c. center延交叉轴中点对齐(类似于文本的垂直居中)d. stretch 如果项目没有指定高度或者设置的auto,项目将会在交叉轴方向占满容器的高度 e. baseline 项目的第一行文字基线对齐
⑥align-content 多轴线时轴线的对齐方式
a.flex-start 与交叉轴起始端对齐 b.flex-end与交叉轴终点对齐 c. center与交叉轴中点对齐 d space-between 与交叉轴两端对齐,轴线之间的间隔平均分布 e. space-around 每根轴线两侧的间隔都相等,轴线之间的间隔比轴线与边框的间隔大一倍(类似于盒子模型的margin)项目之间的间隔比项目与边框的间隔大一倍 f.stretch(默认值):轴线占满整个交叉轴
5:项目的属性:
①order 定义项目的排列顺序。数值越小,排列越靠前,默认为0 可以以此改变项目在容器中的排列顺序
②flex-grow 定义项目的放大比例,默认为0,此时计时容存在剩余空间也不会放大。如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为3,其他项目都为2,则前者占据的剩余空间将是其他项的1.5倍。以此单独给项目设置,让不同元素在页面放缩时产生不同的展示效果。
③flex-shrink 项目的缩小比例,默认为1,即如果空间不足,该项目将缩小,设置为0时,不会因为空间不足二缩小。另外设置负值无效。
④flex-basis 在分配多余空间之前,项目占据的主轴空间(main size)。浏览器会根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。结构嵌套时会经常用到,否则被嵌套在内的容器大小只能根据其项目大小往外撑开。
⑤flex 是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选
⑥align-self 属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。
终于把基本概念敲完了,来,趁刚看完的童鞋还没睡着做点有趣的。上图,麻将来了
接下来简单介绍几个,希望能达到抛砖引玉的效果。
先是一饼 首先是html部分
<section class="box1"> <div class="point"></div> </section>
下边是css部分
.box1{ justify-content:center; /*项目在主轴方向的对齐方式*/ align-items:center; /*项目延交叉轴的对齐方式*/ }
解析一下:大饼是在正中间的,即项目在容器的主轴和交叉轴的对齐位置均是中间 对应设置居中即可。
接下来升级一下,二饼
<section class="box2"> <div class="point"></div> <div class="point"></div> </section>
可以看到这个二饼是竖着在那里的 直接换行的话,你会发现这俩黑蛋蛋是占不满一行的因此也不会换行,这时候就只能强行让他换行了,让他的主轴方向换成竖着的,这时,就能得到两个竖着的饼了,接下来就是调整到中间位置了,此时主轴方向已经换了,水平居中相当于在项目的交叉轴上居中,getit√接下来就是把这连个竖着在中间的蛋蛋给分开了,此时垂直方向分开相当于在项目的主轴让项目两端对齐,可以设置space-between和space-around都能达到效果,就看对间距的具体需求了。
.box2{ flex-direction:column; /*主轴的方向*/ justify-content: space-around; /*在主轴方向的对齐方式*/ align-items: center; /*在交叉轴的对齐方式*/ }
接下来是三饼,第二个在屏幕中间,第三个在屏幕的右下角,一条笔直得斜线将容器分成两瓣。通过对容器的属性设置这个就有点问题了,你会发现,what?这仨家伙怎么设置都是在一行的,跟糖葫芦串串一块粘着一样。怎么办呢,下面就要开始动用项目的属性了,对项目设置单独的对齐方式,可以通过其不同的对齐方式,达到画斜线折线的效果,来上代码。
<section class="box3"> <div class="point"></div> <div class="point"></div> <div class="point"></div> </section>
.box3{ justify-content: center; /*项目在主轴方向的对齐方式*/ } .box3 .point:nth-child(2){ align-self:center; /*项目在交叉轴的单独对齐方式 位置居中 这时你会发现第二个打黑点跑下边屏幕中间位置了 同理设置第三个 跑到最底部了
当然这里由于没有改变他们的主轴排序位置 因此他们在主轴的相对位置还是不变的 这样一条斜线就诞生了*/ } .box3 .point:last-child{ align-self:flex-end;
}
接下来是四饼了,一排两个,一排两个,咔咔咔,四个小圆点被早出来了,换行,额,画风有点诡异,你是不是画出了这样的四饼?
当然了,如果你设置的每个饼的宽高比例大于33.3%,这里不会出现这个问题,已经直接做好一个四饼出来了。但是,麻将里的饼就一饼的饼大,其他的饼都一样大,你在设置6789饼的时候再用之前的比例已经没办法在容器内包含完了,只能换宽高,但是再画出来的饼展示出来,放到在一张图上,有点怪怪的,打个麻将一会饼大一会小的。
接下来就还要用一样大的饼去画了,怎么画呢,既然换行换不出自己想要的结果,那直接让他们不再一行咯,分成两块之后,接下来就跟二饼差不多了,献上代码
<section class="box4"> <!-- 需要嵌套 不嵌套的话 会一行三个一行一个 没办法将第三个排到--> <div class="b4"> <div class="point"></div> <div class="point"></div> </div> <div class="b4"> <div class="point"></div> <div class="point"></div> </div> </section>
.box4{ flex-wrap: wrap; /*是否换行*/ /*justify-content:space-around;*/ /*这里是单独的两块 对项目内容起不到实际作用*/ align-content: space-around; /*多条轴线时 轴线的的对齐方式 两条轴线两端对齐*/ } .box4 .b4{ flex-basis: 100%;/*项目在主轴占据的空间*//*作为项目为填满容器 不设置此属性的话 占位没有打开 两个一排的点在一起*/ display: flex; /*是否换行*/ justify-content:space-around; /*项目在主轴方向的对齐方式*/ /*align-content: space-around;*/ /*多轴线时 轴线的对齐方式*/ }
这里嵌套是要注意几点:
一最外层容器设置给项目的样式对齐直接包含的子元素有效,嵌套的项目需要对被嵌套项目的容器设置;
二 嵌套的项目要做容器也要记得添加display:flex;这样才能在次元素上对其项目设置样式;
三:flex-basis: 项目在主轴上占据的空间 当此项目在嵌套中还要作为容器,此时不设置次属性,你会发现,这个元素的大小是随着子元素大小直接撑开的,但是没有办法设置两端对齐,因为这时子元素作为项目已经相当于顶着容器的边了,这时就要根据需要来设置在主轴上所占空间了。
剩下的直接把代码献上了,使用的不熟练,感觉代码有些冗余,命名是这次比较懒,也没有按照规范命名。有疑问或者更好的方法希望大家能共同交流哦。
<section class="box5"> <!-- 需要嵌套 不嵌套的话 会一行三个一行一个 没办法将第三个排到--> <div class="b5"> <div class="point"></div> <div class="point"></div> </div> <div class="b5"> <div class="point"></div> </div> <div class="b5"> <div class="point"></div> <div class="point"></div> </div> </section>
.box5{ /*flex-direction: column;*/ flex-wrap: wrap; /*justify-content:space-around;*/ /*项目在主轴的对齐方式 单独的块 不起实际作用 直接设置项目内部项目的位置*/ align-content: space-around; /*多轴线 轴线对齐 交叉轴方向*/ } .box5 .b5{ flex-basis: 100%; display: flex; justify-content: space-around; }
<section class="box6"> <div class="b6"> <div class="point"></div> <div class="point"></div> </div> <div class="b6"> <div class="p6"> <div class="point"></div> <div class="point"></div> </div> <div class="p6"> <div class="point"></div> <div class="point"></div> </div> </div> </section>
.box6{ flex-wrap: wrap; } .box6 .b6{ display:flex; flex-basis: 100%; height: 50%; flex-wrap:wrap; justify-content: center; /*主轴方向对齐方式*/ align-items: center; /*交叉轴方向 项目对齐方式*/ } .box6 .b6 .p6{ flex-basis:100%; display: flex; justify-content: center; }
<section class="box7"> <div class="b7"> <div class="point"></div> <div class="point"></div> <div class="point"></div> </div> <div class="b7"> <div class="p7"> <div class="point"></div> <div class="point"></div> </div> <div class="p7"> <div class="point"></div> <div class="point"></div> </div> </div> </section>
.box7{ flex-wrap: wrap; } .box7 .b7{ height: 50%; /*各占一半*/ flex-basis: 100%; /*宽占满*/ display: flex; flex-wrap: wrap; } .box7>.b7:first-child{ justify-content: center; /*居中一下 不让点挤着边框*/ } .box7>.b7:first-child>.point:nth-child(2){ align-self: center; } /*三个点变斜线方法*/ .box7>.b7:first-child>.point:last-child{ align-self: flex-end; } .box7>.b7:last-child{ justify-content: center; /*项目主轴方向居中即可 不用分开对齐了*/ }
<section class="box8"> <div class="point"></div> <div class="point"></div> <div class="point"></div> <div class="point"></div> <div class="point"></div> <div class="point"></div> <div class="point"></div> <div class="point"></div> </section>
.box8{ flex-flow: column wrap; justify-content:center; /*项目在主轴的对齐方式*/ align-content:center; /*轴线对在交叉轴的齐方式*/ }
<section class="box9"> <div class="point"></div> <div class="point"></div> <div class="point"></div> <div class="point"></div> <div class="point"></div> <div class="point"></div> <div class="point"></div> <div class="point"></div> <div class="point"></div> </section>
.box9{ flex-wrap:wrap; justify-content:center; /*项目在主轴方向对齐方式 居中*/ /*换行后有三条轴线*/ align-content: space-around; /*需要完全等距的话 可以分三块 每块高占三分之一 项目在主轴交叉轴居中就可以了*/ }
以上是关于flex 布局 初次接触这个好使又不是特别好用的布局方法的主要内容,如果未能解决你的问题,请参考以下文章