从「布局噩梦」到「丝滑适配」——Flexbox 如何改变前端开发

304 阅读7分钟

前言

前端开发的小伙伴们,今天咱来唠唠 CSS 布局里超厉害的弹性盒子(Flexbox),它就像一个神奇的魔法盒,能把网页元素安排得明明白白,让咱的页面又好看又实用!

想象一下,你面前有一堆形状、大小各异的积木,想搭出一个超酷的城堡。以前用传统布局方法,就像用胶水把积木一块一块粘起来,不仅麻烦,还不太灵活。要是想调整一下城堡的样子,那可费劲了!但有了 Flexbox 这个魔法盒,就不一样啦,它能让积木们自己 “商量” 着怎么排列,轻松又高效。

一、简介

2009 年,W3C 提出了 Flexible Box,也就是我们常说的弹性盒子。它能轻松控制元素的分布方式、对齐方式和视觉顺序。与传统布局(基于 display、position 和 float 属性)不同,弹性盒子在处理复杂布局和响应式设计时更加灵活高效,这也是它在移动端广泛应用的原因。在传统布局中,实现一些复杂的布局效果往往需要繁琐的代码和技巧,而弹性盒子通过简单的属性设置就能轻松达成。

二、核心概念

Flexbox 里有两个关键角色:伸缩容器伸缩项目。给一个元素加上display:flex,它就成了伸缩容器,像一个有魔力的大盒子。容器里的子元素自动变成伸缩项目,不管它们以前是 “小个子” 行内元素,还是 “大块头” 块级元素,进了这个盒子都变得服服帖帖🙇‍♀️🙇‍♀️,按规则排队。

(1)基础概念和方向设置

在这个魔法世界里,还有两根神奇的轴 —— 主轴侧轴

主轴默认是水平的,就像一条平坦的大马路,伸缩项目们沿着它从左到右排排站;

侧轴垂直于主轴,是竖着的小路。

不过,这两根轴的方向可不是固定不变的。用flex-direction这个魔法咒语,就能改变主轴的方向。说声 “row-reverse”,项目们就像接到了向后转的命令,从右往左排列;喊出 “row”,它们又乖乖地排着队从左到右站啦,侧轴方向也跟着变,是不是很神奇?

让我们看看演示:

<div class="demo-section">
        <h2>1. 默认行布局 (flex-direction: row)</h2>
        <div class="flex-container row">
            <div class="flex-item">项目 1</div>
            <div class="flex-item">项目 2</div>
            <div class="flex-item">项目 3</div>
        </div>
    </div>
/* 基础行布局 */
        .row {
            display: flex;
            flex-direction: row; /*默认,也可以不写*/
        }

主轴方向:从左到右

image.png


<div class="demo-section">
        <h2>2. 列布局 (flex-direction: column)</h2>
        <div class="flex-container column">
            <div class="flex-item">项目 1</div>
            <div class="flex-item">项目 2</div>
            <div class="flex-item">项目 3</div>
        </div>
    </div>
/* 列布局 */
        .column {
            display: flex;
            flex-direction: column;
            height: 300px;
        }

侧轴方向:从上到下

image.png


现在我们看看反转: flex-direction: row-reverse;

注意:改变了主轴的方向,侧轴方向也随之更改。

 <div class="demo-section">
        <h2>3. 反向行布局 (flex-direction: row-reverse)</h2>
        <div class="flex-container row-reverse">
            <div class="flex-item">项目 1</div>
            <div class="flex-item">项目 2</div>
            <div class="flex-item">项目 3</div>
        </div>
    </div>
/* 反向行布局 */
        .row-reverse {
            display: flex;
            flex-direction: row-reverse;
        }

主轴方向反转:从右到左

image.png


  <div class="demo-section">
        <h2>4. 反向列布局 (flex-direction: column-reverse)</h2>
        <div class="flex-container column-reverse">
            <div class="flex-item">项目 1</div>
            <div class="flex-item">项目 2</div>
            <div class="flex-item">项目 3</div>
        </div>
    </div>
/* 反向列布局 */
        .column-reverse {
            display: flex;
            flex-direction: column-reverse;
            height: 300px;
        }

侧轴方向反转:从下到上

image.png

好啦!现在你已经学会了Flexbox的基础概念和方向设置,接下来看看对齐方式...

(2)对齐方式

📝在Flex布局中,对齐方式是最常用也是最重要的特性之一。主要包括两大类:

  • justify-content: 控制主轴方向的对齐
  • align-items: 控制侧轴方向的对齐

这两个属性的配合使用,可以轻松实现各种对齐布局效果。

主轴对齐方式:justify-content

🍃justify-content属性决定了flex容器中的项目在主轴方向上如何排列。它有以下几个常用值:

.box1 {
  display: flex;
  justify-content: flex-start | center | flex-end | space-between | space-around;
}
 <div class="box1">
    <div class="content1">111</div>
    <div class="content1">222</div>
    <div class="content1">333</div>
 </div>
1.flex-start (默认值)

🍃所有项目靠近主轴起点对齐。这是默认的对齐方式,适合大多数从左到右的布局场景。

  .box1 {
      background-color: rgb(250, 225, 40);
      width: 500px;
      height: 100px;
      display: flex;
      flex-direction: row;
      justify-content: flex-start; 
    }

image.png

2. center (居中对齐)

🍃所有项目居中对齐。这个是实现水平居中最简单的方式,常用于:

  • 导航栏菜单居中
  • 内容区块居中
  • 按钮组居中对齐
.box1 {
      background-color: rgb(250, 225, 40);
      width: 500px;
      height: 100px;
      display: flex;
      flex-direction: row;
      justify-content: center;
    }

image.png

3. flex-end (尾部对齐)

🍃所有项目靠近主轴终点对齐。适用于:

  • 右对齐的菜单
  • 操作按钮靠右对齐
  • RTL(从右到左)布局
.box1 {
      background-color: rgb(250, 225, 40);
      width: 500px;
      height: 100px;
      display: flex;
      flex-direction: row;
      justify-content: flex-end;
    }

image.png

4. space-between (两端对齐)

🍃项目之间的间隔都相等,首尾两个项目贴近容器边缘。这个值特别适合:

  • 导航栏两端对齐布局
  • 内容分散对齐
  • 均匀分布的列表
.box1 {
      background-color: rgb(250, 225, 40);
      width: 500px;
      height: 100px;
      display: flex;
      flex-direction: row;
      justify-content: space-between;
    }

image.png

5. space-around (环绕对齐)

🍃每个项目两侧的间隔相等,所以项目之间的间隔是项目与边缘间隔的两倍。适合:

  • 卡片布局
  • 图片画廊
  • 需要均匀间距的列表
.box1 {
      background-color: rgb(250, 225, 40);
      width: 500px;
      height: 100px;
      display: flex;
      flex-direction: row;
      justify-content: space-around;
    }

image.png

6. space-evenly

🍃均匀分布,两端距离与中间距离一致

.box1 {
      background-color: rgb(250, 225, 40);
      width: 500px;
      height: 100px;
      display: flex;
      flex-direction: row;
      justify-content: space-evenly;
    }

image.png

侧轴对齐方式:align-items

📝常用值如下:

  1. flex-start :侧轴的起点对齐。

  2. flex-end :侧轴的终点对齐。

  3. center :侧轴的中点对齐。

  4. baseline : 伸缩项目的第一行文字的基线对齐。

  5. stretch :如果伸缩项目未设置高度,将占满整个容器的高度。—— (默认值)

(3)主轴换行方式: flex-wrap

我们认识了主轴方向和对齐方式后,有的小伙伴就会冒出疑问了:如果伸缩项目太多加起来的宽度超过了伸缩盒子的宽度该咋办?🤯🤯🤯

我们设置一个宽300px,高100px的大盒子(box1),每个里面的小盒子(content1)宽100px,高80px,并且设置小盒子右部外边距margin-right为10px。

    .box1 {
      width: 300px;  /*大盒子的宽*/
      height: 100px;
      display: flex;
      flex-direction: row;
    }
    .content1 {
      width: 100px;  /*小盒子的宽*/
      height: 80px;
      margin-right: 10px;
    }

在大盒子里放两个小盒子:

 <div class="box1">
    <div class="content1">111</div>
    <div class="content1">222</div>
  </div>

此时是这样排列的:

image.png

image.png

此时看了,小盒子的宽高正常,我们再加一个小盒子🙇‍♀️:

<div class="box1">
    <div class="content1">111</div>
    <div class="content1">222</div>
    <div class="content1">333</div> 
</div>

image.png

我们发现小盒子的宽竟然被压缩了!!这是为什么?🤔

因为当弹性容器的可用空间不足时(即所有子项的「基础尺寸」总和超过容器宽度),子项会根据自身的 flex-shrink 属性值决定是否压缩,以及压缩比例。(该属性用在子项!)

 注:flex-shrink 定义子项的收缩比例(数值越大越容易被压缩),0 表示不压缩,1 表示按比例压缩。

 .content1 {
      width: 100px;
      height: 80px;
      flex-shrink: 0; /*不压缩*/
    }

image.png

这样就可以解决压缩问题,但是溢出了怎么办?别急,我们可以采用换行flex-wrap

举个栗子🌰:

    .box1 {
      width: 300px;
      height: 200px;
      display: flex;
      flex-direction: row;
      flex-wrap: wrap; /*自动换行*/
    }

    .content1 {
      width: 100px;
      height: 80px;
      flex-shrink: 0;
    }

image.png

是不是轻松解决啦!

📝常用值如下:

  1. nowrap :默认值,不换行。

  2. wrap :自动换行,伸缩容器不够自动换行。

  3. wrap-reverse :反向换行。

(4)复合属性: flex-flow

📝flex-flow 是一个复合属性,复合了 flex-directionflex-wrap 两个属性, 值没有顺序要求。

举个栗子🌰:

flex-flow: row wrap;

三、结尾

通过这篇文章,你是不是对弹性盒子有了基本的了解?前端布局的进化从未停止,但 Flexbox 始终是最值得深耕的「地基」技术。收藏本文中的代码示例,下次遇到布局难题时,试着用「弹性思维」重新拆解需求 —— 你会发现,那些曾让你头疼的适配问题,早已在「弹性盒子」的规则里找到了优雅的解法。