关于 flexbox,网上有着非常多的文章。比如:
那为什么我还要写呢,因为 flexbox 真的很有用很好用啊 :)
有疑问的时候可以查一下 flexbox 的草案,或者找我交流啊。
#基本概念
采用 flex 布局的元素为 flex container(也叫做 flexbox),其中的所有子元素为 flex item。
将元素的 display
属性设置为flex
或者为 inline-flex
就可以将一个元素设置成 flex container,其中子元素也就自动变成 flex item 了。(如果是设置成 flex
这个 container 就是 block 级别的,如果是 inline-flex
则是 inline 级别的。)
flex 布局时,可以指明是横向(row)布局,还是竖向(column)布局,默认是横向布局。两种不同的布局方式,会决定其他 flex 属性的效果。
main axis
是 flex container 的主轴,其方向与 flex 布局方向一致。就是说,如果采用横向布局,则 main axis 与 CSS 坐标系的 x 轴一致,如果采用竖向布局,则 main axis 与 y 轴一致。
corss axis
是 flex container 的交叉轴,与主轴垂直。
main-start / main-end
分别是 flex container 主轴的起始边和终点边。默认情况下,flex item 从 main-start 向 main-end 方向排列。
cross-start / cross-end
分别是 flex container 交叉轴的起始边和终点边。默认情况下,flex item 在交叉轴方向上会占满 cross-start 和 cross-end 之间的空间。
main size
指 flex item 的 宽度 或 高度,如果是横向布局,则 main size 是指 宽度,如果是竖向布局,则 main size 是指 高度。
cross size
与 main size 类似。如果是横向布局,则 cross size 指 高度,如果是竖向布局,则 cross size 是指 宽度。
flex container 和 flex item 都有一些 flex 相关的属性可以使用。
需要说明的是,本文所有例子中右侧的 demo 区域,都已经使用了以下 html 结构:
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
</div>
并且使用了以下 style:
.container {
display: flex;
background: #70F770;
}
.item {
color: white;
border: 1px solid #333;
}
.item:nth-child(1) {
background: #f00;
}
.item:nth-child(2) {
background: #a50;
}
.item:nth-child(3) {
background: #5a0;
}
.item:nth-child(4) {
background: #0f0;
}
.item:nth-child(5) {
background: #0a5;
}
.item:nth-child(6) {
background: #05a;
}
.item:nth-child(7) {
background: #00f;
}
.item:nth-child(8) {
background: #00a;
}
注意: 本页面使用了 autoprefixer
#container属性
flex container 有以下几种 flex 属性可以使用
- flex-direction
- flex-wrap
- flex-flow
- justify-content
- align-items
- align-content
下面会对每个属性进行说明,并给出例子。
#flex-direction
flex-direction
决定布局方向,也就是 main axis 的方向。
可使用以下几个值:
.container {
flex-direction: row | row-reverse | column | column-reverse;
}
flex-direction: row
为横向布局,该值为默认值。下面的例子中可以看到,这8个 item 是横向排开的。
.container {
flex-direction: row;
}
flex-direction: row-reverse
为横向布局,但其中的 flex item 会反方向铺展开,起点也是从最右侧(main end)开始。
.container {
flex-direction: row-reverse;
}
column
为竖向布局
.container {
flex-direction: column;
}
column-reverse
竖向布局。与 row-reverse
类似,其中的 flex item 也会发反方向铺展开来,起点在下侧(main end)。
.container {
flex-direction: column-reverse;
}
#flex-wrap
当 container 的 main axis 上排不下所有的 flex item 时怎么办呢? 属性 flex-wrap
就是来解决这个问题的,这个属性可以用来决定排不下的 item 是不是要换行或者换列。其可用值如下:
.container {
flex-wrap: nowrap | wrap | wrap-reverse;
}
nowrap
为默认值,表示不换行。(如果是采用竖向布局,则表示不换列 :)
如果 item
在主轴上排不下,比如下面的例子中,container 使用了 column
方向排序,内部的所有 item 因为 min-height
设置为 40px
了,所有 item 的高度加在一起已经超过了 containter 的可用高度了。但是因为 flex-wrap
的值为 nowrap
所以并不会换列。
注意:下面的例子中,flex-directin: column
,所以采用的是竖向布局,就是说 main axis 会是 y 方向。
.container {
flex-direction: column;
flex-wrap: nowrap;
}
.item {
min-height: 40px;
width: 30px;
}
flex-wrap
的值 是 wrap
时, 如果所有 item 不能在主轴上一行或者一列排开,则会换行或者换列。
下面的例子中,采用竖向布局,主轴在垂直方向。因为 item 的 min-height
设为 40px
,所以这些 item 并不能在一列排下。
.container {
flex-direction: column;
flex-wrap: wrap;
}
.item {
min-height: 40px;
width: 30px;
}
wrap-reverse
时,行为会与值为 wrap
时一样。但是排列时,值为 wrap
排列会从交叉轴(corss axis)的 cross start 开始,而值为 wrap-reverse
时,排列会从交叉轴的 cross end 开始
.container {
flex-direction: column;
flex-wrap: wrap-reverse;
}
.item {
min-height: 40px;
width: 30px;
}
#flex-flow
flex-flow
属性是 flex-direction
属性和 flex-wrap
属性的简写形式,默认值为 row nowrap
.container {
flex-flow: <flex-direction> || <flex-wrap>;
}
#justify-content
justify-content
用于描述 flex item 及其之间的"空闲空间"在 container 主轴上的对齐方式。
.container {
justify-content: flex-start | flex-end | center | space-between | space-around;
}
flex-start
是默认值,表示 container 中的内容会分布在主轴的起始位置。
.container {
justify-content: flex-start;
}
flex-end
则表示 container 中的内容会分布在主轴的末尾位置。
.container {
justify-content: flex-end;
}
center
则表示 container 中的内容在主轴上居中。
.container {
justify-content: center;
}
space-between
则表示 container 中主轴上的所有“空闲空间”会均匀分布到 item 之间。
.container {
justify-content: space-between;
}
space-around
则表示 container 中主轴上的所有“空闲空间”会均匀分布到 item 的两侧。
下面的例子中,1的左边有“一份”空间,右边也有“一份”空间。2的左边和右边也同样有“一份”空间,所以可以看到1左边有“一份”空关键,而1和2之间是有“两份”的。
.container {
justify-content: space-around;
}
#align-items
align-items
属性决定 container 中的 item 在 交叉轴cross axis 上是如何分布的。
可用值:
.container {
align-items: flex-start | flex-end | center | baseline | stretch;
}
flex-start
表示对其到 交叉轴 croass axis 的起始边(cross start)。
下面的例子没有指定flex-direction
,所以默认为横向布局。
.container {
align-items: flex-start;
}
flex-end
表示对其到 交叉轴croass axis 的终点边(cross end)。
.container {
align-items: flex-end;
}
center
表示对其到 交叉轴croass axis 的中线。
.container {
align-items: center;
}
baseline
表示按照 item 中文字的基线对齐。
.container {
align-items: baseline;
}
.item {
font-size: 20px;
}
.item:nth-child(2n+1) {
font-size: 28px;
}
.item:nth-child(4) {
font-size: 50px;
}
stretch
是默认值,如果 item 的 cross size (横向布局时,即高度)没指明的话, item 会伸展开来,cross axis 方向填满。
.container {
align-items: stretch;
}
#align-content
align-content
这个属性只有在 item 排成多行(flex-direction
是横向)或者多列(flex-direction
是竖向)的时候才生效。它决定这多行/多列的 item 整体上在 cross axis 上的分布方式。
可用值:
.container {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
flex-start
表示所有 item 整体上分布在 cross axis 的起始位置(cross start)
下面的例子中,因为 item 设置了 min-width
, container 上 flex-wrap
设置为 wrap
所以会换行。
.container {
flex-direction: row;
flex-wrap: wrap;
align-content: flex-start;
}
.item {
min-width: 85px;
}
flex-end
表示所有 item 整体上分布在 cross axis 的末尾位置(cross end)
.container {
flex-direction: row;
flex-wrap: wrap;
align-content: flex-end;
}
.item {
min-width: 85px;
}
center
表示所有 item 整体上在 cross axis 的中线上对齐
.container {
flex-direction: row;
flex-wrap: wrap;
align-content: center;
}
.item {
min-width: 85px;
}
space-between
表示所有每行/每列之间空间均匀分布。
.container {
flex-direction: row;
flex-wrap: wrap;
align-content: space-between;
}
.item {
min-width: 85px;
}
space-around
表示所有每行/每列两边的空间均匀分布。
.container {
flex-direction: row;
flex-wrap: wrap;
align-content: space-around;
}
.item {
min-width: 85px;
}
stretch
是默认值, 表示每行/列都将会自由拉伸开,cross axis 上占用整个空间。
.container {
flex-direction: row;
flex-wrap: wrap;
align-content: stretch;
}
.item {
min-width: 85px;
}
#item属性
flexbox 中的 item 也有着相关的 flex 属性。
- order
- flex-grow
- flex-shrink
- flex-basis
- flex
- align-self
#order
默认情况下,flex item 在 container 中分布时会按照 html 代码中的顺序。但我们也可以使用 order
属性来控制 item 的分布顺序。
order
的值是一个整数。初始默认值是0
,值越小,就会排的越靠前,这个值也可以是负值。
.item {
order: <integer>; /* default 0 */
}
注意观察下面例子中 item 的顺序。
.item:nth-child(2n) {
order: -1;
}
.item:nth-child(5) {
order: 3;
}
.item:nth-child(3) {
order: 99;
}
#flex-grow
flex-grow
属性决定这个 item 所占空间比例
其值是一个不小于0的数字,注意该值并不是作为百分比来解释。默认值是0
。
.item {
flex-grow: <number>; /* default 0 */
}
flex-grow
是如何工作的? flexbox 中的 item 在 main axis 上的尺寸首先由其 flex-basis
属性(该属性后面会进行描述)决定,假设这时 main axis 上还有“空闲空间”的话,就把这些空间分给使用了 flex-grow
属性的那些 item,flex-grow
的值就是它们额外可以拿到的空间的份数。
假设只有一个 item 使用了 flex-grow
属性,则其值是 1
还是 100
,其结果会是一样的,因为只有这一个 item 去分多余的“空闲空间”。
.item:nth-child(1) {
flex-grow: 1;
}
.item:nth-child(3) {
flex-grow: 2;
}
.item:nth-child(5) {
flex-grow: 4;
}
#flex-shrink
flex-shrink
属性决定空间不足时这个 item 收缩的比例,默认值是1。
.item {
flex-shrink: <number>; /* default 1 */
}
.item {
flex-basis: 190px;
flex-shrink: 1;
}
.item:nth-child(3) {
flex-shrink: 2;
}
.item:nth-child(5) {
flex-shrink: 0;
}
#flex-basis
flex-basis
表示在分配空闲空间之前 item 的 main size 的初始大小。
它可以使用与 width
/height
属性相同的值,比如20px
, 30%
, 4em
等。除此之外,还有一个值 content
, 表示尺寸基于 item 的内容, 相当与width: auto; flex-basis: auto;
。
默认值是 auto
,表示 如果该 item 定义了 main size 尺寸则使用该尺寸,如果没有,则基于其内容。
.item:nth-child(2) {
width: 20px;
flex-basis: auto;
}
.item:nth-child(4) {
flex-basis: 20%;
}
#flex
flex
是 flex-grow
, flex-shrink
, flex-basis
三个属性的简写形式。
常见值:
initial
等价于 0 1 auto
。 item 的大小会遵守其 width
/height
属性,如果 mian size 计算出来的是 auto
,则 item 的大小是由其内容决定的。如果 container 仍然有可用空间,item 并不会伸展。但如果 container 的空间不足, item 会尽可能的缩小。
auto
等价于 1 1 auto
。item 的大小会遵守其 width
/height
属性,但该 item 可以伸展。假设 container 中所有的 item 使用都是 flex: auto
, flex: initial
或者 flex: none
,当所有 item 的尺寸计算完毕以后,空余的空间会被平均分配给属性 flex: auto
的 item。
none
等价与 0 0 auto
。item 的大小会遵守其 width
/height
属性,但不会有伸缩性。
flex: <positive-number>
等价与 flex: <positive-number> 1 0
。该 item 会完全按照指定的比例去使用空闲空间。
#align-self
align-self
属性可以用来设置该 item 在 cross axis 上的对齐方式,用来覆盖在 flex container 上的相关属性设置。
其可用值与 container 上 align-items
的值一致。
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
.item:nth-child(2) {
align-self: flex-end;
}
.item:nth-child(3) {
align-self: center;
}
.item:nth-child(7) {
font-size: 10px;
align-self: baseline;
}
.item:nth-child(8) {
font-size: 25px;
align-self: baseline;
}
以上就是所有内容了,怎么样,会用了没。