每次使用或者问到flex总是感觉云里雾里的,这次下定决心一定把flex吃透了。
首先flex是针对于HTML标签的,它是一种布局方式。其实说到底它是一种display的布局样式,只不过他对HTML标签的影响效果更大, 更复杂一些,这也从一方面说明他的重要性。要想知道flex到底是如何影响元素的显示方式,就要搞清楚与之相关的属性的作用。
display
很多人会容易忽略的地方,其实flex的定义是这样的 : display:flex; 我们要想了解flex的影响,就要从display这个样式开始。
display这个属性用于定义建立布局时元素生成的显示框类型。对于 HTML 等文档类型,如果使用 display 不谨慎会很危险,因为可能违反 HTML 中已经定义的显示层次结构。对于 XML,由于 XML 没有内置的这种层次结构,所有 display 是绝对必要的。
而display的其他几个属性也有着相同的作用和处理方式,我们不妨将他们放在一起思考一下。
display属性值
1.控制元素的显示隐藏
none:隐藏对象。与visibility属性的hidden值不同,其不为被隐藏的对象保留其物理空间
2.控制行内或块级元素显示
inline:指定对象为内联元素。
block:指定对象为块元素。
inline-block:指定对象为内联块元素。(CSS2)
3.列表项目
list-item:指定对象为列表项目。
4.table相关
table:指定对象作为块元素级的表格。类同于html标签<table>(CSS2)
inline-table:指定对象作为内联元素级的表格。类同于html标签<table>(CSS2)
table-caption:指定对象作为表格标题。类同于html标签<caption>(CSS2)
table-cell:指定对象作为表格单元格。类同于html标签<td>(CSS2)
table-row:指定对象作为表格行。类同于html标签<tr>(CSS2)
table-row-group:指定对象作为表格行组。类同于html标签<tbody>(CSS2)
table-column:指定对象作为表格列。类同于html标签<col>(CSS2)
table-column-group:指定对象作为表格列组显示。类同于html标签<colgroup>(CSS2)
table-header-group:指定对象作为表格标题组。类同于html标签<thead>(CSS2)
table-footer-group:指定对象作为表格脚注组。类同于html标签<tfoot>(CSS2)
5.关联上下文
run-in:根据上下文决定对象是内联对象还是块级对象。(CSS3)
6.box弹性盒子
box:将对象作为弹性弹性盒显示。(弹性盒最老版本)(CSS3)
inline-box:将对象作为内联块级弹性弹性盒显示。(弹性盒最老版本)(CSS3)
7.box子元素设置属性
flexbox:将对象作为弹性弹性盒显示。(弹性盒过渡版本)(CSS3)
inline-flexbox:将对象作为内联块级弹性弹性盒显示。(弹性盒过渡版本)(CSS3)
8.flex弹性盒子
flex:将对象作为弹性弹性盒显示。(弹性盒最新版本)(CSS3)
inline-flex:将对象作为内联块级弹性弹性盒显示。(弹性盒最新版本)(CSS3)
弹性盒子的发展史这里就不详细说了,大致就是从 box->flexbox->flex,三者在使用和效果上存在区别,目前主要用的是flex最新版本。
有兴趣的话可以看一下这个问题:CSS3 display:flex和display:box有什么区别? - 知乎
flex
根据上述的display属性,我们可以推出来,flex与table布局相似,都会对元素内部的子元素排列和显示造成影响。
现在我们知道了flex使用来规定具有 display:flex;属性的元素内部子元素的显示方式的。
接下来就可以看一下具体的使用方式。
现在场景如下:
<div class="flex_container">
<div class="flex_child_1"></div>
<div class="flex_child_2"></div>
<div class="flex_child_3"></div>
</div>
有一个flex_container盒子,他作为父盒子出现,我们想要通过display:flex;属性将它设置为弹性盒子,它内部的元素显示会发生变化(如何变化在后边会介绍)。
.flex_container {
margin: 10px;
width: 400px;
height: 30vh;
display: flex; //设置为弹性盒子
}
父盒子的属性
我们在给父元素设置display:flex;属性之后,要先了解一下伴随着这个属性出现的可以设置在父元素上的几个配套样式属性,这些样式决定了父盒子中子盒子的排列显示方式。
- flex-direction:决定即项目的排列方向(即主轴方向)。
row
(默认值):子元素从左到右排列。row-reverse
:子元素从右到左排列。column
:子元素从上到下排列。column-reverse
:子元素从下到上排列。- align-items:定义项目在交叉轴(其实就是对应direction属性的交叉方向)上如何对齐。
flex-start
:交叉轴的起点对齐。flex-end
:交叉轴的终点对齐。center
:交叉轴的中点对齐。baseline
: 项目的第一行文字的基线对齐。stretch
(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。- align-content :定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
flex-start
:与交叉轴的起点对齐。flex-end
:与交叉轴的终点对齐。center
:与交叉轴的中点对齐。space-between
:与交叉轴两端对齐,轴线之间的间隔平均分布。space-around
:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。stretch
(默认值):轴线占满整个交叉轴。- flex-wrap:决定一行排满了之后如何换行
- nowrap(默认值):不换行
- wrap:换行之后,新元素在后
- wrap-reverse:换行之后,新元素在前
- flex-flow:是
flex-direction
和flex-wrap
的简写形式
- 默认值为
row nowrap
。- justify-content:定义了项目的对齐方式。
flex-start
(默认值):左对齐flex-end
:右对齐center
: 居中space-between
:两端对齐,项目之间的间隔都相等。space-around
:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
子元素的属性
在设置好父元素的相关属性之后,子元素的排列方式也就有了依据,接下来看一下作为flex弹性盒子的子元素会有哪些可设置的属性以及效果。
order
:
定义项目的排列顺序。数值越小,排列越靠前,默认为0。align-self
:
允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items
属性。默认值为auto
,表示继承父元素的align-items
属性,如果没有父元素,则等同于stretch
。flex-grow
:
定义项目的放大比例,默认为0
,即如果存在剩余空间,也不放大。flex-shrink
:
定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。flex-basis
:
定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto
,即项目的本来大小。flex
:
是flex-grow
,flex-shrink
和flex-basis
的简写,默认值为0 1 auto
。后两个属性可选。
在子元素中最重要的三个属性就是简写成flex的flex-grow、flex-shrink和flex-basis。三者其中最重要的最常用的是flex-grow,即元素的放大比例(注:以下说明中,以主轴为从左到右为例)
flex-grow:
- 如果父元素有剩余空间,那么就子盒子就会根据flex-grow的值来分配父盒子的剩余空间。
- 分配方式就是:父盒子剩余空间*(当前盒子flex-grow值 / 所有子盒子flex-grow值的和)
- 注意:这里是分配的是父盒子的剩余空间,如果子盒子原本就有宽度,那么子盒子的宽度计算公式就应该是:(当前盒子宽度+父盒子剩余空间*(当前盒子flex-grow值/所有子盒子felx-grow值的和))
flex-grow:
- 如果父元素的宽度小于所有子元素的宽度的和(即子元素会超出父元素)。子元素会根据这个属性来缩小已达到父盒子的宽度。
- 缩小方式是:子盒子缩小尺寸=所有子盒子超出部分*(子盒子flex-shrink的值/所有子盒子flex-shrink值的和)
- 即子盒子缩小后的尺寸 = 子盒子原本尺寸-子盒子缩小尺寸
flex-basis:
- 该属性用来设置元素的宽度,其实,width也可以设置宽度。如果元素上同时设置了width和flex-basis,那么width 的值就会被flex-basis覆盖掉。
以上是对flex相关样式属性的描述和理解,如果有误差的地方希望大家可以指正。