本节目标
- 掌握flex-grow的使用。
- 掌握flex-grow放大的计算公式(难点)。
- 掌握编写导航条的技巧。
内容摘要
本篇介绍了项目属性 flex-grow,用于定义项目的扩大系数,用于分配容器的剩余空间。
阅读时间约10~15分钟,文字虽多,但主要都是例子。
flex-grow基础
flex-grow 属性定义项目的扩大系数,用于分配容器的剩余空间,那么什么是剩余空间呢?
其实非常简单,剩余空间计算方式就是:
容器大小 减去 所有项目的总大小
参考如下示例: 其中:
1. 每个项目的宽度为50px,3个为150px。
2. 剩余空间为 450px - 150px = 300px。
语法格式:
.item {
/* >=0 的数,默认值为 0 */
flex-grow: <number>;
}
其中:
1. 默认为 0 ,即如果容器存在剩余空间,也不放大。
2. flex-grow只能为>=0的数字,项目根据设置的系数进行放大。
那么问题就来了:
项目是如何根据设置的系数分配剩余空间呢?
这边涉及到两个关键公式:
1)计算将多少剩余空间拿来分配。
公式:剩余空间 * ( 所有项目的flex-grow之和 >= 1 ? 1 : 所有项目的flex-grow之和 ) 。
这边用了一个三元表达式,理解不难,公式的意思就是说:
如果 所有项目的flex-grow之和 大于等于1,那么就是所有的剩余空间都拿来分配,否则乘以系数即为要分配的剩余空间。
2)计算每个项目分配到多少剩余空间。
公式:要分配的剩余空间 * ( 单个项目flex-grow / 所有项目的flex-grow之和 )
简单的说,就是按照 flex-grow 占比进行分配。
下面我们结合例子进行说明,对这边的计算公式进行理解。
示例1,设置项目的flex-grow为1:
接上一篇例子,有一个div(容器,450px),容器内包含3个div(项目,各50px)。
.item {
/* flex-basis属性定义了项目占据主轴空间(main size)大小。 */
/* 这边设置为50px */
flex-basis: 50px;
/* flex-grow 属性定义项目的扩大系数 */
/* 这边设置为1 */
flex-grow: 1;
}
运行效果: 我们观察到3个项目的宽度都变成了150px,可以看到项目被进行了扩大。
现在套公式看下情况:
1)计算总共要分配多少剩余空间。
要分配的剩余空间
= 剩余空间 * ( 所有项目的flex-grow之和 >= 1 ? 1 : 所有项目的flex-grow之和 )
= 300px * (3 >= 1 ? 1 : 3)
= 300px * 1
= 300px
2)计算每个项目分配到多少剩余空间。
因为每个项目flex-grow都为1,所以每个项目分配的剩余空间都一样。
每个项目分配的剩余空间
= 要分配的剩余空间 * ( 单个项目flex-grow / 所有项目的flex-grow之和 )
= 300px * ( 1 / 3)
= 100px
每个项目多分配100px,加上自身设置的flex-basis,最终每个项目宽度就为150px了。
示例2,设置项目1的flex-grow为1,项目2的flex-grow为2,项目3的flex-grow为3:
我们直接套公式计算:
1)计算总共要分配多少剩余空间。
要分配的剩余空间
= 剩余空间 * ( 所有项目的flex-grow之和 >= 1 ? 1 : 所有项目的flex-grow之和 )
= 300px * (6 >= 1 ? 1 : 6)
= 300px * 1
= 300px
2)计算每个项目分配到多少剩余空间。
因为每个项目flex-grow都不一样,所以每个项目分配的剩余空间要分开计算。
项目1分配的剩余空间
= 要分配的剩余空间 * ( 项目1flex-grow / 所有项目的flex-grow之和 )
= 300px * ( 1 / 6)
= 50px
项目2分配的剩余空间
= 要分配的剩余空间 * ( 项目2flex-grow / 所有项目的flex-grow之和 )
= 300px * ( 2 / 6)
= 100px
项目3分配的剩余空间
= 要分配的剩余空间 * ( 项目3flex-grow / 所有项目的flex-grow之和 )
= 300px * ( 3 / 6)
= 150px
所以最终:项目1宽为100px、项目2宽为150px、项目3宽为200px。
写上代码看看效果:
.item {
/* flex-basis属性定义了项目占据主轴空间(main size)大小。 */
/* 这边设置为50px */
flex-basis: 50px;
}
.item1 {
flex-grow: 1;
}
.item2 {
flex-grow: 2;
}
.item3 {
flex-grow: 3;
}
运行效果: 观察运行效果,符合预期。
示例3:设置项目1的 flex-grow 为 0.1,项目2的 flex-grow 为0.2,项目3的 flex-grow 为 0.3:
这个示例和上例差不多,只是数字变成了小数,并且总和不大于1。
先套公式来计算一下:
1)计算总共要分配多少剩余空间。
要分配的剩余空间
= 剩余空间 * ( 所有项目的flex-grow之和 >= 1 ? 1 : 所有项目的flex-grow之和 )
= 300px * (0.6 >= 1 ? 1 : 0.6)
= 300px * 0.6
= 180px
2)计算每个项目分配到多少剩余空间。
因为每个项目flex-grow都不一样,所以每个项目分配的剩余空间要分开计算。
项目1分配的剩余空间
= 要分配的剩余空间 * ( 项目1flex-grow / 所有项目的flex-grow之和 )
= 180px * ( 0.1 / 0.6)
= 30px
项目2分配的剩余空间
= 要分配的剩余空间 * ( 项目2flex-grow / 所有项目的flex-grow之和 )
= 180px * ( 0.2 / 0.6)
= 60px
项目3分配的剩余空间
= 要分配的剩余空间 * ( 项目3flex-grow / 所有项目的flex-grow之和 )
= 180px * ( 0.3 / 0.6)
= 90px
所以最终:项目1宽为80px、项目2宽为110px、项目3宽为140px。
样式代码如下:
.item {
/* flex-basis属性定义了项目占据主轴空间(main size)大小。 */
flex-basis: 50px;
}
.item1 {
/* flex-grow属性定义项目的放大比例 */
flex-grow: 0.1;
}
.item2 {
/* flex-grow属性定义项目的放大比例 */
flex-grow: 0.2;
}
.item3 {
/* flex-grow属性定义项目的放大比例 */
flex-grow: 0.3;
}
运行效果如下: 符合计算预期。
flow-grow应用
flow-grow属性在项目中运用很多,比如页面布局、导航条、分页等。
实例1:使用 flex 弹性布局实现如下效果: 这个其实就是腾讯首页的导航条了,我们模拟实现一下,步骤分为4步:
1)首先先写html标签,标签很简单一个 nav 包含若干 a 标签:
<nav class="container">
<a class="item" href="#">新闻</a>
<a class="item" href="#">视频</a>
<a class="item" href="#">图片</a>
<a class="item" href="#">军事</a>
<a class="item" href="#">体育</a>
<a class="item" href="#">NBA</a>
<a class="item" href="#">娱乐</a>
<a class="item" href="#">财经</a>
<a class="item" href="#">科技</a>
</nav>
2)设置基本样式,背景、颜色、边框圆角等:
.container {
height: 44px;
background-color: #1479d7;
border-radius: 3px;
}
.item {
color: white;
text-align: center;
text-decoration: none;
}
运行效果: 3)设置容器为 flex 布局,项目 flex-grow 为1 平分剩余空间:
.container {
/* 设置子元素的布局为flex布局 */
display: flex;
}
.item {
/* 设置项目放大系数 */
flex-grow: 1;
}
运行效果: 4)再来一个上下居中即可,flex 弹性布局将容器属性 align-items 设置为 center 即可:
.container {
/* 设置交叉轴上项目居中排列 */
align-items: center;
}
运行效果: 至此这个例子就完成了。
和之前使用float相比,我们尝试改变容器大小,会发现项目也跟着变化,这个就是弹性的意思了。如下图所示:
本节总结
容器内未被占用的空间称为剩余空间。
flex-grow用于设置项目的放大系数。
项目放大尺寸计算包含两个公式:
1)计算将多少剩余空间拿来分配。
公式:剩余空间 * ( 所有项目的flex-grow之和 >= 1 ? 1 : 所有项目的flex-grow之和 ) 。
2)计算每个项目分配到多少剩余空间。
公式:要分配的剩余空间 * ( 单个项目flex-grow / 所有项目的flex-grow之和 )
- flex-grow不是设置具体的尺寸,在弹性布局中应用广泛。