MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

CSS弹性盒子布局:Flexbox的display: flex与相关属性的应用

2021-06-221.2k 阅读

CSS弹性盒子布局基础:display: flex

在现代前端开发中,CSS弹性盒子布局(Flexbox)是一种极为强大且灵活的布局模式,极大地简化了我们对页面元素的排列和分布控制。而开启弹性盒子布局的第一步,就是通过设置display: flex属性。

当一个元素被设置为display: flex,它就成为了一个弹性容器(flex container)。这个容器内的直接子元素会自动成为弹性项目(flex items)。弹性容器为我们提供了一种全新的布局上下文,在这个上下文中,弹性项目的排列和对齐方式都遵循Flexbox的规则。

例如,以下是一个简单的HTML结构,我们将一个div元素设置为弹性容器:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Flexbox Basics</title>
    <style>
        .flex-container {
            display: flex;
            background-color: lightgray;
        }
        .flex-item {
            background-color: skyblue;
            padding: 10px;
            margin: 5px;
        }
    </style>
</head>
<body>
    <div class="flex-container">
        <div class="flex-item">Item 1</div>
        <div class="flex-item">Item 2</div>
        <div class="flex-item">Item 3</div>
    </div>
</body>
</html>

在上述代码中,.flex-container类通过display: flex被定义为弹性容器,其内部的三个.flex-item则是弹性项目。默认情况下,弹性项目会在一行水平排列,并且会根据其内容自动调整大小。

弹性容器的主要属性

flex-direction属性

flex-direction属性用于确定弹性项目在弹性容器中的排列方向。它有四个可选值:row(默认值)、row - reversecolumncolumn - reverse

  • row:弹性项目从左到右水平排列,这是最常见的排列方式。例如:
.flex-container {
    display: flex;
    flex-direction: row;
}
  • row - reverse:弹性项目从右到左水平排列,与row方向相反。
.flex-container {
    display: flex;
    flex-direction: row - reverse;
}
  • column:弹性项目从上到下垂直排列。
.flex-container {
    display: flex;
    flex-direction: column;
}
  • column - reverse:弹性项目从下到上垂直排列,与column方向相反。
.flex-container {
    display: flex;
    flex-direction: column - reverse;
}

justify-content属性

justify-content属性用于控制弹性项目在主轴(根据flex-direction确定的主要排列方向)上的对齐方式。它有六个可选值:flex - start(默认值)、flex - endcenterspace - betweenspace - aroundspace - evenly

  • flex - start:弹性项目向主轴起始位置对齐。如果主轴是水平方向(flex-direction: row),则项目会靠左对齐;如果主轴是垂直方向(flex-direction: column),则项目会靠上对齐。
.flex-container {
    display: flex;
    justify-content: flex - start;
}
  • flex - end:弹性项目向主轴结束位置对齐。水平方向时靠右对齐,垂直方向时靠下对齐。
.flex-container {
    display: flex;
    justify-content: flex - end;
}
  • center:弹性项目在主轴上居中对齐。
.flex-container {
    display: flex;
    justify-content: center;
}
  • space - between:弹性项目均匀分布在主轴上,两端的项目与容器边缘紧贴,项目之间的间距相等。
.flex-container {
    display: flex;
    justify-content: space - between;
}
  • space - around:弹性项目均匀分布在主轴上,每个项目两侧的间距相等,这意味着项目之间的间距是项目与容器边缘间距的两倍。
.flex-container {
    display: flex;
    justify-content: space - around;
}
  • space - evenly:弹性项目均匀分布在主轴上,项目之间以及项目与容器边缘的间距都相等。
.flex-container {
    display: flex;
    justify-content: space - evenly;
}

align-items属性

align-items属性用于控制弹性项目在交叉轴(与主轴垂直的轴)上的对齐方式。它有五个可选值:stretch(默认值)、flex - startflex - endcenterbaseline

  • stretch:弹性项目会拉伸以填满交叉轴方向的可用空间。如果弹性项目在交叉轴方向上没有设置明确的高度或宽度(例如在flex-direction: row时未设置高度),它们会自动伸展以适应容器的高度。
.flex-container {
    display: flex;
    align-items: stretch;
}
  • flex - start:弹性项目向交叉轴起始位置对齐。在水平排列(flex-direction: row)时,项目靠上对齐;垂直排列(flex-direction: column)时,项目靠左对齐。
.flex-container {
    display: flex;
    align-items: flex - start;
}
  • flex - end:弹性项目向交叉轴结束位置对齐。水平排列时靠下对齐,垂直排列时靠右对齐。
.flex-container {
    display: flex;
    align-items: flex - end;
}
  • center:弹性项目在交叉轴上居中对齐。
.flex-container {
    display: flex;
    align-items: center;
}
  • baseline:弹性项目根据它们的基线对齐。基线是文本在一行中所处的位置,对于包含文本的弹性项目,这种对齐方式可以确保文本在同一水平线上。
.flex-container {
    display: flex;
    align-items: baseline;
}

flex-wrap属性

flex-wrap属性决定弹性项目是否换行。它有三个可选值:nowrap(默认值)、wrapwrap - reverse

  • nowrap:弹性项目不会换行,所有项目会尽量在一行或一列(取决于flex-direction)内排列。如果容器空间不足,项目会被压缩。
.flex-container {
    display: flex;
    flex-wrap: nowrap;
}
  • wrap:当容器空间不足时,弹性项目会换行。换行的方向与主轴方向相关,例如flex-direction: row时,项目会从上到下换行;flex-direction: column时,项目会从左到右换行。
.flex-container {
    display: flex;
    flex-wrap: wrap;
}
  • wrap - reverse:与wrap类似,但换行的方向相反。在flex-direction: row时,项目会从下到上换行;flex-direction: column时,项目会从右到左换行。
.flex-container {
    display: flex;
    flex-wrap: wrap - reverse;
}

align-content属性

align-content属性用于控制多行弹性项目在交叉轴上的对齐方式,仅在弹性项目换行(flex-wrap: wrapflex-wrap: wrap - reverse)时生效。它有六个可选值:stretch(默认值)、flex - startflex - endcenterspace - betweenspace - around

  • stretch:多行弹性项目会拉伸以填满交叉轴方向的可用空间,类似于align-items: stretch对单行项目的作用。
.flex-container {
    display: flex;
    flex-wrap: wrap;
    align-content: stretch;
}
  • flex - start:多行项目向交叉轴起始位置对齐。
.flex-container {
    display: flex;
    flex-wrap: wrap;
    align-content: flex - start;
}
  • flex - end:多行项目向交叉轴结束位置对齐。
.flex-container {
    display: flex;
    flex-wrap: wrap;
    align-content: flex - end;
}
  • center:多行项目在交叉轴上居中对齐。
.flex-container {
    display: flex;
    flex-wrap: wrap;
    align-content: center;
}
  • space - between:多行项目均匀分布在交叉轴上,两端的行与容器边缘紧贴,行与行之间的间距相等。
.flex-container {
    display: flex;
    flex-wrap: wrap;
    align-content: space - between;
}
  • space - around:多行项目均匀分布在交叉轴上,每行两侧的间距相等,行与行之间的间距是行与容器边缘间距的两倍。
.flex-container {
    display: flex;
    flex-wrap: wrap;
    align-content: space - around;
}

弹性项目的主要属性

flex - grow属性

flex - grow属性定义弹性项目的放大比例,默认值为0,即如果存在剩余空间,也不放大。当所有弹性项目的flex - grow值都为0时,它们会根据自身内容大小占据空间,不会拉伸以填满剩余空间。

如果将某个弹性项目的flex - grow值设置为1,而其他项目保持为0,那么该项目会占据所有剩余空间。如果多个项目都设置了flex - grow值,例如flex - grow: 2flex - grow: 1,它们将按照比例分配剩余空间。例如,以下代码中,第二个弹性项目会占据剩余空间的2/3,第三个项目占据1/3:

.flex-item:nth - of - type(2) {
    flex - grow: 2;
}
.flex-item:nth - of - type(3) {
    flex - grow: 1;
}

flex - shrink属性

flex - shrink属性定义弹性项目的缩小比例,默认值为1。当弹性容器空间不足时,弹性项目会根据flex - shrink值进行缩小。如果将某个项目的flex - shrink值设置为0,当空间不足时,该项目不会缩小。

假设所有项目的flex - shrink值都为1,并且容器空间不足,它们会按比例缩小以适应容器。如果一个项目的flex - shrink值比其他项目大,它会相对更多地缩小。例如:

.flex-item:nth - of - type(2) {
    flex - shrink: 2;
}

上述代码中,第二个弹性项目在空间不足时会比其他项目缩小得更快。

flex - basis属性

flex - basis属性定义在分配多余空间之前,弹性项目占据的主轴空间(宽度或高度,取决于flex-direction)。它的默认值是auto,表示根据项目内容自动确定大小。

我们也可以设置具体的长度值,如200px或百分比值,如50%。例如:

.flex-item:nth - of - type(2) {
    flex - basis: 300px;
}

在上述代码中,第二个弹性项目在分配剩余空间之前,其宽度(假设flex-direction: row)会被设置为300px。

flex属性

flex属性是flex - growflex - shrinkflex - basis的简写属性。常见的用法有:

  • flex: 1:等同于flex: 1 1 0%,表示弹性项目会放大以填满剩余空间,在空间不足时会缩小,并且初始大小为0%(根据内容自动调整)。
  • flex: 2 0 300px:表示弹性项目放大比例为2,不缩小,初始宽度(假设flex-direction: row)为300px。
.flex-item:nth - of - type(2) {
    flex: 2 0 300px;
}

order属性

order属性用于控制弹性项目的排列顺序,默认值为0。可以为弹性项目设置不同的order值,值越小,项目越靠前排列。例如:

.flex-item:nth - of - type(2) {
    order: -1;
}

上述代码会使第二个弹性项目排在所有其他项目之前。

align-self属性

align-self属性允许单个弹性项目覆盖容器的align-items属性,单独设置自身在交叉轴上的对齐方式。它的可选值与align-items相同,即stretchflex - startflex - endcenterbaseline。例如:

.flex-item:nth - of - type(2) {
    align-self: flex - end;
}

上述代码会使第二个弹性项目在交叉轴上靠下对齐(假设flex-direction: row),而不受容器align-items属性的影响。

Flexbox在实际布局中的应用案例

水平居中布局

在传统布局中,实现水平居中可能需要使用复杂的margin设置或定位技巧。而在Flexbox中,这变得非常简单。只需将容器设置为display: flex,并使用justify-content: center即可。例如:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Horizontal Center</title>
    <style>
        .container {
            display: flex;
            justify-content: center;
            background-color: lightgray;
            height: 200px;
        }
        .box {
            background-color: skyblue;
            width: 100px;
            height: 100px;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="box"></div>
    </div>
</body>
</html>

垂直居中布局

同样,垂直居中在Flexbox中也很容易实现。将容器设置为display: flex,并使用align-items: center。例如:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vertical Center</title>
    <style>
        .container {
            display: flex;
            align-items: center;
            background-color: lightgray;
            height: 200px;
        }
        .box {
            background-color: skyblue;
            width: 100px;
            height: 100px;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="box"></div>
    </div>
</body>
</html>

导航栏布局

导航栏是Web页面中常见的组件,使用Flexbox可以轻松创建响应式的导航栏。例如:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Navigation Bar</title>
    <style>
        nav {
            display: flex;
            justify-content: space - between;
            background-color: #333;
            color: white;
            padding: 10px;
        }
        nav a {
            color: white;
            text-decoration: none;
        }
    </style>
</head>
<body>
    <nav>
        <a href="#">Home</a>
        <a href="#">About</a>
        <a href="#">Services</a>
        <a href="#">Contact</a>
    </nav>
</body>
</html>

在上述代码中,nav元素作为弹性容器,通过justify-content: space - between使导航链接均匀分布在容器中。

卡片布局

卡片布局常用于展示内容,如产品卡片、文章卡片等。Flexbox可以帮助我们快速实现卡片的布局,并使其在不同屏幕尺寸下有良好的表现。例如:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Card Layout</title>
    <style>
        .card-container {
            display: flex;
            flex-wrap: wrap;
            justify-content: space - around;
        }
        .card {
            background-color: white;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
            width: 200px;
            margin: 10px;
            padding: 15px;
        }
    </style>
</head>
<body>
    <div class="card-container">
        <div class="card">
            <h3>Card 1</h3>
            <p>Some content here...</p>
        </div>
        <div class="card">
            <h3>Card 2</h3>
            <p>Some content here...</p>
        </div>
        <div class="card">
            <h3>Card 3</h3>
            <p>Some content here...</p>
        </div>
    </div>
</body>
</html>

在上述代码中,.card-container是弹性容器,通过flex-wrap: wrap使卡片在空间不足时换行,justify-content: space - around让卡片均匀分布。

Flexbox的兼容性与注意事项

虽然Flexbox在现代浏览器中得到了广泛支持,但在一些较旧的浏览器中可能存在兼容性问题。为了确保兼容性,可以使用浏览器前缀,例如:

.flex-container {
    display: -webkit - flex; /* Safari */
    display: -ms - flex; /* IE 10 */
    display: flex;
}

另外,在使用Flexbox布局时,要注意一些属性之间的相互影响。例如,flex - growflex - shrinkflex - basis的设置会相互作用,影响弹性项目的最终大小。同时,要充分理解主轴和交叉轴的概念,以便正确使用justify-contentalign-items等属性。

在实际项目中,还可以结合媒体查询(media queries)来优化Flexbox布局在不同屏幕尺寸下的表现,以提供更好的用户体验。例如:

@media (max - width: 600px) {
    .flex-container {
        flex - direction: column;
    }
}

上述代码表示在屏幕宽度小于600px时,弹性容器内的项目会从水平排列改为垂直排列。

Flexbox是前端开发中一项强大的布局技术,通过合理运用display: flex以及相关属性,我们能够高效地创建各种复杂且灵活的页面布局,同时兼顾不同设备的兼容性和响应式设计。无论是简单的水平垂直居中,还是复杂的导航栏和卡片布局,Flexbox都能提供简洁而有效的解决方案。在日常开发中,不断实践和探索Flexbox的各种特性,将有助于提升我们的前端布局能力,打造出更优质的用户界面。