概念

在 CSS 中,display: flex 是一种布局模型,用于创建弹性盒子(flexbox)。它定义了一个容器元素及其子元素的布局方式,使其能够更灵活地调整和排列内容。

使用 display: flex 可以将一个容器元素转换为弹性盒子,并控制其中子元素的排列方式、对齐方式以及伸缩行为。

下面是一个示例,展示了如何使用 display: flex

<div class="container">
  <div class="item">Item 1</div>
  <div class="item">Item 2</div>
  <div class="item">Item 3</div>
</div>
.container {
  display: flex;
}

在上面的示例中,将一个 <div> 元素的 display 属性设置为 flex,将其转换为一个弹性盒子。

使用 display: flex 后,弹性盒子中的子元素(.item)可以按照一定的规则进行排列,默认情况下它们将水平排列。弹性盒子还具有一些属性和值,用于控制子元素的布局和行为。

常见属性

父元素属性

以下是一些常用的弹性盒子属性(父元素属性):

  • flex-direction:指定子元素的排列方向,可以是 row(水平方向,默认值)、column(垂直方向)、row-reverse(水平反向)或 column-reverse(垂直反向)。

  • justify-content:指定子元素在主轴上的对齐方式,可以是 flex-startflex-endcenterspace-betweenspace-around 等。

  • align-items:指定子元素在交叉轴上的对齐方式,可以是 flex-startflex-endcenterbaselinestretch 等。

    • 主轴(main axis)和交叉轴(cross axis)。它们用于定义弹性盒子内部元素的排列方式。
    1. 主轴(Main Axis):
    • 主轴是弹性盒子的主要方向,决定了弹性盒子内元素的水平或垂直排列方式。
    • 默认情况下,主轴的方向是水平的,从左到右排列(即从起始边(start)到结束边(end))。
    • 通过设置 flex-direction 属性,可以改变主轴的方向,可以使其为水平方向(rowrow-reverse)或垂直方向(columncolumn-reverse)。
    1. 交叉轴(Cross Axis):
    • 交叉轴是与主轴垂直的轴线,与主轴形成一个交叉的关系。
    • 交叉轴的方向取决于主轴的方向。如果主轴是水平方向,那么交叉轴就是垂直方向;如果主轴是垂直方向,那么交叉轴就是水平方向。
    • 交叉轴的起始边和结束边与主轴的起始边和结束边相对应。
  • flex-wrap:指定子元素是否换行,可以是 nowrap(不换行,默认值)、wrap(换行)或 wrap-reverse(反向换行)。

  • align-content:指定多行子元素在交叉轴上的对齐方式,只在存在多行时生效,可以是 flex-startflex-endcenterspace-betweenspace-around 等。

总结:

.container {
  display: flex;              /* 开启 flex 布局 */
  flex-direction: row;        /* 主轴方向 row | row-reverse | column | column-reverse */
  justify-content: flex-start;/* 主轴对齐方式 flex-start | flex-end | center | space-between | space-around | space-evenly */
  align-items: stretch;       /* 交叉轴对齐 flex-start | flex-end | center | baseline | stretch */
  flex-wrap: nowrap;          /* 是否换行 nowrap | wrap | wrap-reverse */
  align-content: stretch;     /* 多根轴线的对齐方式 flex-start | flex-end | center | space-between | space-around | stretch */
}

子元素属性

.item {
  flex: 1;              /* flex-grow, flex-shrink, flex-basis 的缩写 */
  order: 0;             /* 排列顺序,数值小的在前 */
  align-self: auto;     /* 单个子元素交叉轴对齐方式,覆盖父元素 align-items */
  
  /* 拆开写: */
  flex-grow: 1;         /* 放大比例,默认 0 */
  flex-shrink: 1;       /* 缩小比例,默认 1 */
  flex-basis: auto;     /* 分配多余空间前,元素的基础大小 */
}

👉 常用场景:

  • 平分容器宽度:

    .item { flex: 1; }
    
  • 固定宽度 + 自适应:

    .fixed { flex: 0 0 200px; } /* 固定 200px */
    .auto  { flex: 1; }         /* 占剩余空间 */
    

如何保证一行的个数固定

1、flex: 0 0 25%;

.container {
  display: flex;
  flex-wrap: wrap;
}

.item {
  flex: 0 0 25%; /* 1/4 */
}

如果需要拉伸的话, flex: 1 0 25%;

2、clac 动态计算

.container {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}

.item {
  flex: 0 0 calc((100% - 3 * 16px) / 4);
}

常见适用情况

弹性盒子(flexbox)是一种强大的布局模型,适用于许多不同的情况。以下是一些常见的情况,其中使用弹性盒子布局可以非常有用:

  1. 等高的列布局:当希望多个列的高度保持一致时,弹性盒子布局可以方便地实现这一目标。弹性盒子的子元素可以自动撑开,使所有列的高度保持一致。

  2. 自适应和响应式布局:弹性盒子布局适应不同尺寸的屏幕和设备非常方便。可以使用弹性盒子的属性和值,根据可用空间自动调整和重排子元素。

  3. 水平和垂直居中:弹性盒子提供了简单的方法来水平和垂直居中元素,无论是在容器内部还是容器本身。

  4. 项目排序和重新排序:可以使用弹性盒子的 order 属性来更改子元素的顺序,从而改变它们在布局中的位置。

  5. 间距和对齐控制:弹性盒子的属性可以帮助你精确地控制子元素之间的间距和对齐方式,使布局更加灵活和美观。

  6. 多列布局:通过设置弹性盒子的 flex-wrap 属性,可以创建多列布局,使多个子元素在容器内自动换行。

  7. 导航菜单和工具栏:弹性盒子非常适合用于创建导航菜单和工具栏,使项目水平排列,并具有弹性宽度和对齐选项。

  8. 等宽的网格布局:如果需要创建一个等宽的网格布局,弹性盒子可以简化这个过程,并且在容器尺寸变化时保持网格的均匀分布。

这只是一些弹性盒子布局的常见应用场景,实际上,弹性盒子提供了许多强大的特性和灵活性,可以适应各种布局需求。

flex弹性盒子和传统盒子的区别

使用 flex 弹性盒子(flexbox)和传统的盒子模型(block 和 inline)相比,有以下几个区别:

  1. 自适应空间分配:在弹性盒子中,子元素的宽度和高度可以根据可用空间进行自适应分配。弹性盒子具有伸缩性,可以根据容器的大小和内容来调整子元素的尺寸。而在传统的盒子模型中,元素的尺寸通常由其内容决定,无法方便地进行自适应调整。

  2. 方向灵活性:弹性盒子提供了更灵活的方向控制。可以通过设置 flex-direction 属性来改变弹性盒子的主轴方向(水平或垂直),以及交叉轴方向。这样,可以更方便地实现水平布局、垂直布局或者混合布局。而在传统的盒子模型中,水平布局和垂直布局需要使用不同的布局方式(block 或 inline)。

  3. 对齐和排序控制:弹性盒子提供了更精确的对齐和排序控制。可以使用 justify-contentalign-items 属性来控制子元素在主轴和交叉轴上的对齐方式,实现水平居中、垂直居中等对齐效果。而在传统的盒子模型中,对齐需要通过调整外边距(margin)或使用其他技巧来实现。

  4. 灵活的顺序控制:弹性盒子允许通过设置 order 属性来改变子元素的顺序,实现灵活的布局调整。可以通过调整元素的 order 值来改变它们在布局中的排列顺序。而在传统的盒子模型中,改变元素的顺序通常需要修改 HTML 结构。

需要注意的是,传统的盒子模型在大多数情况下仍然有效,特别是对于简单的布局需求。弹性盒子模型提供了更多的布局控制选项和灵活性,适用于更复杂和动态的布局需求。

示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div class="wrapper">
    <div class="container1"></div>
    <!--    <div class="container2"></div>-->
    <!--    <div class="container3"></div>-->
    <!--    <div class="container4"></div>-->
</div>
<style>
    body {
        margin: 0;
        padding: 0;
        overflow: hidden;
    }

    .wrapper {
        height: 100vh;
        display: flex;
        /*居中方法一:*/
        /*justify-content: center;*/
        /*align-items: center;*/
    }

    .container1 {
        width: 200px;
        height: 200px;
        background: #e57676;
        /*居中方法二:*/
        margin: auto;
    }
</style>
</body>
</html>

在这里插入图片描述

margin: auto 是指在主轴和副轴上占据剩余空间。只有一个 auto 相当于占掉上下左右的剩余空间,自然就居中了。

比如使用 margin-left: auto ,就变成了:

在这里插入图片描述

所以根据该规则,我们可以:

左右两列布局:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div class="wrapper">
    <div class="container"></div>
    <div class="container"></div>
    <div class="container"></div>
    <div class="container"></div>
</div>
<style>
    body {
        margin: 0;
        padding: 0;
        overflow: hidden;
    }

    .wrapper {
        background: #f0f0f0;
        height: 100vh;
        display: flex;
        /*居中方法一:*/
        /*justify-content: center;*/
        /*align-items: center;*/
    }

    .container {
        width: 200px;
        height: 200px;
        background: #e57676;
        border: 1px solid #181515;
        /*居中方法二:*/
        /*margin-left: auto;*/
    }

    .container:last-child {
        margin-left: auto;
    }
</style>
</body>
</html>

在这里插入图片描述

左右两列 + 一个居中

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            overflow: hidden;
        }

        .wrapper {
            background: #f0f0f0;
            height: 100vh;
            display: flex;
        }

        .container1 {
            width: 200px;
            height: 200px;
            background: #e57676;
            border: 1px solid #181515;
        }

        .container2 {
            width: 200px;
            height: 200px;
            background: #e57676;
            border: 1px solid #181515;
        }

        .container3 {
            width: 200px;
            height: 200px;
            background: #e57676;
            border: 1px solid #181515;
            margin: 0 auto;
        }

        .container4 {
            width: 200px;
            height: 200px;
            background: #e57676;
            border: 1px solid #181515;
        }
    </style>
</head>
<body>
<div class="wrapper">
    <div class="container1"></div>
    <div class="container2"></div>
    <div class="container3"></div>
    <div class="container4"></div>
</div>

</body>
</html>

在这里插入图片描述

巧妙利用该属性还可以实现列表布局:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            overflow: hidden;
        }

        .wrapper {
            background: #f0f0f0;
            height: 100vh;
            display: flex;
            flex-wrap: wrap;
            align-content: flex-start;
        }

        .container1, .container2, .container3, .container4, .container5, .container6, .container7, .container8, .container9, .container10, .container11, .container12 {
            width: 200px;
            height: 200px;
            box-sizing: border-box;
            background: #e57676;
            border: 1px solid #181515;
            --n: 8;
            --gap: calc((100% - 200px * var(--n)) / var(--n) / 2);
            margin: 10px var(--gap);
        }
    </style>
</head>
<body>
<div class="wrapper">
    <div class="container1"></div>
    <div class="container2"></div>
    <div class="container3"></div>
    <div class="container4"></div>
    <div class="container5"></div>
    <div class="container6"></div>
    <div class="container7"></div>
    <div class="container8"></div>
    <div class="container9"></div>
    <div class="container10"></div>
    <div class="container11"></div>
    <div class="container12"></div>
</div>

</body>
</html>

在这里插入图片描述

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐