Flex布局的那些事儿

前端开发
2019年08月28日
0

弹性盒子布局

弹性盒子布局(Flexbox)是一种一维的布局模型,一次只能处理一个维度的布局,一行或一列。

在元素的样式上设置display: flex;或者display: inline-flex;可以将该元素变成 Flex container(弹性容器) 。弹性容器的直系子元素被称为 Flex item(弹性项目) ,弹性容器直接包含的 文本元素 会被包裹成匿名的弹性单元。

主轴(main axis)与交叉轴(cross axis)

主轴与交叉轴始终是相互垂直的关系。

flex-direction

主轴可以通过flex-direction来定义,可以值4个值(默认值是row):

  • row
  • row-reverse
  • column
  • column-reverse

主轴被定义时,交叉轴也会被定义。主轴与交叉轴的位置关系可以看下图:

165962e700f39c4d21555ef3fa9fdb1d.jpeg

(start与end的位置会由writing-mode来定义,上图默认为:从左到右)

示例:

css
.container { display: flex; position: relative; float: left; width: 200px; height: 200px; margin: 10px; border: 1px solid #ddd; } .container1 { flex-direction: row; } .container2 { flex-direction: row-reverse; } .container3 { flex-direction: column; } .container4 { flex-direction: column-reverse; } .item { width: 50px; height: 50px; border: 1px solid #f00; box-sizing: border-box; }
html
<div class="container container1"> <div class="item item1">item1</div> <div class="item item2">item2</div> <div class="item item3">item3</div> </div> <div class="container2"> <div class="item item1">item1</div> <div class="item item2">item2</div> <div class="item item3">item3</div> </div> <div class="container3"> <div class="item item1">item1</div> <div class="item item2">item2</div> <div class="item item3">item3</div> </div> <div class="container4"> <div class="item item1">item1</div> <div class="item item2">item2</div> <div class="item item3">item3</div> </div>

fcb5135ee43b31cf7d29f27f0a33396a.jpeg

从上面的图片可以看出,Flex Item元素是从主轴的start位置到end位置依序排列。

多行分布:flex-wrap

css
.container { display: flex; width: 200px; height: 200px; padding: 10px; border: 1px solid #ddd; } .item { width: 80px; height: 80px; border: 1px solid #f00; }
html
<div class="container"> <div class="item item1">item1</div> <div class="item item2">item2</div> <div class="item item3">item3</div> </div>

2dffb7f1a51d76758e07e1fd8cec4521.jpeg

从上面的例子可以看出,在默认的情况下,Flex Item元素会分布在一行。

如果需要多行的分布,则需要设置Flex Container的flex-wrap属性,可以取3个值(默认值为nowrap)。

  • nowrap
  • wrap
  • wrap-reverse

当设置flex-wrap: wrap;时,溢出的Flex Item元素会沿着交叉轴从start到end依序排列。flex-wrap: wrap-reverse则从end到start依序排列。

css
.container { display: flex; flex-direction: row; width: 200px; height: 200px; padding: 10px; border: 1px solid #ddd; } .container1 { flex-wrap: wrap; } .container2 { flex-wrap: wrap-reverse; } .item { width: 80px; height: 80px; border: 1px solid #f00; }
html
<div class="container container1"> <div class="item item1">item1</div> <div class="item item2">item2</div> <div class="item item3">item3</div> </div> <div class="container container2"> <div class="item item1">item1</div> <div class="item item2">item2</div> <div class="item item3">item3</div> </div>

fb902a8cf3a4ad12e2ab2563b89f0348.jpeg

flex-flow

flex-flowflex-directionflex-wrap的简写形式。

css
.container { display: flex; flex-flow: row wrap; } /* 相当于 */ .container { display: flex; flex-direction: row; flex-wrap: wrap; }

对齐方式

justify-content

justify-content定义了在主轴上如何分配Flex Item元素及其周围的空间。常用取值如下:

  • flex-start
  • flex-end
  • center
  • space-between
  • space-around

c3d9341903ac31f192e5ebff8163e62c.jpeg

justify-content还可取以下值:

  • start
  • end
  • left
  • right
  • baseline
  • first baseline
  • last baseline
  • space-evenly
  • strecth
  • safe center
  • unsafe center

align-items

align-items定义了在交叉轴如何分配Flex Item元素及其周围的空间。常用取值如下:

  • stretch
  • center
  • start
  • end

2d8ae764ada531b64187e454b43f2196.jpeg

当设置为stretch时,Flex Item元素的高度或宽度会被拉伸。

align-items还可取以下值:

  • start
  • end
  • left
  • right
  • self-start
  • self-end
  • first baseline
  • last baseline
  • safe
  • unsafe

align-content

设置了浏览器如何沿着Flex Container的纵轴和网格容器(Grid Container)的主轴在内容项之间和周围分配空间。该属性对单行弹性盒子模型无效。(即:带有flex-wrap: nowrap)

align-self

会对齐当前flex行中的Flex Item元素,并覆盖 align-items的值. 如果任何Flex Item元素的交叉轴方向margin值设置为auto,则会忽略align-self

place-content

align-contentjustify-content的简写。

间隙 gap

row-gap

row-gap定义Flex Item的行间隙

css
.item { row-gap: 10px; }

column-gap

column-gap定义Flex Item的列间隙

css
.item { column-gap: 20px; }

gap

row-gapcolumn-gap的简写。

css
.item { gap: 10px 20px; }

大小

flex-grow

flex-grow定义了Flex Item元素的拉伸因子,值越大,占据的区域越大。

css
.container { display: flex; flex-direction: row; align-items: center; gap: 10px 10px; width: 200px; height: 200px; margin: 10px; border: 1px solid #000; } .item { height: 50px; border: 1px solid #f00; } .item1 { flex-grow: 1; } .item2 { flex-grow: 2; } .item3 { flex-grow: 3; }
html
<div class="container"> <div class="item item1">item1</div> <div class="item item2">item2</div> <div class="item item3">item3</div> </div>

c7a0ba4f5234f9fe10f20e9280c7fd6d.jpeg

flex-shrink

flex-shrink定义了Flex Item元素的收缩规则。Flex Item元素仅在默认宽度之和大于Flex Container的时候才会收缩。值越大,占据的区域越小。

css
.container { display: flex; flex-direction: row; align-items: center; gap: 10px 10px; width: 200px; height: 200px; margin: 10px; border: 1px solid #000; } .item { width: 80px; height: 50px; border: 1px solid #f00; } .item1 { flex-shrink: 1; } .item2 { flex-shrink: 2; } .item3 { flex-shrink: 3; }
html
<div class="container"> <div class="item item1">item1</div> <div class="item item2">item2</div> <div class="item item3">item3</div> </div>

06e699db1be8ff7bbe1c038abcd27acd.jpeg

flex-basis

flex-basis定义了Flex Item元素在主轴方向的初始大小。一般情况下这个属性使用flex-basis: auto;即可。

flex

flex-growflex-shrinkflex-basis的简写。

可取如下值:

  • initial:重置为初始值,相当于:flex: 0 1 auto;
  • auto:相当于:flex: 1 1 auto;
  • none:相当于:flex: 0 0 auto;
  • <number>

flex属性可以指定1个、2个或3个值。

单值:值必须为以下之一:

  • 一个<number>,它会被当作flex-grow的值;
  • 一个有效的宽度值(30px),它会被当作flex-basis的值;
  • 关键字initial、auto或none。

双值:第一个值必须为<number>,并且会被当作flex-grow的值;第二个值必须是以下之一:

  • 一个<number>,它会被当作flex-shrink的值;
  • 一个有效的宽度值(30px),它会被当作flex-basis的值。

三值

  • 第一个值必须为<number>,它会被当作flex-grow的值;
  • 第二个值必须为<number>,它会被当作flex-shrink的值;
  • 第三个必须为一个有效的宽度值(30px)或者auto,它会被当作flex-basis的值。

排序 order

order定义了Flex Item的排序规则。仅对视觉顺序产生作用,并不会影响元素本身的逻辑。值小,则排前;值大,则排后。

不影响弹性盒子的属性

由于弹性盒子使用了不同的布局算法,某些属性用在弹性容器上没有意义:

  • 多栏布局模块的 column-* 属性对弹性项目无效。
  • float 与 clear 对弹性项目无效。使用 float 将使元素的 display 属性计为block。
  • vertical-align 对弹性项目的对齐无效。