伸缩布局 Flex

布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性。

它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。

Flex( flexible box,弹性布局 ),一般称之为弹性盒模型,是 CSS3 引入的一种新的布局模型。它提供了一种更加有效的方式来进行容器内的项目布局,以适应各种类型的显示设备与不同尺寸的屏幕。

它可以实现多行自适应、多列自适应、间距自适应、任意对齐。

与其他属性不同的是,flex 并不是一个属性,而是一个模块,包含多个CSS属性。


弹性盒模型:块级伸缩容器 | 内联伸缩容器

[ 版本更迭?!] 要让一个元素变成伸缩容器,需要使用 display 属性。

[ FFC?! ] 设为 Flex 布局以后,子元素的floatclearvertical-align属性将失效。

display: flex | inline-flex;            // 新版本

   display:flexbox | inline-flexbox;       // 混合版本
   display:box | inline-box;               // 旧版本

如:
// 任何一个容器都可以指定为 Flex 布局
   .box{display:flex;}     

// 行内元素也可以使用 Flex 布局
   .box{display:inline-flex;}    

// Webkit 内核的浏览器,必须加上-webkit前缀。
   .box{
     display: -webkit-flex; /* Safari */
     display: flex;
   }

// 代码示例

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<style>
		.parent{
			/*width: 800px;*/
			height: 500px;
			background-color: pink;
			display: flex;                  /*flex布局模式*/
		}
		.child1,.child3{flex: 1;}
		.child2{flex: 2;}

		.child1{background-color: red;}
		.child2{background-color: green;}
		.child3{background-color: blue;}
	</style>
</head>
<body>
	<div class="parent">               <!-- 伸缩容器 -->
		<div class="child1"></div>        <!-- 伸缩项目 -->
		<div class="child2"></div>        <!-- 伸缩项目 -->
		<div class="child3"></div>        <!-- 伸缩项目 -->
	</div>
</body>
</html>

布局应用?!] 采用 Flex 布局的元素,称为 Flex 容器(flex container),简称"容器"。

它的所有子元素自动成为容器成员,称为 Flex 项目(flex item),简称"项目"。


[1] Flex 容器( flex container ):即,采用 flex 布局的元素

  • 方向 — flex 容器默认存在两条轴:水平方向的主轴( main axis )和垂直方向的侧轴( cross axis )
  • 主轴方向不一定是水平的,它主要取决于 flex-direction 属性

[2] Flex 项目( flex item ):即,容器内的子元素                        // 伸缩项目默认沿主轴排列

  • main start - 主轴起点 | main end - 主轴终点   &   cross start - 侧轴起点 | cross end - 侧轴终点
  • 单个伸缩项目所占据的:主轴空间 - main size  /  侧轴空间 - cross size

Flex 容器:伸缩流 & 对齐方式

在 flex 容器上可以设置的属性有以下 6 个:

  • 伸缩流(包括方向与换行) flex-flow
    • 伸缩流方向 flex-direction
    • 伸缩流换行 flex-wrap
  • 对齐方式
    • 主轴对齐 justify-content
    • 侧轴对齐 align-items
    • 堆栈伸缩行 align-content

[ 伸缩流方向 ]指定主轴的方向( 即,项目在容器中的排列方向 )

// 新版本,同混合版本
   flex-direction: row(默认)| row-reverse | column | column-reverse
                   水平方向        反向水平    垂直方向     反向垂直

// 旧版本
   box-orient: horizontal | vertical(垂直) |inline-axis(默认)| block-axis
                水平方向        垂直方向         内联轴方向         块级轴方向
   box-direction: normal | reverse      // 正常 | 反向

[ 伸缩流换行 ]指定伸缩项目溢出伸缩容器时是否换行                        // 允许使用overflow处理溢出内容

// 新版本,同混合版本
   flex-wrap: nowrap[默认] | wrap | wrap-reverse
                不换行        换行     反转换行

// 旧版本:没有浏览器支持box-lines属性,所以,在旧版本中无法实现伸缩项目换行显示
   box-lines: single[默认] | multiple | N/A

// CSS允许使用overflow属性来处理溢出内容的显示方式

[ 伸缩流 ]伸缩流方向与伸缩行换行的缩写

//新版本同混合版本
  flex-flow: <flex-direction> | <flex-wrap>           // 默认值 flex-flow: row nowrap

//旧版本无对应属性

[ 主轴对齐 ]设置伸缩容器当前行伸缩项目在主轴方向的对齐,指定如何在伸缩项目之间分布伸缩容器额外空间

当一行上的所伸缩项目不能伸缩或可伸缩已达到最大长度时,这一属性才会对伸缩容器额外空间进行分配。

当伸缩项目溢出某一行时,这一属性也会在项目的对齐上施加一些控制。

// 新版本
   justify-content: flex-start[默认] | center | flex-end | space-between | space-around
                        左对齐         居中对齐    右对齐        两端对齐        扩散对齐

// 混合版本
   flex-pack: start[默认] | center | end | justify | distribute

// 旧版本
   box-pack: start[默认] | center | end | justify | N/A

[ 侧轴对齐 ]用来设置伸缩容器当前行在侧轴方向的对齐方式

// 新版本
   align-items: flex-start | center | flex-end | baseline | stretch[默认]
                 顶端对齐     中间对齐   底部对齐     基线对齐    伸缩项目拉伸填充整个伸缩容器 
// 混合版本
   flex-align: start | center | end | baseline | stretch[默认]

// 旧版本
   box-align: start | center | end | baseline | stretch[默认]

注意:如果伸缩项目有width/height属性将优先于侧轴对齐为拉伸的方式

[ 堆栈伸缩行 ]指定多个伸缩项目行在侧轴的对齐方式

该属性只有在 flex-wrap:wrap | wrap-reverse,且伸缩项目存在多行时才生效。

// 新版本
   align-content: flex-start | center | flex-end | space-between | space-around | stretch[默认]
                   顶边对齐     中间对齐   底部对齐       两端对齐         扩散对齐      伸缩项目拉伸填充整个伸缩容器    
// 混合版本
   flex-line-pack: start | center | end | justify | distribute | stretch[默认]

//旧版本无对应属性

Flex 项目:伸缩性 & 显示顺序

[ 匿名伸缩项目 ] 一个伸缩项目就是伸缩容器的一个子元素。

伸缩容器中的文本也被视为一个伸缩项目 — 浏览器会将任何直接在伸缩容器中的连续文字块包裹为匿名伸缩项目。


在伸缩项目上可以设置的属性主要有以下 6 个:

  • 自身侧轴对齐方式 align-self
  • 伸缩性 flex
    • 伸缩基准值 flex-basis
    • 扩展比率 flex-grow
    • 收缩比率 flex-shrink
  • 显示顺序 order

[ 自身侧轴对齐方式 ]单个伸缩项目在侧轴的对齐方式,该属性可以覆盖伸缩容器的侧轴对齐方式

对于匿名伸缩项目,align-self的值永远与其关联的伸缩容器的align-items的值相同

// 新版本
   align-self: auto[默认] | flex-start | center | flex-end | baseline | stretch
                自动          顶边对齐    中间对齐   底部对齐    基线对齐     伸缩项目拉伸填充这个伸缩容器

// 混合版本
   flex-item-align: auto[默认] | start | center | end | baseline | stretch

//旧版本无对应属性

注意:
  1. 如果align-self的值为auto,则其计算值为伸缩项目的伸缩容器的align-items值
  2. 如果伸缩项目的任一个侧轴上的外边距为auto,则该伸缩项目在伸缩容器的剩余空间内居中对齐,且align-self没有效果。

[ 伸缩基准值 ]伸缩项目在主轴方向上的初始大小

  • 如果flex-basis的值为0,表示伸缩项目在主轴方向上的初始大小为0,分配所有空间;
  • 如果flex-basis的值为auto,表示伸缩项目在主轴方向上的初始大小为设置宽度 ( 如果没有设置宽度,则为内容宽度 ),再分配剩余空间。
// 新版本
   flex-basis: <length> | auto[默认]         // 规定元素的初始长度

// 混合版本
   positive-flex: <number>[默认为1]

//旧版本无对应属性

注意:flex-basis的<length>值可以是一个数字后面跟着px、em等单位,也可以是一个百分数,相对于其父伸缩容器的主轴长度。

[ 扩展比率 ]当伸缩容器的额外空间为正值时,此伸缩项目相对伸缩容器里其他伸缩项目能扩展的空间比例

  • 若flex-grow的值为0,表示即使存在剩余空间也不放大;
  • 若所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话);
  • 若一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。
// 新版本
   flex-grow: <number>[默认为0]

// 混合版本
   positive-flex: <number>[默认为0]

// 旧版本无对应属性

[ 收缩比率 ]当伸缩容器的额外空间为负值时,此伸缩项目相对于伸缩容器里其他伸缩项目能收缩的空间比例。

  • 如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。
  • 如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。
// 新版本
   flex-shrink: <number>[默认为1]

// 混合版本
   negative-flex: <number>[默认为0]

// 旧版本无对应属性

注意:伸缩基准值、扩展比率和收缩比率都可以为小数,但不能为负数。

[ 伸缩性 ]伸缩基准值、扩展比率和收缩比率的缩写

// 新版本
   flex: none | [<flex-grow> <flex-shrink>? || <flex-basis>]

// 混合版本
   flex: none | [<pos-flex> <neg-flex>? || <preferred-size>]

// 旧版本
   box-flex: <number>
  • 当 flex 为关键字 none 或存在 auto 时,flex-basis 为 auto;
  • 若 flex 只有数字值,则 flex-basis 为 0%;
flex: none  ————  flex: 0 0 auto;  //表示宽度为原始宽度,不发生扩展或收缩
flex: auto  ————  flex: 1 1 auto;  //表示除了占据原先的宽度外,还要分配剩余宽度(包括扩展或收缩)
flex: 0  ————  flex: 0 1 0%;  //表示收缩为最小宽度
flex: 1  ————  flex: 1 1 0%;  //表示分配所有宽度(包括扩展或收缩)
flex: 0 auto  ————  flex: 0 1 auto;(默认值)  //表除了占据原先的宽度外,还要分配剩余宽度(只收缩,不扩展)
flex: 0 1  ————  flex: 0 1 0%;

[ 显示顺序 ]定义伸缩项目的排列顺序,数值越小,排列越靠前

伸缩容器中的伸缩项目默认显示顺序是遵循文档在源码中出现的先后顺序( HTML文档的DOM结构中的先后顺序 )

// 新版本
   order: <number>[默认为0]
// 混合版本
   flex-order: <number>[默认为0]
// 旧版本
   box-ordinal-group: <integer>[默认为1]

注意:order的属性值可以是负数,但不能是小数。