个人主页:学习前端的小z
个人专栏:HTML5和CSS3悦读
本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结,欢迎大家在评论区交流讨论!
文章目录
- Flex布局
- 1 Flex容器和Flex项目
- 2 Flex 容器属性
- 2.1 主轴的方向
- 2.2 主轴对齐方式
- 2.3 Flex 项目换行
- 2.4 交叉轴对齐方式
- 2.4.1 align-items属性
- 2.4.2 align-content属性
- 3 Flex 项目属性
- 3.1 Flex项目排序
- 3.2 Flex 项目交叉轴对齐方式
- 3.2 放大比例
- 3.3 收缩比例
- 3.4 Flex项目基准宽度
Flex布局
Flex是Flexible Box的缩写,意为”弹性(放大、缩小)布局”,用来为盒状模型提供最大的灵活性。
flex布局是目前主流的布局方式,结合盒子模型+定位,可以快速实现页面各种复杂布局。
大部分场景下可以代替浮动布局,特殊场景下,比如:文字环绕效果,还得使用浮动布局更方便。
学习Flex布局搞清楚几个重要的概念:
flex container
:flex 容器flex item
:flex 项目,针对容器的子级main axis
:主轴,默认是水平方向cross axis
:交叉轴,默认是垂直方向main start
:主轴和 flex 容器左边的交叉点main end
:主轴和 flex 容器右边的交叉点cross start
:交叉轴和 flex 容器上边的交叉点cross end
:交叉轴和 flex 容器下边的交叉点main size
:flex 项目占据的主轴宽度,可伸缩cross size
:flex 项目占据的交叉轴高度,可伸缩
flex 项目默认沿主轴排列
1 Flex容器和Flex项目
指定一个 Flex 容器:
<style>
.box {display: flex;/*display: inline-flex;*/
}
</style>
<div class="box"><div></div><span></span>文字<input type="text">
</div>
Flex 容器的子级全部变成 Flex 项目,不管你原来是 block,inline-block,inline 都会设置为 flex 项目(display: block)一样对待。
flex项目变成block,这个block和之前学习position:absolute、fixed以及float:left|right的块级类似,虽然计算属性display:block,但是表现形式和行内块类似,默认都是内容的宽度,但是可以设置宽度、高度、外边距、内边距、边框等等
2 Flex 容器属性
2.1 主轴的方向
flex-direction属性决定主轴的方向(即项目的排列方向)。
flex-direction: row | row-reverse | column | column-reverse;
- row(默认值):主轴为水平方向,起点在左端。
- row-reverse:主轴为水平方向,起点在右端。很少使用
- column:主轴为垂直方向,起点在上沿。交叉轴就变成水平
- column-reverse:主轴为垂直方向,起点在下沿。交叉轴就变成水平。很少使用
2.2 主轴对齐方式
justify-content属性定义了项目在主轴上的对齐方式。
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
它可能取5个值,具体对齐方式与轴的方向有关。下面假设主轴为从左到右。
- flex-start(默认值):左对齐
- flex-end:右对齐
- center: 居中
- space-between:两端对齐,项目之间的间隔都相等。
- space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
- space-evenly:每个间隙距离相等. (兼容处理:用 space-between配合before+after使用)
2.3 Flex 项目换行
默认情况下,项目都排在一条线(又称”轴线”)上。flex-wrap属性定义,如果一条轴线排不下,如何换行。
- Flex容器指定了具体宽度
- 所有的Flex项目总宽度 > Flex容器宽度
flex-wrap: nowrap | wrap | wrap-reverse;
它可能取三个值。
1、nowrap(默认):不换行。Flex宽度700px,每个Flex项目宽度为100px, 1000px > 700px,只能收缩至70px
2、wrap:换行,第一行在上方。
3、wrap-reverse:换行,第一行在下方。很少使用
flex-flow
flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap
。很少使用
flex-flow: <flex-direction> <flex-wrap>;
2.4 交叉轴对齐方式
2.4.1 align-items属性
align-items属性设置 flex项目在每个 flex 行的交叉轴上的默认对齐方式。
align-items: flex-start | flex-end | center | baseline | stretch;
它可能取5个值。具体的对齐方式与交叉轴的方向有关,下面假设交叉轴从上到下。
- flex-start:交叉轴的起点对齐。
- flex-end:交叉轴的终点对齐。
- center:交叉轴的中点对齐。
- baseline: 项目的第一行文字的基线对齐。很少使用
- stretch(默认值):没有交换主轴和交叉轴方向的情况下,如果Flex项目未设置高度或设为auto,将占满整个容器的高度。如果flex项目有高度,则不会被拉伸占满,高度也可以会超过flex容器
【实践】利用justify-content和align-items快速实现水平垂直居中
- 与之前的 position:absolute + margin 水平垂直居中更好,不脱标,不会遮盖等问题
2.4.2 align-content属性
align-content属性只适用多行的flex容器(flex 项目不止一行时该属性才有效果),它的作用是当flex容器在交叉轴上有多余的空间时,将flex 项目作为一个整体(属性值为:flex-start、flex-end、center时)进行对齐。
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
未指定 flex-wrap: wrap;
,那么 align-content
属性是无效的:
翻译:flex wrappe:nowrap属性防止align-content产生效果。
尝试将flex-wrap设置为nowrap以外的其他内容。
说白了nowrap无效,设置 wrap-reverse 或者 wrap 是可以的,只要换行才可以对align-content产生效果
只要设置了flex-wrap: wrap,表示存在多行,那么就用align-content,否则单行总是用align-items即可
该属性可能取6个值。
- flex-start:与交叉轴的起点对齐。
- flex-end:与交叉轴的终点对齐。
- center:与交叉轴的中点对齐。
- space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
- space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
- stretch(默认值):轴线占满整个交叉轴。如果flex项目有高度,则不会被拉伸占满,高度也可以会超过flex容器
3 Flex 项目属性
3.1 Flex项目排序
order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。很少使用
order: <integer>;
3.2 Flex 项目交叉轴对齐方式
align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。
.item {align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
该属性可能取6个值,除了auto,其他都与align-items属性完全一致。
该属性可能取6个值,除了auto,其他都与align-items属性完全一致。
auto 表示继承 Flex 容器的 align-items 属性的值。
3.2 放大比例
该属性用来设置当父元素的宽度大于所有子元素的宽度的和时(即父元素会有剩余空间),子元素如何分配父元素的剩余空间。 flex-grow 的默认值为 0,意思是该元素不索取父元素的剩余空间,如果值大于0,表示索取。值越大,索取的越厉害。
flex-grow: <number>; /* default 0 */
如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。
假如设置父元素 400px,子元素 A 为100px,子元素 B 为 200px.则剩余空间为 100px
例子一:
A的 flex-grow 为 0,B的 flex-grow 为 0(即A、B不设置该属性)
则A、B的实际宽度为他们本身的宽度,即A的实际宽度为100px ; B的实际宽度为200px
例子二:
A的 flex-grow 为1,B的 flex-grow为0(即不设置该属性)
则A的实际宽度为 100px + 100px =200px ; B的实际宽度为 200px + 0 = 200px
例子三:
A的 flex-grow 为 1,B的 flex-grow 为 2
则 A 的实际宽度为 100px + 100px * 1/3 = 400/3 px , B的实际宽度为 200px + 100px * 2/3 = 800/3 px
上面的 总系数为 1 + 2 = 3 ,然后按照 各元素的 flex-grow 的属性值进行分配 A 1/3 B 2/3
结论: d = 剩余空间,g1 = flex-grow1,g2 = flex-grow2,A = A宽度,B = B宽度,设 At = A最终分配的宽度,Bt = B最终分配的宽度,当 d > 0,At = A + d * (g1 / g1 + g2),Bt = B + d * (g1 / g1 + g2)
最终结果 At + Bt = A + B + d = 父盒子的宽度,达到扩展
3.3 收缩比例
该属性用来设置子元素的 缩小比例,当父元素的宽度小于所有子元素的宽度的和时(即子元素会超出父元素),子元素如何缩小自己的宽度的。 **flex-shrink
**的默认值为 1,当父元素的宽度小于所有子元素的宽度的和时,子元素的宽度会减小。值越大,减小的越厉害。如果值为 0,表示不减小。
假如设置父元素 400px,子元素A为 200px,子元素B为 300px.则超出空间为 100px
例子一:
设置A的 flex-shrink 为 0,B的 flex-shrink 为 0
则A,B都不减小宽度,A、B的实际宽度为他们本身的宽度,即A的实际宽度为 200px ; B的实际宽度为 300px
例子二:
A的 flex-shrink 为 0,B的 flex-shrink 为 1,则A不减小宽度,B减小
则A的实际宽度为他本身的宽度= 200px , B的实际宽度为 300px - 100px(超出的宽度)= 200px
例子三:
如果A,B都减小宽度,A设置 flex-shirk 为 3,B设置 flex-shirk 为 2。则最终 A 的大小为 自身宽度 (200px) - A减小的宽度(100px * (200px * 3 / (200px * 3 + 300px * 2))) = 150px
最终 B 的大小为 自身宽度 (300px)- B减小的宽度 (100px * (300px * 2/(200px* 3 + 300px* 2))) = 250px
结论: d = 超出空间,g1 = flex-shrink1,g2 = flex-shrink2,A = A宽度,B = B宽度,设 At = A最终分配的宽度,Bt = B最终分配的宽度,当 d > 0,At = A - d * ( A * g1 / (A * g1 + B * g2) ),Bt = B - d * ( B * g2 / (A * g1 + B * g2) )
最终结果 At + Bt = A + B - d = 父盒子的宽度,达到收缩
3.4 Flex项目基准宽度
basis 的中文意思就是 基础、基准 ,该属性用来设置元素的宽度,通常情况下大家使用 width 设置宽度。但是如果元素上同时设置了 width 和 flex-basis ,那么 width 的值就会被 flex-basis 覆盖掉。其实就是flex 项目占据的主轴宽度(main size),可伸缩
flex-basis: <length> | auto; /* default auto */
放大比例(flex-grow)和收缩比例(flex-shrink)都是更加基准宽度(flex-basis)来进行计算的,如果没有基准宽度(flex-basis),那么就去使用width,如果width也没有,就会自动计算。
<style>.father {display: flex;width: 400px;height: 200px;}.box {width: 200px;height: 100px;flex-basis: 300px;background: blue;}
</style>
<div class="father"><div class="box"></div>
</div>
可以看到给父元素添加 display:flex 属性后让其变成 flex 布局 ,子元素的 width 设置成 200 px ,flex-basis 设置成 300 px,最终显示为 300px ,width 的值就被 flex-basis 覆盖掉,这个属性比较好理解
flex 属性
flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。
.item {flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。
建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。