Flex(弹性盒子)布局是CSS3中的一种新的布局模式,它提供了一种更加高效和简洁的方法来布局、对齐和分配容器中项目之间的空间,即使它们的大小是未知或动态变化的。

一、基本概念

Flex布局涉及两个主要角色:容器(flex container)和项目(flex item)。

1. 容器(flex container)

通过设置display属性为flexinline-flex来创建flex容器:

  1. .container {
  2. display: flex; /* 块级flex容器 */
  3. /* 或 */
  4. display: inline-flex; /* 行内flex容器 */
  5. }

注意事项

  • 设为flex容器后,子元素的floatclearvertical-align属性将失效
  • 块级flex容器会独占一行,而inline-flex容器则不会

2. 项目(flex item)

容器的直接子元素自动成为flex项目。

二、容器属性

1. flex-direction

定义主轴的方向,即项目的排列方向。

  1. .container {
  2. flex-direction: row | row-reverse | column | column-reverse;
  3. }
  • row(默认值):主轴为水平方向,起点在左端
  • row-reverse:主轴为水平方向,起点在右端
  • column:主轴为垂直方向,起点在上端
  • column-reverse:主轴为垂直方向,起点在下端

示例

  1. /* 水平从左到右排列(默认) */
  2. .container {
  3. display: flex;
  4. flex-direction: row;
  5. }
  6. /* 垂直从上到下排列 */
  7. .container {
  8. display: flex;
  9. flex-direction: column;
  10. }

2. flex-wrap

定义当一行放不下时是否换行以及如何换行。

  1. .container {
  2. flex-wrap: nowrap | wrap | wrap-reverse;
  3. }
  • nowrap(默认值):不换行,可能导致溢出
  • wrap:换行,第一行在上方
  • wrap-reverse:换行,第一行在下方

示例

  1. /* 不换行(默认) */
  2. .container {
  3. display: flex;
  4. flex-wrap: nowrap;
  5. }
  6. /* 换行,第一行在上方 */
  7. .container {
  8. display: flex;
  9. flex-wrap: wrap;
  10. }

3. flex-flow

flex-directionflex-wrap的简写形式。

  1. .container {
  2. flex-flow: <flex-direction> || <flex-wrap>;
  3. }

示例

  1. /* 等同于设置flex-direction: row和flex-wrap: wrap */
  2. .container {
  3. display: flex;
  4. flex-flow: row wrap;
  5. }

4. justify-content

定义项目在主轴上的对齐方式。

  1. .container {
  2. justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
  3. }
  • flex-start(默认值):左对齐
  • flex-end:右对齐
  • center:居中
  • space-between:两端对齐,项目之间的间隔相等
  • space-around:每个项目两侧的间隔相等,项目之间的间隔比项目与边缘的间隔大一倍
  • space-evenly:每个项目两侧的间隔完全相等

示例

  1. /* 居中对齐 */
  2. .container {
  3. display: flex;
  4. justify-content: center;
  5. }
  6. /* 两端对齐 */
  7. .container {
  8. display: flex;
  9. justify-content: space-between;
  10. }

5. align-items

定义项目在交叉轴上的对齐方式。

  1. .container {
  2. align-items: flex-start | flex-end | center | baseline | stretch;
  3. }
  • stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度
  • flex-start:交叉轴的起点对齐
  • flex-end:交叉轴的终点对齐
  • center:交叉轴的中点对齐
  • baseline:项目的第一行文字的基线对齐

示例

  1. /* 垂直居中 */
  2. .container {
  3. display: flex;
  4. align-items: center;
  5. }
  6. /* 顶部对齐 */
  7. .container {
  8. display: flex;
  9. align-items: flex-start;
  10. }

6. align-content

定义多根轴线的对齐方式,只有当flex-wrap: wrap时才有效。

  1. .container {
  2. align-content: flex-start | flex-end | center | space-between | space-around | stretch;
  3. }
  • stretch(默认值):轴线占满整个交叉轴
  • flex-start:与交叉轴的起点对齐
  • flex-end:与交叉轴的终点对齐
  • center:与交叉轴的中点对齐
  • space-between:与交叉轴两端对齐,轴线之间的间隔平均分布
  • space-around:每根轴线两侧的间隔相等

示例

  1. /* 多行垂直居中 */
  2. .container {
  3. display: flex;
  4. flex-wrap: wrap;
  5. align-content: center;
  6. height: 400px;
  7. }

三、项目属性

1. order

定义项目的排列顺序,数值越小,排列越靠前,默认为0。

  1. .item {
  2. order: <integer>;
  3. }

示例

  1. /* 第一个项目排最后 */
  2. .item:first-child {
  3. order: 1;
  4. }
  5. /* 最后一个项目排最前 */
  6. .item:last-child {
  7. order: -1;
  8. }

2. flex-grow

定义项目的放大比例,默认为0(即如果存在剩余空间,也不放大)。

  1. .item {
  2. flex-grow: <number>;
  3. }

示例

  1. /* 第二个项目将占据剩余空间的2/3,第三个项目将占据剩余空间的1/3 */
  2. .item:nth-child(2) {
  3. flex-grow: 2;
  4. }
  5. .item:nth-child(3) {
  6. flex-grow: 1;
  7. }

3. flex-shrink

定义项目的缩小比例,默认为1(即如果空间不足,该项目将缩小)。

  1. .item {
  2. flex-shrink: <number>;
  3. }

示例

  1. /* 第一个项目不缩小 */
  2. .item:first-child {
  3. flex-shrink: 0;
  4. }
  5. /* 第二个项目的缩小比例为其他项目的两倍 */
  6. .item:nth-child(2) {
  7. flex-shrink: 2;
  8. }

4. flex-basis

定义在分配多余空间之前,项目占据的主轴空间,默认值为auto(即项目的本来大小)。

  1. .item {
  2. flex-basis: <length> | auto;
  3. }

示例

  1. /* 设置项目的基础宽度为200px */
  2. .item {
  3. flex-basis: 200px;
  4. }

5. flex

flex-grow, flex-shrinkflex-basis的简写,默认值为0 1 auto

  1. .item {
  2. flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ];
  3. }

示例

  1. /* 放大比例为1,缩小比例为1,基础大小为0% */
  2. .item {
  3. flex: 1;
  4. }
  5. /* 放大比例为2,缩小比例为1,基础大小为100px */
  6. .item {
  7. flex: 2 1 100px;
  8. }

6. align-self

允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。

  1. .item {
  2. align-self: auto | flex-start | flex-end | center | baseline | stretch;
  3. }

示例

  1. /* 第三个项目垂直居中对齐 */
  2. .item:nth-child(3) {
  3. align-self: center;
  4. }

四、常见布局实例

1. 等高布局

  1. .container {
  2. display: flex;
  3. }
  4. .item {
  5. flex: 1;
  6. }

2. 居中布局

  1. .container {
  2. display: flex;
  3. justify-content: center; /* 水平居中 */
  4. align-items: center; /* 垂直居中 */
  5. height: 300px;
  6. }

3. 移动端导航栏

  1. nav {
  2. display: flex;
  3. }
  4. nav a {
  5. flex: 1;
  6. text-align: center;
  7. padding: 10px;
  8. }

4. 圣杯布局(三栏布局)

  1. .container {
  2. display: flex;
  3. }
  4. .main {
  5. flex: 1;
  6. order: 2;
  7. }
  8. .left {
  9. width: 200px;
  10. order: 1;
  11. }
  12. .right {
  13. width: 200px;
  14. order: 3;
  15. }

五、注意事项与最佳实践

  1. 浏览器兼容性

    • 现代浏览器都支持Flex布局,但IE10和IE11只部分支持,且有一些已知问题
    • 对于需要兼容旧版浏览器的项目,应考虑使用前缀或降级处理
  2. 嵌套使用

    • Flex容器内部可以再嵌套Flex容器,形成复杂布局
    • 嵌套使用时需注意主轴和交叉轴的变化
  3. 性能考虑

    • 频繁改变Flex项目的顺序可能导致性能问题
    • 对于需要频繁重排的场景,应谨慎使用
  4. 结合其他布局技术

    • Flex布局可以与Grid布局、传统布局等结合使用
    • 根据实际需求选择最合适的布局技术
  5. 避免固定高度

    • 尽可能使用flex-growflex-shrink来控制项目大小,而不是硬编码尺寸
    • 这样可以使布局更加灵活,适应不同的屏幕和内容
  6. 调试工具

    • 使用浏览器开发者工具中的Flex布局可视化功能来调试
    • Chrome和Firefox的开发者工具都提供了这方面的支持

六、总结

Flex布局是现代网页设计中不可或缺的技术,它的灵活性和强大功能使得复杂的布局变得简单。通过掌握容器属性和项目属性,可以轻松实现各种常见和复杂的布局需求。随着浏览器兼容性的提高,Flex布局已成为前端开发的标准实践。