CSS Flex 项目属性
项目属性管弹性
容器属性管整体布局,这一篇讲写在项目上的属性。它们解决同一类问题,项目怎么瓜分空间、怎么排序、怎么单独对齐。核心有三个,flex-grow、flex-shrink、flex-basis,后面跟着两个小帮手,align-self 和 order。
flex-grow,放大瓜分剩余空间
flex-grow 管的是容器有剩余空间时,项目按什么比例放大。默认值是 0,意思是即使有剩余空间,项目也不放大。
三个项目 flex-grow 分别是 1、1、2,剩余空间会被分成四份,前两个各拿一份,最后一个拿两份。数字不必是整数,0.5 也可以。
注意 flex-grow 分配的是剩余空间,不是整个宽度,项目原本的内容宽度不会被重新分配。三个项目全写 0,剩余空间就空着,谁都不拿。
flex-shrink,缩小应对空间不足
flex-shrink 和 flex-grow 相反,空间不够时按比例缩小。默认值是 1,所以上一篇说的压缩行为,其实是默认值造成的。
把某个项目设成 0,它在空间不足时也不会被压缩,宁可撑破容器也不牺牲自己。
典型场景是带 logo 的导航,logo 被压扁很难看,让它固定不动,让其他链接去承担缩小。
flex-basis,基准尺寸
flex-basis 定义项目在放大和缩小之前的基准尺寸。默认值 auto,意思是优先用 width 的值,没写 width 就用内容宽度。
给 flex-basis 设一个具体的像素值或百分比,相当于给它一个虚拟的初始宽度,之后的放大缩小都基于这个值。
三个属性分开讲完了,放在一个例子里对比更直观。
.item-a {
flex-grow: 1; /* 剩余空间拿 1 份 */
}
.item-b {
flex-grow: 1; /* 剩余空间拿 1 份 */
}
.item-c {
flex-grow: 2; /* 剩余空间拿 2 份 */
}
.item-logo {
flex-shrink: 0; /* logo 永远不缩小 */
}
.sidebar {
flex-basis: 200px; /* 基准 200px,放得下就不变 */
}
和 width 的区别在于,flex-basis 会参与弹性计算。空间充足时项目可以长得比基准大,空间不足时可以缩得比基准小,width 是死值,不参与这套弹性逻辑。
flex 简写
三个属性分开写太啰嗦,实际开发几乎都用简写 flex。三个常用组合必须背下来。
| 简写 | 展开 | 记忆点 |
|---|---|---|
| flex: 1 | flex-grow 1,flex-shrink 1,flex-basis 0% | 均分剩余空间 |
| flex: auto | flex-grow 1,flex-shrink 1,flex-basis auto | 按内容自适应 |
| flex: none | flex-grow 0,flex-shrink 0,flex-basis auto | 尺寸固定不变 |
flex: 1 最常用,三个项目都写 flex: 1,剩余空间均分,效果等同均分整行。flex: auto 在空间不足时会被压缩,flex: none 则完全拒绝变化,适合头像、图标这类固定元素。
记忆口诀,none 拒绝变化,1 全都要,auto 看内容。
.item {
flex: 1; /* 等价于 flex: 1 1 0%,均分剩余空间 */
}
.fixed {
flex: none; /* 等价于 flex: 0 0 auto,尺寸固定 */
}
align-self,单独对齐
align-self 允许单个项目脱离容器的 align-items 规则,自己定交叉轴对齐方式。默认值 auto,意思是继承容器的设置。
.toolbar {
display: flex;
align-items: center; /* 默认都居中 */
}
.toolbar .icon {
align-self: flex-start; /* 这个图标顶到上方 */
}
常见场景是混排,大部分项目垂直居中,唯独某个图标要对齐顶部,写 align-self 一次搞定,不用为它单独包一层容器。
order,调整视觉顺序
order 调整项目的显示顺序,默认值 0,数值小的排前面,负数排得更靠前。它只改变视觉顺序,DOM 顺序不变。
屏幕阅读器按 DOM 顺序朗读,所以 order 重排后的页面,读出来的顺序是乱的。能用 DOM 顺序解决就别用 order,实在要用也要确认无障碍场景可接受。
经典导航栏示例
把上面所有属性串起来,做一个经典导航栏,logo 在左,链接居中,按钮在右。
<nav class="navbar">
<a href="#" class="logo">Logo</a>
<ul class="links">
<li><a href="#">首页</a></li>
<li><a href="#">教程</a></li>
<li><a href="#">关于</a></li>
</ul>
<a href="#" class="btn">登录</a>
</nav>
.navbar {
display: flex;
align-items: center; /* 三块内容垂直居中 */
}
.links {
display: flex;
flex: 1; /* 链接区吃掉中间所有空间 */
justify-content: center; /* 链接在中间区域里居中 */
}
.btn {
flex: none; /* 按钮尺寸保持原样 */
}
链接区 flex: 1 吃掉剩余空间,把 logo 顶到左端,把按钮顶到右端,链接自己再居中,一个布局三行代码搞定。这里用到的 CSS 属性关键字其实都学过了,auto 和 0 的含义,和别处一模一样。
小结
flex-grow 管放大,flex-shrink 管缩小,flex-basis 管基准,三个配合的简写记住 flex: 1、flex: auto、flex: none 就够了。align-self 负责单兵作战,order 负责悄悄换位。下一篇进入实战,把这四篇的知识用在真实布局里。