flex
一般来说 justify表示水平方向的样式设置;
align表示垂直方向的样式设置;
items表示全体元素的样式设置;
content表示整体布局的样式设置;
self表示元素自身的样式设置,其一定是应用在子元素上的。
因此,justify-content属性就表示整体布局的水平对齐设 置,align-items就表示全体元素的垂直对齐样式设置。
flex-shink是设置默认宽度
父容器属性,display:flex是基本,
-
开启了flex布局的元素叫做
flex container -
flex container里面的直接子元素叫做flex items(也就是开启了flex布局的盒子包裹的第一层子元素) -
如果display对应的值是flex的话,那么
flex container是以block-level的形式存在的,相当于是一个块级元素 -
如果display的值设置为
inline-flex的话,那么flex container是以inline-level的形式存在的,相当于是一个行内块元素
如果一个元素的父元素开启了flex布局;那么其子元素的display属性对自身的影响将会失效
justify-content
(flex-start;flex-end,center,space-around,space-between)沿着主轴方向排列
特点:
- flex items之间的距离相等
- flex items与main start、main end之间的距离等于flex items的距离
- space-around
特点:
- flex items之间的距离相等
- flex items与main start、main end之间的距离等于flex items的距离的一半
- space-between
- 与main start、main end两端对齐
- flex items之间的距离相等
- space-evenly
除了设置 justify-content:space-between以外,还可以直接操作子项的margin
max-width属性的优先级大于width属性的优先级,能够使尺寸从固定值变成相对值
失效原因
原因一:子元素设置了 margin:auto,注意:margin-left/right auto 这些是没问题的.
最常见错误
原因二:盒子本身伪类选择器.
以上是网上容易找到的,都没解决我的问题,最后我就把子类元素所有样式全部去掉一个一个实验,最后发现是子类元素设置了 flex:1 导致的.
原因三: 子元素设置单个盒模型占比导致justify-content失效.
flex-direction
(row(),column(垂直排列),row-reverse,column-reverse)决定主轴方向,横着排,还是速着排
- 注意:
flex-direction并不是直接改变flex items的排列顺序,他只是通过改变了主轴方向间接的改变了顺序
如果flex-direction属性的值是column 或是column-reverse,则flex子项的垂直对齐不应使用align-items属性控制,而是应该使用justify-content属性控制。
flex-wrap
(nowrap,wrap,wrap-reverse) 是否换行,flex的换行只有子元素有固定宽度才会换行
flex-flow
是flex-direcrion和flex-wrap的缩写,不分先后 flex-flow: wrap column
align-items
垂直对齐属性(flex-start;flex-end,center,baseline,stretch拉伸),设置子容器如何沿交叉轴排列
align-items决定了单行flex items在cross axis(交叉轴)上的对齐方式
注意:主轴只要是横向的,无论flex-direction设置的是row还是row-reverse,其交叉轴都是从上指向下的;
主轴只要是纵向的,无论flex-direction设置的是column还是column-reverse,其交叉轴都是从左指向右的;
也就是说:主轴可能会有四种,但是交叉轴只有两种
- stretch(默认值):当flex items在交叉轴方向上的size(指width或者height,由交叉轴方向确定,column时候是width,row的时候是height,注意父元素宽高不能是auto)为auto时,会自动拉伸至填充;但是如果
flex items的size并不是auto,那么产生的效果就和设置为flex-start一样
注意:触发条件为:父元素设置align-items的属性值为stretch,而子元素在交叉轴方向上的size设置为auto
- flex-start:与cross start对齐
- flex-end:与cross end对齐
- center:居中对齐
- baseline:与基准线对齐
至于baseline这个属性值,平时用的并不是很多,基准线可以认为是盒子里面文字的底线,基准线对齐就是让每个盒子文字的底线对齐
注意:align-items的默认值与justify-content的默认值不同,它并不是flex-start,而是stretch
align-self
align-self属性的各个属性值的表现和align-items属性的 各个属性值一样,区别在于align-self属性设置的是具体某个flex 子项的垂直对齐方式
align-content
align-content属性和align-items属性的区别在于align-items属性设置的是每一个flex子项的垂直对齐方式,而align-content属性将所有flex,align-content控制子项的内容大小,而align-items控制在这个大小内的摆放
stretch可以看成弹性布局中align-content属性的默认值,表示每一行flex子项都等比例拉伸。例如,如果共两行flex子 项,则每一行拉伸的高度是50%。
flex-star是逻辑CSS属性值,与文档流方向相关,默认表现为顶部堆砌。
flex-end是逻辑CSS属性值,与文档流方向相关,默认表现为底部堆放。
center表现为整体垂直居中对齐。
space-between表现为上下两行两端对齐,剩下的每一行元素等分剩余空间。
space-around表现为每一行元素上下都享有独立不重叠的空白空间。
space-evenly表现为每一行元素上下的空白空间的大小都是一致的。
子容器属性
-
flex是flex-grow || flex-shrink?|| flex-basis的简写,说明flex属性值可以是一个、两个、或者是三个,剩下的为默认值
-
默认值为flex: 0 1 auto
-
none: 0 0 auto
-
auto:1 1 auto
(1)如果flex的属性值只有1个值,则具体规则如下。
如果是数值,如flex: 1,则这个1为flex-grow属性的值,此 时flex-shrink属性和flex-basis属性的值分别是1和0%。注 意,这里的flex-basis属性的值是0%,而不是默认值auto。 如果是长度值,如flex:100px,则这个100px显然为flex-basis属性的值,因为3个缩写CSS属性中只有flex-basis的属 性值支持长度值。此时flex-grow属性和flex- shrink属性 的值都是1,注意,这里的flex-grow属性的值是1,而不是默认 值0。
(2)如果flex的属性值有2个值,则第一个值一定是flex-grow属性值(因为表示0个或1个的问号“?”在flex-shrink的后 面),第二个值根据值的类型不同对应不同的CSS属性,具体规则如 下。 如果第二个值是数值,例如flex: 1 2,则这个2是flex-shrink属性的值,此时flex-basis属性计算值是0%,并非默 认值auto。 如果第二个值是长度值,例如flex: 1 100px,则这个100px 为flex-basis属性值。
(3)如果flex的属性值有3个值,则长度值为flex-basis属性 值,其余2个数值分别为flex-grow和flex-shrink的属性值。下面两行CSS语句都是合法的,且含义也是一样的: 下面两行CSS语句含义是一样的 *
flex: 1 2 50%;
flex: 50% 1 2;
flex:100px等同于flex:1 1 100px,即flex-grow使用的 不是默认值0,而是使用的1。按照CSS规范的说法,这样设计的目的是让flex属性的表现更符 合我们日常开发需要的效果。意思就是,当我们使用flex:1的时 候,正常情况下就是要flex-basis为0%,即基础尺寸为0;当我们使用flex:100px的时候,正常情况下就是需要flex-grow为1,也 就是尺寸保持向外的弹性。这样更人性化
故事是这样的,有一个人家生了5个孩子,分别叫作老大、 老二、老三、老四和老五。要是只有一个孩子,那这个孩子就继承 100%的家产,但是现在有5个孩子,家长需要提早定好家产分配规 则。而flex属性的作用就如同制定分配家产的规则。
flex-basis属性用来分配基础数量的家产。
flex-grow属性用来家产仍有富余的时候该如何分配。
flex-shrink属性用来家产不足的时候该如何分配。
flex-grow
弹性延伸比例
- 可以设置任何非负数字(正整数、正小数、0),默认值为0 所有剩余空间总量是1。
如果只有1个flex子项设置了flex-grow属性值,则有两种分配
情况1。
如果flex-grow属性值小于1,则flex子项扩展的空间就是 总剩余空间和这个比例的计算值。有空间剩余
情况2。
如果flex-grow属性值大于1,则flex子项独享所有剩余空 间。 如果有多个子项flex设置了flex-grow属性值,则有两种分配
如果有多个子项flex设置了flex-grow属性值,则有两种分配 情况
情况1
如果flex-grow属性值的总和小于1,则每个flex子项扩展 的空间就是总剩余空间和当前flex子项设置的flex-grow 比例的计算值。有空间剩余
情况2
如果flex-grow属性值的总和大于1,则所有剩余空间被利 用,分配比例就是各个flex子项的flex-grow属性值的比 例。例如,所有flex子项都设置flex-grow:1,则表示剩 余空间等分;如果设置的flex-grow比例是1:2:1,则中间 的flex子项占据一半的剩余空间,剩下另外一半的剩余空间 由前后两个flex子项等分。
flex-basis
默认原始尺寸,flex不为0时失效 (会有flex-grow设置为0的情况,比如flex:0 1 100px)
flex-basis用来设置flex items在主轴方向上的base size,以后flew-grow和flex-shrink计算时所需要用的base size就是这个- auto(默认值)、content:取决于内容本身的size,这两个属性可以认为效果都是一样的,当然也可以设置具体的值和百分数(根据父盒子的比例计算)
- 决定
flex items最终base size因素的优先级为max-width/max-height/min-width/min-height>flex-basis>width/height>内容本身的size - 可以理解为给
flex items设置了flex-basis属性且属性值为具体的值或者百分数的话,主轴上对应的size(width/height)就不管用了
最终尺寸计算的优先级是: 最大最小尺寸限制 > 弹性增长或收缩 > 基础尺寸
基础尺寸由flex-basis属性或width属性,以及box-sizing盒模型共同决定; 内容尺寸指最大内容宽度,当没有设置基础尺寸时会顶替基础尺 寸的角色; 弹性增长指的是flex-grow属性,弹性收缩指的是flex-shrink属性; 最大尺寸主要受max-width属性限制;最小尺寸则比较复杂,受 最小内容宽度、width属性和min-width属性共同影响。
如果flex-basis属性和width属性同时设置了具体的数 值,width属性值会被忽略,优先使用flex-basis的属性值作为基础尺寸
如果flex-basis的属性值是初始值auto,则会使用 width属性设置的长度值作为基础尺寸。
如果flex-basis和width的属性值都是auto,则会使用 flex子项的最大内容宽度(文字内容全部一行显 示的宽度)作为基础尺寸,此时称为“内容尺寸”。示 意效果如图6-62所示,最终尺寸大小是由文字内容长度决定的。
而设置了box-sizing:border-box后
这是因为flex-basis属性不支持box-sizing属性吗?其实并 不是,设置flex-basis属性的元素的最小尺寸是最小内容宽度(文 字内容在所有换行点换行后的尺寸),
如果flex-shrink属性不为0, 则: 如果min-width属性值不是auto,则元素的最小尺寸就是minwidth的属性值,此时width属性无法影响最小尺寸,哪怕 width的属性值大于min-width的属性值;
比较width属性的计算值和最小内容宽度的大小,较小的值就是 元素的最小尺寸;
如果width的属性值和min-width的属性值均为auto,则元素 的最小尺寸就是最小内容宽度;
如果flex子项设置了overflow:hidden,且最小尺寸是由最小 内容宽度决定的,则最小尺寸无效。
flex-basis属性下的最小尺寸是由内容决定的, 而width属性下的最小尺寸是由width属性的计算值决定的。
flex-shrink
- 当flex items在主轴方向上超过了flex container的size之后,flex-shrink属性才会生效
flex-shrink属性指定了容器剩余空间不足时候的分配规则,默认值是1,表示空间不足要分配,- 可以设置任意非负数字(正小数、正整数、0),默认值是1
如果只有1个flex子项设置了flex-shrink属性值,则有两种分配情况。
- 如果flex-shrink属性值小于1,则收缩不完全,会有一部 分内容溢出flex容器。 如果flex-shrink属性值大于等于1,则收缩完全,元素正 好填满flex容器。
如果多个flex子项设置了flex-shrink属性,则有两种分配情况。
- 如果flex-shrink属性值的总和小于1,则收缩不完全,
收缩比例 = flex-shrink * flex item的基础尺寸,基础尺寸就是flex item放入flex container之前的size
每个flex item收缩的size为超出的尺寸 / 所有flex items 的收缩比例之和 * 收缩比例 (考虑到了每个item尺寸不一样的情况,所以要除所有收缩比例之和)
-
如果flex-shrink属性值的总和大于1,则收缩完全,每个元素收缩尺寸的比例和flex-shrink属性值的比例一样。
总结:当flex items的flex-shrink属性值的总和小于1时,通过其计算收缩size的公式可知,其总共收缩的距离是超出的size * sum,由于sum是小于1的,那么无论如何子盒子都不会完全收缩至超过的距离,也就是说在不换行的情况下子元素一定会有超出
order 排列顺序,越小越靠前,默认值为0,可以负数
应该在什么时候使用flex:0/1/none/auto
flex:initial的基本表现
flex:initial等同于设置flex: 0 1 auto,可以理解为 flex属性的默认值。其行为表现用文字描述为:应用flex:initial的元素在flex 容器有剩余空间时其尺寸不会增长(flex-grow:0,不会增长把剩余空间占满),在flex容器 尺寸不足时尺寸会收缩变小(flex-shrink:1,如果子项很多,那么尺寸会缩小,比如文字换行),同时当前应用 flex:initial的元素的尺寸自适应于内容(flex-basis:auto)
flex:0和flex:none的区别
flex:0等同于设置flex: 0 1 0%,flex:none等同于设置 flex: 0 0 auto,flex:0不会增大,但是会弹性收缩,flex:none,不增大,不缩小,尺寸由内容决定
flex:1和flex:auto的区别
flex:1等同于设置flex: 1 1 0%,flex:auto等同于设置 flex: 1 1 auto
结合flex属性值的描述,我们可以得出flex:1和flex:auto的 行为表现:元素尺寸可以弹性增大,也可以弹性减小,但是flex:1 在容器尺寸不足时会优先最小化内容尺寸,flex:auto在容器尺寸不足时会优先最大化内容尺寸。
当希望元素充分利用剩余空间,同时不会侵占其他元素应有的宽度的时候,适合使用flex:1
当希望元素充分利用剩余空间,但是元素各自的尺寸又需要按照各自内容进行分配的时候,就适合使用flex:auto。
总结
flex:initial表示默认的弹性布局状态,无须专门设置,适合 小控件元素的分布布局(其中某一个flex子项的内容动态变化也 没有关系)。
flex:0适用场景较少,适合设置在替换元素的父元素上。
flex:none适合设置在内容不能换行显示的小控件元素上,如按钮。
flex:1适合等分布局。
flex:auto适合基于内容动态适配的布局。
flex最后一行排列不均匀
比如上面是4个子项,下面三个子项,排列不均匀,想让下面三个子项靠左对齐
子项宽度固定,比如子项宽度是24%
.list:not(:nth-child(4n)) { margin-right: calc(4% / 3); } 设定非第四个子项的margin
子项宽度不固定
行数不固定
用空元素占位
grid布局
.wrapper {
/* 声明一个容器 */
display: grid;
/* 声明列的宽度 */
repeat() 函数:可以简化重复的值。该函数接受两个参数,
第一个参数是重复的次数,第二个参数是所要重复的值
grid-template-columns: repeat(3, 200px);
/* 声明行间距和列间距 */
grid-gap: 20px;
/* 声明行的高度 */
grid-template-rows: 100px 200px;
}
display声明,grid块级元素网格布局,inline-grid行内元素,网格布局
网格轨道:grid-template-columns 和 grid-template-rows 属性来定义网格中的行和列。容器内部的水平区域称为行,垂直区域称为列,就是定义一行一列多少个元素
repeat() 函数
auto-fill 关键字:表示自动填充,让一行(或者一列)中尽可能的容纳更多的单元格
grid-template-columns: repeat(auto-fill, 200px) 表示列宽是 200 px,但列的数量是不固定的,只要浏览器能够容纳得下,就可以放置元素,
fr关键字 grid-template-columns: 200px 1fr 2fr 表示第一个列宽设置为 200px,后面剩余的宽度分为两部分,宽度分别为剩余宽度的 1/3 和 2/3
minmax() 函数 minmax() 函数产生一个长度范围,表示长度就在这个范围之中都可以应用到网格项目中。它接受两个参数,分别为最小值和最大值。grid-template-columns: 1fr 1fr minmax(300px, 2fr)
auto 设置auto可以自适应
grid-row-gap 属性、grid-column-gap 属性分别设置行间距和列间距。grid-gap 属性是两者的简写形式。
areas和area配置
grid-auto-flow
控制自动布局是先行后列,还是先列后行 grid-auto-flow: row; column; 如果加了dense 那就会尽可能填满表格,rou dense;colunmn dense
justify-items 属性设置单元格内容的水平位置(左中右),align-items 属性设置单元格的垂直位置(上中下)
.container {
justify-items: start | end | center | stretch(拉伸);
align-items: start | end | center | stretch(拉伸);
}
justify-content 属性、align-content 属性以及 place-content 属性
justify-content 属性是整个内容区域在容器里面的水平位置(左中右),align-content 属性是整个内容区域的垂直位置(上中下)。它们都有如下的属性值。跟flex一样
.container {
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
align-content: start | end | center | stretch | space-around | space-between | space-evenly;
}
-
space-around - 每个项目两侧的间隔相等。所以,项目之间的间隔比项目与容器边框的间隔大一倍
-
space-between - 项目与项目的间隔相等,项目与容器边框之间没有间隔
-
space-evenly - 项目与项目的间隔相等,项目与容器边框之间也是同样长度的间隔
-
stretch - 项目大小没有指定时,拉伸占据整个网格容器
grid-column-start 属性、grid-column-end 属性、grid-row-start 属性以及grid-row-end 属性
可以指定网格项目所在的四个边框,分别定位在哪根网格线,从而指定项目的位置
- grid-column-start 属性:左边框所在的垂直网格线
- grid-column-end 属性:右边框所在的垂直网格线
- grid-row-start 属性:上边框所在的水平网格线
- grid-row-end 属性:下边框所在的水平网格线
布局
两栏布局的实现
一般两栏布局指的是左边一栏宽度固定,右边一栏宽度自适应,两栏布局的具体实现:
- 利用浮动,将左边元素宽度设置为200px,并且设置向左浮动。将右边元素的margin-left设置为200px,宽度设置为auto(默认为auto,撑满整个父元素)。
.outer {
height: 100px;
}
.left {
float: left;
width: 200px;
background: tomato;
}
.right {
margin-left: 200px;
width: auto;
background: gold;
}
- 利用浮动,左侧元素设置固定大小,并左浮动,右侧元素设置overflow: hidden; 这样右边就触发了BFC,BFC的区域不会与浮动元素发生重叠,所以两侧就不会发生重叠。
.left{
width: 100px;
height: 200px;
background: red;
float: left;
}
.right{
height: 300px;
background: blue;
overflow: hidden;
}
- 利用flex布局,将左边元素设置为固定宽度200px,将右边的元素设置为flex:1。
.outer {
display: flex;
height: 100px;
}
.left {
width: 200px;
background: tomato;
}
.right {
flex: 1;
background: gold;
}
- 利用绝对定位,将父级元素设置为相对定位。左边元素设置为absolute定位,并且宽度设置为200px。将右边元素的margin-left的值设置为200px。
.outer {
position: relative;
height: 100px;
}
.left {
position: absolute;
width: 200px;
height: 100px;
background: tomato;
}
.right {
margin-left: 200px;
background: gold;
}
- 利用绝对定位,将父级元素设置为相对定位。左边元素宽度设置为200px,右边元素设置为绝对定位,左边定位为200px,其余方向定位为0。
.outer {
position: relative;
height: 100px;
}
.left {
width: 200px;
background: tomato;
}
.right {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 200px;
background: gold;
}
三栏布局的实现
三栏布局一般指的是页面中一共有三栏,左右两栏宽度固定,中间自适应的布局,三栏布局的具体实现:
- 利用绝对定位,左右两栏设置为绝对定位,中间设置对应方向大小的margin的值。
.outer {
position: relative;
height: 100px;
}
.left {
position: absolute;
width: 100px;
height: 100px;
background: tomato;
}
.right {
position: absolute;
top: 0;
right: 0;
width: 200px;
height: 100px;
background: gold;
}
.center {
margin-left: 100px;
margin-right: 200px;
height: 100px;
background: lightgreen;
}
- 利用flex布局,左右两栏设置固定大小,中间一栏设置为flex:1。
.outer {
display: flex;
height: 100px;
}
.left {
width: 100px;
background: tomato;
}
.right {
width: 100px;
background: gold;
}
.center {
flex: 1;
background: lightgreen;
}
- 利用浮动,左右两栏设置固定大小,并设置对应方向的浮动。中间一栏设置左右两个方向的margin值,注意这种方式**,中间一栏必须放到最后:**
.outer {
height: 100px;
}
.left {
float: left;
width: 100px;
height: 100px;
background: tomato;
}
.right {
float: right;
width: 200px;
height: 100px;
background: gold;
}
.center {
height: 100px;
margin-left: 100px;
margin-right: 200px;
background: lightgreen;
}
圣杯布局
- 圣杯布局,利用浮动和负边距来实现。父级元素设置左右的 padding,三列均设置向左浮动,中间一列放在最前面,宽度设置为父级元素的宽度,因此后面两列都被挤到了下一行,通过设置 margin 负值将其移动到上一行,再利用相对定位,定位到两边。
.outer {
height: 100px;
padding-left: 100px;
padding-right: 200px;
}
.left {
position: relative;
left: -100px;
float: left;
margin-left: -100%;
width: 100px;
height: 100px;
background: tomato;
}
.right {
position: relative;
left: 200px;
float: right;
margin-left: -200px;
width: 200px;
height: 100px;
background: gold;
}
.center {
float: left;
width: 100%;
height: 100px;
background: lightgreen;
}
双飞翼布局
- 双飞翼布局,双飞翼布局相对于圣杯布局来说,左右位置的保留是通过中间列的 margin 值来实现的,而不是通过父元素的 padding 来实现的。本质上来说,也是通过浮动和外边距负值来实现的。
.outer {
height: 100px;
}
.left {
float: left;
margin-left: -100%;
width: 100px;
height: 100px;
background: tomato;
}
.right {
float: left;
margin-left: -200px;
width: 200px;
height: 100px;
background: gold;
}
.wrapper {
float: left;
width: 100%;
height: 100px;
background: lightgreen;
}
.center {
margin-left: 100px;
margin-right: 200px;
height: 100px;
}
分栏布局
用ul 和li布局,用li使用弹性布局或者网格布局的话,项目符号会立刻消失,例如原点或者序号。
columns
columns是columns-width 和 columns-count的缩写,顺序不限制
columns-width
每一栏/列的理想宽度,会与实际宽度有出入,更像一个期望宽度,不支持百分比,浏览器会根据这个期望宽度,来确定ul分成几栏
columns-count
理想分栏数量,最终分栏效果跟columns-width相互制约,看谁优先级高。优先级计算是全部转换成行数,看谁更小,就用谁
columns-gap
支持百分比,columns-gap其实是gap的子属性,在网格布局规范制定之后的一段时间,CSS世界中的行与列之间的 间隙使用了gap属性进行了统一,也就是分栏布局、弹性布局和网格 布局的间隙都全部统一使用gap属性表示,而gap属性实际上是 column-gap属性和row-gap属性的缩写。
columns-rule
column-rule属性和border属性的语法和规则是一模一样的, 只是column-rule是设置各个分栏的分隔线样式,border是设置元 素的边框样式 例如column-rule: dashed deepskyblue;