Flexbox学习笔记-flex项目属性

605 阅读6分钟

Flexbox是一种当页面需要适应不同的屏幕大小以及设备类型时确保元素拥有恰当的行为的布局方式。引入弹性盒布局模型的目的是提供一种更加有效的方式来对一个容器中的子元素进行排列、对齐和分配空白空间。

浏览器支持


flex项目属性

flex属性


flex属性是用于设置弹性盒子的子元素如何分配空间。
flex 属性是 flex-grow、flex-shrink 和 flex-basis 属性的简写属性。

    flex: flex-grow flex-shrink flex-basis|auto|initial|inherit;

    flex: auto; 等价于 flex: 1 1 auto;  
    flex: none; 等价于 flex: 0 0 auto;  
    flex: init; 等价于 flex: 0 1 auto;  

flex属性和弹性盒子(父元素)在主轴上的剩余空间有关。

- flex-grow

属性用于设置或检索弹性盒子的扩展比率。 简单说就是父元素(弹性盒子)的剩余空间的分配比率。

    flex-grow: number|initial|inherit;  

default: 0
例如:只有子元素使用flex-grow

    <div class="container">
	<div class="left">left</div>
	<div class="main">主要内容</div>
	<div class="right">right</div>
    </div>
    
        .left, .right{
		width: 100px;
		height: 100px;
		background: #ccc;
	}
	.container{
		display: flex;
		flex-direction: row;
		height: 100px;
		width: 500px;
		border: 1px solid blue;
		margin-left: 50px;
		margin-top: 50px;
	}
	.main{
		flex-grow: 1;
    }

图1

如上图所示:剩余空间 = 500 - 100*2 = 300,而.main设置了flex-grow: 1; .main占据了所有的剩余空间。

例:多个子元素使用flex-grow
样式设置如下,.main和.right都使用flex-grow属性把弹性盒子的剩余空间分成3份,其中.main占据2份,.right占据1份。图2是应用该样式的结果。从图2看出除了本身的100px的宽度之外,还占据了剩余空间的一部分。

        .right{
		flex-grow: 1;
		text-align: right;
	}
	.main{
		flex-grow: 2;
	}

图2

根据图3很清楚的看出.main除去占据剩余空间的2份外,本身文本也自动有了宽度,所以:
.mian的宽度 = .mian文本的宽度 + 2份剩余空间
.right的宽度 = 本身的100px宽度 + 1份剩余空间
图3
:flex-grow可应用于动画显示。js设置object.style.flexGrow="5"

- flex-basis

flex-basis 属性用于设置或检索弹性盒伸缩基准值。

flex-basis: number|auto|initial|inherit;

flex-basis和width类似,flex-basis主要是预设了主轴方向的大小,弹性盒子的剩余空间要减去flex-basis的带下余下的才是真正的剩余空间。

        .left, .right{
		flex-basis: 100px;
		background: #12fda3;
	}
	main{
		flex-grow: 1;
	}

如上图可见,.left和.right设置flex-basis:100px和设置width:100px效果一样(见图1)。

  • 如果子元素同时设置了width和flex-basis属性,则width会被覆盖;

  • 如果flex-basis和width两者中有个一个设置了auto,则非auto的属性优先级高;

  • 如果flex-basis和width都设置了auto,则根据文本填充的大小为大小。

      .flex-left, .flex-right{
      	width: 50px;
      	flex-basis: 100px;
      	background: #12fda3;
      }
    

        .flex-left, .flex-right{
		width: 50px;
		flex-basis: auto;
		background: #12fda3;
	}

        .flex-left, .flex-right{
		width: auto;
		flex-basis: auto;
		background: #12fda3;
	}

- flex-shrink

flex-shrink 属性指定了 flex 元素的收缩规则。flex 元素仅在默认宽度之和大于容器的时候才会发生收缩,其收缩的大小是依据 flex-shrink 的值。
default: 1

flex-shrink: number|initial|inherit;

(1)不设置flex-shrink

        .container2{
		display: flex;
		flex-direction: row;
		height: 100px;
		width: 500px;
		border: 1px solid blue;
		margin-left: 50px;
		margin-top: 50px;
	}
        .container2>div{
		flex-basis: 120px;
	}
	.container2>.section1{ background: red; }
	.container2>.section2{ background: lightblue; }
	.container2>.section3{ background: lightgreen; }
	.container2>.section4{ background: gray; }
	.container2>.section5{ background: pink; }
	
    <div class="container2">
	<div class="section1 shrink1">section1</div>
	<div class="section2 shrink1">section2</div>
	<div class="section3 shrink1">section3</div>
	<div class="section4 shrink2">section4</div>
	<div class="section5 shrink2">section5</div>
    </div>

根据代码,父容器的宽度是500px,而每个子元素section都预设了120px的宽度,子元素的总宽度大于父容器的宽度,但是根据图来看,每个子元素实际的宽度是100px(包含border的宽度),并没有超出总宽度。

再看:

        .container2>.section1{ flex-basis: 150px; background: red; }
	.container2>.section2{ background: lightblue; }
	.container2>.section3{ background: lightgreen; }
	.container2>.section4{ background: gray; }
	.container2>.section5{ background: pink; }

这两个图看出了,section1要比section2\3\4\5都大,但是又不等于150px;

子元素总宽度:150 + 120 + 120 + 120 + 120 = 630
section1占据比例宽度:500 * 150/630 = 119.0476
section2占据比例宽度:500 * 120/630 = 95.2380
section3占据比例宽度:500 * 120/630 = 95.2380
section4占据比例宽度:500 * 120/630 = 95.2380
section5占据比例宽度:500 * 120/630 = 95.2380
正好是实际的宽度。

再看:

        .container2>div{
		flex-basis: 120px;
	}
	.container2>.section1{ flex-basis: 150px; background: red; }
	.container2>.section2{ background: lightblue; }
	.container2>.section3{ flex-basis: 80px; background: lightgreen; }
	.container2>.section4{ background: gray; }
	.container2>.section5{ background: pink; }

根据上述公式计算section3的宽度:
500 * 80/590 = 67.7966
和实际结果符合。

由此可见:width|flex-basis属性本身就有按比例分配规则。

(2)设置flex-shrink

        .container2>.section1{ background: red; }
	.container2>.section2{ background: lightblue; }
	.container2>.section3{ background: lightgreen; }
	.container2>.section4{ background: gray; }
	.container2>.section5{ background: pink; }
	.shrink1{ flex-shrink: 1; }
	.shrink2{ flex-shrink: 2; }
	
	<div class="container2">
	<div class="section1 shrink1">section1</div>
	<div class="section2 shrink1">section2</div>
	<div class="section3 shrink1">section3</div>
	<div class="section4 shrink2">section4</div>
	<div class="section5 shrink2">section5</div>
	</div>

分析:
本例中section1、section2、section3 显式定义了 flex-shrink 为 1,section4、section5 定义了 flex-shrink 为 2,所以计算出来总共将剩余空间分成了 7 份,其中 section1、section2、section3占 1 份,section4、section5 占 2 份,即收缩比例为1:1:1:2:2。 section1收缩比例:1/7
section2收缩比例:1/7
section3收缩比例:1/7
section4收缩比例:2/7
section5收缩比例:2/7
父容器定义为 500px,子项被定义为 120px,子项相加之后即为 600 px,超出父容器 100px。
于是我们可以计算section1/2/3/4/5 将被移除的溢出量是多少:
section1收缩宽度:100 * 1/7 = 14.28
section2收缩宽度:100 * 1/7 = 14.28
section3收缩宽度:100 * 1/7 = 14.28
section4收缩宽度:100 * 2/7 = 28.57
section5收缩宽度:100 * 2/7 = 28.57
最后: section1实际宽度:120 - 14.28 = 105.72 section2实际宽度:120 - 14.28 = 105.72
section3实际宽度:120 - 14.28 = 105.72
section4实际宽度:120 - 28.57 = 91.43
section5实际宽度:120 - 28.57 = 91.43

o(╥﹏╥)o貌似多出了0.02...,先这样吧。。。

如有错误,请指出。