超详细弹性布局解析!一篇文章让你彻底掌握Flexbox
目录弹性容器主轴属性交叉轴属性弹性项目属性属性详解orderflex-growflex-shrinkflex-basisflexalign-self弹性布局是CSS引进的一种布局模型可以控制子元素的排列方向对齐方式空间分配和换行全称为Flexible Box,其核心概念有四个分别为设置弹性容器flex contaniner弹性项目flex item主轴main axis和交叉轴cross axis接下来将详细讲解弹性容器和弹性项目的属性弹性容器首先什么是弹性容器呢简单来说任何一个元素只要设置了display:flex或display:inline-flex那么这个元素就变成了弹性容器弹性容器的直接子元素会变成弹性项目那display:flex和display:inline-flex又是什么呢display:flex块级元素独占一行display:inline-flex内联元素会于其他内容同行且宽度由内容撑开主轴属性弹性容器内部有两根看不见的轴这两根轴是掌握所有容器属性的关键主轴(main axis)是弹性项目主要排列的方向水平方向默认为从左到右有起点main start和终点main end还有一根是交叉轴cross axis是垂直方向默认为从上到下同样的交叉轴也有起点cross start和终点cross end,接下来我们要学习的是主轴的相关属性属性可选值默认值作用displayflex(块级弹性容器)inline-flex(内联弹性容器)----开启弹性布局flex-direcionrow(从左到右)row-reverse(从右到左)coulm(从上到下)coulm-revers(从下到上)row设置主轴反向flex-wrapnowrap(不换行)wrap(换行)wrap-revers(反向换行)nowrap控制是否换行flex-flow方向换行例如 row wraprow nowrap同时设置方向和换行justify-contentflex-start(起始对齐)flex-end(末尾对齐)center(居中对齐)space-evenly(均匀对齐)space-around(环绕对齐)space-between(两端对齐)flex-start设置项目的对齐方式column-gap长度值0设置主轴方向上的间距看完了属性那么就要用代码来实验一下了!DOCTYPE html html langzh-CN head meta charsetUTF-8 title弹性容器主轴/title style /* 主轴属性演示 */ .a { display: flex; /* 开启块级弹性容器 */ flex-direction: row; /* 主轴方向水平从左到右 */ flex-wrap: wrap; /* 允许换行宽度不足时换行 */ justify-content: space-evenly; /* 主轴对齐均匀间距 */ gap: 20px 15px; /* 行间距20px交叉轴列间距15px主轴 */ background: #e0f7fa; /* 设置背景颜色 */ border: 2px solid #00796b; /* 设置边框 */ padding: 10px; /* 内边距 */ width: 350px; /* 限制宽度使换行效果可见 */ } .b { background: #ffb74d; padding: 10px 20px; width: 80px; /* 固定宽度一行最多放3个 */ text-align: center; } /style /head body div classa div classb1/div div classb2/div div classb3/div div classb4/div /div /body /html交叉轴属性交叉轴的属性和主轴的其实大差不差其中有一个值是可以同时设置主轴和交叉轴的间距那就是gap,可以在后面设置两个值同时设置交叉轴方向的行间距和主轴方向的列间距格式为gap行间距 列间距接下来看看交叉轴的属性设置吧属性可选值默认值作用align-itemsstretch(拉伸)flex-start(起始对齐)flex-end(末尾对齐)centrer(居中对齐)baseline(基线对齐)stretdh单行项目在交叉轴上的对齐方式align-contentstretch(拉伸)flex-start(起始对齐)flex-end(末尾对齐)centrer(居中对齐)space-between(两端对齐)space-around(环绕对齐)stretch多行项目在交叉轴上的对齐方式主轴上需要有flex-wrapwrap并产生多行row-gap长度值设置交叉轴方向上的项目间距!DOCTYPE html html langzh-CN head meta charsetUTF-8 title弹性容器交叉轴/title style .a { display: flex; flex-direction: row; /* 主轴水平交叉轴垂直 */ align-items: center; /* 交叉轴对齐居中对齐垂直居中 */ width: 300px; /*宽度*/ height: 150px; /* 高度*/ background: #ced2e9; border: 2px solid #1229ac; gap: 10px; padding: 10px; margin-bottom:20px ; } .a .e{ background: #afbaf0; padding: 10px; color: white; } /* 不同高度项目突出交叉轴效果 */ .a .b:first-child { height: 40px; } .a .b:nth-child(2) { height: 60px; } .a .b:last-child { height: 80px; } .b { display: flex; flex-direction: row; flex-wrap: wrap; /* 必须换行才能产生多行 */ align-content: center; /* 多行整体在交叉轴居中 */ height: 250px; /* 固定高度让多行居中效果明显 */ background: #fff3e0; border: 2px solid #ff9800; row-gap: 20px; /* 单独设置交叉轴方向的行间距 */ column-gap: 10px; /* 主轴列间距 */ padding: 10px; width: 300px; } .b .e { background: #81c784; width: 80px; height: 40px; display: flex; align-items: center; justify-content: center; } /style /head body div classa div classe999/div div classe888/div div classe666/div /div div classb div classe1/div div classe2/div div classe3/div div classe4/div div classe5/div div classe6/div /div /body /html弹性项目弹性项目的属性是写在弹性容器里面的子元素上的可以用来单独控制每个项目来看看弹性项目的属性吧属性属性可选值默认值作用order整数可以是负数0设置数字来决定排列顺序数字越大越靠后flex-grow非负数0剩余空间的放大比例0代表不放大1代表所有元素一起平分剩余空间flex-shrink非负数1空间不足时的缩小比例0代表不缩小1代表所有元素一起按比例缩小flex-basis长度/auto/contentauto分配剩余空间前的初始空间flex复合属性flex-growflex-shinkflex-basis0 1 auto简写同时设置上面三个属性常用的flex:1表示 1 1 0%align-selfauto(继承父级)stretch(拉伸)flex-start(起始对齐)flex-end(末尾对齐)center(居中对齐)baseline(基线对齐)auto覆盖容器的属性设置可以单独对元素进行设置属性详解其实弹性容器的属性还比较通俗易懂但是这个弹性项目的却叫人眼花缭乱感觉作用晦涩难懂其实我也有这种困扰所以我单独对弹性项目的属性去查阅了资料整理了一下把各种专业名词拆成容易理解的大白话下面来看看我的详细讲解吧order这个属性简单来说就是让已经拍好的队形进行重排我们都知道在默认情况下元素的顺序是按照写代码的顺序从上到下来排列的但是order可以改变这个顺序元素在设置了这个属性后会按照设置的数字来排列数字越小排的越靠前而且是可以设置负数的而元素的默认值是0顺序按上下来排如果在几个元素中单独给一个元素设置order的值为负数那么这个元素就会排到最前面单独设置一个元素的值为大于0 的数那么这个元素无论处于代码中的哪个地方最终的排序他都会处于最后面!DOCTYPE html html langen head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleorder/title style .a{ display: flex; gap: 10px; background-color: aqua; } #c{order:1} #d{order:-1} /style /head body div classa div idb111/div div idc222/div div idd333/div /div /body /htmlflex-grow这个属性俗称吃剩饭当容器内还有多余的空间时设置这个属性的值超过0元素就会按比例瓜分剩下的多余空间具体分的是宽度还是高度那就要看主轴的方向了。那选中就有人要问了这个按比例分配具体是怎么分呢打个比方主轴的方向是水平那么分配的就是宽度此时宽度为500px前面不参与分配的元素已经占了200px还剩300px后面有两个元素要参与分配A设置为flex-grow:1B为flex-grow:2那A的宽度为300/(12)*1100pxB为300/(12)*2200px,也就是说参与分配的元素分配后最终的宽度计算公式为{剩余空间/(所有参与分配的元素的flex-grow总和)*(自己的flex-grow值)}。如果主轴的方向是垂直方向流程也不变主轴朝哪边他就分哪边。但是有一个点要注意那就是元素的内边距、外边距、边框和gap属性都会间接影响到分配的空间当设置了这些属性时会先扣除这些属性所占用的空间剩下的再进行分配!DOCTYPE html html langen head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleflex-grow/title style .a{ display: flex; width: 500px; height: 500px; gap: 10px; background-color: aqua; } #b{ width: 200px; background-color: rgb(224, 213, 2) } #c{ flex-grow: 1; background-color: rgb(138, 231, 7); } #d{ flex-grow: 2; background-color: rgb(247, 36, 3); } /style /head body div classa div idb111/div div idc222/div div idd333/div /div /body /htmlflex-shrink既然有吃剩饭那相反的也会有吃不饱只能挨饿缩小自己容器有过大的时候也会有偏小的时候那容器都不够大了里面装的满满的元素为了不被挤出去也只能跟着缩小和上面的flex-drow差不多都是按比例来缩小而为了防止元素挤出容器这个属性默认值是1也就是默认按比例缩小当然也可以设置为flex-shrink:0,这样的话被设置的元素就不会因为容器的空间不足而按比例缩小虽然缩小也是按比例来的但是和放大不一样缩小按的是权重比例。所有元素都会按一个加权比例来分担不足空间先用容器的宽度减去所有元素相加的总宽度得到不足的空间然后每个元素要用自己的flex-shrink值乘以自身的宽度再把所有元素的权重相加得到总权重之后用每个元素的自身的宽度除以总权重来得到缩小的权重比例最后用不足的空间乘以每个元素的缩小权重来得到需要缩小的宽度拿元素本身的宽度减去需要缩小的宽度就能得到最终的宽度看起来很复杂其实也确实挺复杂。我们来举个栗子一个容器是300pxA元素是200pxB元素是300px不足的空间是500-300200A元素的flex-shrink值是1B的值也是1那么A的权重是1*200200B的权重为1*300300总权重500A的缩小比例就是200/5000.4B的比例为300/5000.6可以算出A的最终宽度为200-200*0.4120pxB的宽度为200-300*0.6180px总结一下缩小的计算公式为{元素自身宽度-不足空间*元素权重/总权重元素最终宽度}!DOCTYPE html html langen head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleflex-shrink/title style .a{ display: flex; width: 300px; height: 300px; gap: 10px; background-color: aqua; } #c{ width: 200px; flex-shrink: 1; background-color: rgb(138, 231, 7); } #d{ width: 300px; flex-shrink: 1; background-color: rgb(247, 36, 3); } /style /head body div classa div idc222/div div idd333/div /div /body /htmlflex-basis相比于上面两个这个属性属于特别简单的了flex-basis属性就是弹性项目再分配剩余空间之前的初始尺寸该属性可以定义的值有四个分别是auto意思是自动设置了这个元素会想查找自己的宽高设置如果没有设置宽高的话那么该元素的尺寸则由内容直接撑开conter为内容尺寸会直接根据内容自动计算尺寸如果设置了宽高会被直接忽略掉但是兼容性较晚反倒不如auto常用长度直接输入长度50px20rem50%等输入的是百分比的话则会相对于父容器尺寸0强制元素初始尺寸为0完全依赖剩余空间分配(flex-grow);flex这是一个简写相当于同时去定义flex-grow,flex-shrink,flex-basis这三个属性最常用的是flex:1这等同于flex-grow:1,flex-shrink:1,flex-basis:0%,也就是可大可小初始尺寸为0完全根据剩余的空间来进行分配flex:auto相当于1 1 auto同样可大可小初始尺寸由内容来决定flex:none相当于0 0 auto这个既不长大也不缩小完全由内容决定尺寸除了这几个还有就是手动指定根据flex-grow,flex-shrink,flex-basis的位置来输入值用这个可以使代码看起来简洁很多写起来也方便align-self这个属性比较横通俗点就是我行我素父容器用align-items来控制所以头项目再交叉轴上的对齐方式用这个属性就可以脱离父容器的掌控优先级凌驾于容器之上用来单独控制元素的对齐