一文搞懂flex布局 【弹性盒布局】

CSS系列文章目录

  1. CSS 之 display 布局属性详解
  2. CSS 之 position 定位属性详解
  3. 一文搞懂flex布局 【弹性盒布局】

在这里插入图片描述



前言

Flexible Box 模型,通常被称为 flexbox,翻译成中文就是“弹性盒子”,是一种一维的布局模型。它给 flexbox 的子元素之间提供了强大的空间分布和对齐能力。

它是一种现代的 CSS 布局方式,通过使用 display: flex 属性来创建一个弹性容器,可以自动适配各种设备的不同宽度,而不必依赖于传统的块状布局和浮动定位,并在其中使用灵活的盒子模型来进行元素的排列和定位。

在这里插入图片描述


一、flexbox 的两根轴线

当使用 flex 布局时,首先想到的是两根轴线 — 主轴交叉轴 。主轴由 flex-direction 定义,另一根轴垂直于它。我们使用 flexbox 的所有属性都跟这两根轴线有关,所以有必要在一开始首先理解它。

1.1 主轴

主轴由 flex-direction 定义,可以取 4 个值:

  • row
  • row-reverse
  • column
  • column-reverse

如果你选择了 row 或者 row-reverse,你的主轴将沿着行向延伸。

在这里插入图片描述
选择 column 或者 column-reverse 时,你的主轴会沿着页面的上下方向延伸——也就是块向。

在这里插入图片描述

1.2 交叉轴

交叉轴垂直于主轴,所以如果你的 flex-direction(主轴)设成了 row 或者 row-reverse 的话,交叉轴的方向就是沿着上下方向延伸的。

在这里插入图片描述

如果主轴方向设成了 column 或者 column-reverse,交叉轴就是水平方向。
在这里插入图片描述
理解主轴和交叉轴的概念对于对齐 flexbox 里面的元素是很重要的;flexbox 的特性是沿着主轴或者交叉轴对齐之中的元素。

二、起始线和终止线

另外一个需要理解的重点是 flexbox 不会对文档的书写模式提供假设。过去,CSS 的书写模式主要被认为是水平的,从左到右的。现代的布局方式涵盖了书写模式的范围,所以我们不再假设一行文字是从文档的左上角开始向右书写,新的行也不是必须出现在另一行的下面。

你可以在接下来的文章中学到更多 flexbox 和书写模式关系的详细说明。下面的描述是来帮助我们理解为什么不用上下左右来描述 flexbox 元素的方向。

如果 flex-directionrow,并且我是在书写英文,那么主轴的起始线是左边,终止线是右边。

在这里插入图片描述
如果我在书写阿拉伯文,那么主轴的起始线是右边,终止线是左边。

在这里插入图片描述
在这两种情况下,交叉轴的起始线是 flex 容器的顶部,终止线是底部,因为两种语言都是水平书写模式。

之后,你会觉得用起始和终止来描述比左右更合适,这会对你理解其他相同模式的布局方法(例如:CSS Grid Layout)起到帮助的作用。

三、Flex 容器

文档中采用了 flexbox 的区域就叫做 flex 容器。为了创建 flex 容器,我们把一个容器的 display 属性值改为 flex 或者 inline-flex。完成这一步之后,容器中的直系子元素就会变为 flex 元素。

在这里插入图片描述

在这里插入图片描述

由于所有 CSS 属性都会有一个初始值,所以 flex 容器中的所有 flex 元素都会有下列行为:

  • 元素排列为一行(flex-direction 属性的初始值是 row)。
  • 元素从主轴的起始线开始。
  • 元素不会在主维度方向拉伸,但是可以缩小。
  • 元素被拉伸来填充交叉轴大小。
  • flex-basis 属性为 auto。
  • flex-wrap 属性为 nowrap。

这会让你的元素呈线形排列,并且把自己的大小作为主轴上的大小。如果有太多元素超出容器,它们会溢出而不会换行。如果一些元素比其他元素高,那么元素会沿交叉轴被拉伸来填满它的大小。

.box {
  display: flex;
}
<div class="box">
  <div>One</div>
  <div>Two</div>
  <div>Three
    <br>has
    <br>extra
    <br>text
  </div>
</div>

在这里插入图片描述

3.1 更改 flex 方向 flex-direction

flex 容器中添加 flex-direction 属性可以让我们更改 flex 元素的排列方向。设置 flex-direction: row-reverse 可以让元素沿着行的方向显示,但是起始线和终止线位置会交换。

flex 容器的属性 flex-direction 改为 column,主轴和交叉轴交换,元素沿着列的方向排列显示。改为 column-reverse,起始线和终止线交换。

  • row(默认值):主轴为水平方向,起点在左端。
  • row-reverse:主轴为水平方向,起点在右端。
  • column:主轴为垂直方向,c起点在上沿。
  • column-reverse:主轴为垂直方向,起点在下沿。

在这里插入图片描述

下面的例子中,flex-direction 值为 row-reverse。尝试使用其他的值 row ,column,column-reverse,看看内容会发生什么改变。

.box {
  display: flex;
  flex-direction: row-reverse;
}
<div class="box">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
</div>

在这里插入图片描述

四、用 flex-wrap 实现多行 Flex 容器

虽然 flexbox 是一维模型,但可以使我们的 flex 项目应用到多行中。在这样做的时候,你应该把每一行看作一个新的 flex 容器。任何空间分布都将在该行上发生,而不影响该空间分布的其他行。

在这里插入图片描述

  • nowrap(默认):不换行。

在这里插入图片描述

  • wrap:换行,第一行在上方。

在这里插入图片描述

  • wrap-reverse:换行,第一行在下方。

在这里插入图片描述

为了实现多行效果,请为属性 flex-wrap 添加一个属性值 wrap 。现在,如果你的项目太大而无法全部显示在一行中,则会换行显示。下面的实时例子包含已给出宽度的项目,对于 flex容器,项目的子元素总宽度大于容器最大宽度。由于 flex-wrap 的值设置为 wrap,所以项目的子元素换行显示。若将其设置为 nowrap ,这也是初始值,它们将会缩小以适应容器,因为它们使用的是允许缩小的初始 Flexbox 值。如果项目的子元素无法缩小,使用 nowrap 会导致溢出,或者缩小程度还不够小。

.box {
  display: flex;
  flex-wrap: wrap;
}
<div class="box">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
</div>

在这里插入图片描述

五、简写属性 flex-flow

你可以将两个属性 flex-directionflex-wrap 组合为简写属性 flex-flow。第一个指定的值为 flex-direction ,第二个指定的值为 flex-wrap .

在下面的例子中,尝试将第一个值修改为 flex-direction 的允许取值之一,即 row, row-reverse, column 或 column-reverse, 并尝试将第二个指定值修改为 wrapnowrap

.box {
  display: flex;
  flex-flow: row wrap;
}
<div class="box">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
</div>

在这里插入图片描述

六、flex 元素上的属性

为了更好地控制 flex 元素,有六个属性可以作用于它们:

  • flex-grow
  • flex-shrink
  • flex-basis
  • order
  • flex
  • align-self

在这里,我们只会大概介绍一下它们的用法,更详细的细节请参阅其他的文章。

在考虑这几个属性的作用之前,需要先了解一下可用空间(available space)这个概念。这几个 flex 属性的作用其实就是改变了 flex 容器中的可用空间的行为。同时,可用空间对于 flex元素的对齐行为也是很重要的。

假设在 1 个 500px 的容器中,我们有 3 个 100px 宽的元素,那么这 3 个元素需要占 300px 的宽,剩下 200px 的可用空间。在默认情况下,flexbox 的行为会把这 200px 的空间留在最后一个元素的后面。

在这里插入图片描述
如果期望这些元素能自动地扩展去填充满剩下的空间,那么我们需要去控制可用空间在这几个元素间如何分配,这就是元素上的那些 flex 属性要做的事。

6.1 Flex 元素属性:flex-basis

flex-basis 定义了该元素的空间大小,flex 容器里除了元素所占的空间以外的富余空间就是可用空间。该属性的默认值是 auto。此时,浏览器会检测这个元素是否具有确定的尺寸。在上面的例子中,所有元素都设定了宽度(width)为 100px,所以 flex-basis 的值为 100px。

如果没有给元素设定尺寸,flex-basis 的值采用元素内容的尺寸。这就解释了:我们给只要给 Flex 元素的父元素声明 display: flex,所有子元素就会排成一行,且自动分配大小以充分展示元素的内容。

6.2 Flex 元素属性:flex-grow

flex-grow 若被赋值为一个正整数,flex 元素会以 flex-basis 为基础,沿主轴方向增长尺寸。这会使该元素延展,并占据此方向轴上的可用空间(available space)。如果有其他元素也被允许延展,那么他们会各自占据可用空间的一部分。

如果我们给上例中的所有元素设定 flex-grow 值为 1,容器中的可用空间会被这些元素平分。它们会延展以填满容器主轴方向上的空间。

flex-grow 属性可以按比例分配空间。如果第一个元素 flex-grow 值为 2,其他元素值为 1,则第一个元素将占有 2/4(上例中,即为 200px 中的 100px), 另外两个元素各占有 1/4(各 50px)。

6.3 Flex 元素属性:flex-shrink

flex-grow 属性是处理 flex 元素在主轴上增加空间的问题,相反 flex-shrink 属性是处理 flex 元素收缩的问题。如果我们的容器中没有足够排列 flex 元素的空间,那么可以把 flex 元素 flex-shrink 属性设置为正整数来缩小它所占空间到 flex-basis 以下。与 flex-grow 属性一样,可以赋予不同的值来控制 flex 元素收缩的程度——给 flex-shrink 属性赋予更大的数值可以比赋予小数值的同级元素收缩程度更大。

在计算 flex 元素收缩的大小时,它的最小尺寸也会被考虑进去,就是说实际上 flex-shrink 属性可能会和 flex-grow 属性表现的不一致。因此,我们可以在文章《控制 Flex 子元素在主轴上的比例》中更详细地看一下这个算法的原理。

备注: 在给 flex-growflex-shrink 赋值时要注意比例。如果我们给所有 flex 元素的 flex 属性赋值为 1 1 200px ,并且希望其中一个元素可以增加到 2 倍,我们可以给该元素的 flex 属性赋值为2 1 200px。当然,你也可以选择赋值为 flex: 10 1 200px 和 flex: 20 1 200px 。

6.4 Flex 属性的简写

你可能很少看到 flex-growflex-shrink,和 flex-basis 属性单独使用,而是混合着写在 flex 简写形式中。 Flex 简写形式允许你把三个数值按这个顺序书写 — flex-grow,flex-shrink,flex-basis。

你可以在下面的实例中尝试把 flex 简写形式中的数值更改为不同数值,但要记得第一个数值是 flex-grow。赋值为正数的话是让元素增加所占空间。第二个数值是 flex-shrink — 正数可以让它缩小所占空间,但是只有在 flex 元素总和超出主轴才会生效。最后一个数值是 flex-basisflex 元素是在这个基准值的基础上缩放的。

.box {
  display: flex;
}

.one {
  flex: 1 1 auto;
}

.two {
  flex: 1 1 auto;
}

.three {
  flex: 1 1 auto;
}
<div class="box">
  <div class="one">One</div>
  <div class="two">Two</div>
  <div class="three">Three</div>
</div>

在这里插入图片描述
大多数情况下可以用预定义的简写形式。在这个教程中你可能经常会看到这种写法,许多情况下你都可以这么使用。下面是几种预定义的值:

  • flex: initial
  • flex: auto
  • flex: none
  • flex: <positive-number>

flex: initial 是把 flex 元素重置为 Flexbox 的初始值,它相当于 flex: 0 1 auto。在这里 flex-grow 的值为 0,所以 flex 元素不会超过它们 flex-basis 的尺寸。flex-shrink 的值为 1, 所以可以缩小 flex 元素来防止它们溢出。flex-basis 的值为 auto. Flex 元素尺寸可以是在主维度上设置的,也可以是根据内容自动得到的。

flex: auto 等同于 flex: 1 1 auto;和上面的 flex:initial 基本相同,但是这种情况下,flex 元素在需要的时候既可以拉伸也可以收缩。

flex: none 可以把 flex 元素设置为不可伸缩。它和设置为 flex: 0 0 auto 是一样的。元素既不能拉伸或者收缩,但是元素会按具有 flex-basis: auto 属性的 flexbox 进行布局。

你在教程中常看到的 flex: 1 或者 flex: 2 等等。它相当于flex: 1 1 0 或者 flex: 2 1 0。元素可以在 flex-basis 为 0 的基础上伸缩。

尝试在下面的实例中应用这些简写值。

.box {
  display: flex;
}

.one {
  flex: 1;
}

.two {
  flex: 1;
}

.three {
  flex: 1;
}
<div class="box">
  <div class="one">One</div>
  <div class="two">Two</div>
  <div class="three">Three</div>
</div>

在这里插入图片描述

6.5 order属性:定义项目的排列顺序

数值越小,排列越靠前,默认为0,可以是负值。

.item {
    order: <整数>;
}

在这里插入图片描述

6.6 align-self属性

align-self 属性允许单个项目有与其他项目不一样的对齐方式,可覆盖 align-items 属性。默认值为 auto,表示继承父元素的 align-items 属性,如果没有父元素,则等同于 stretch

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

在这里插入图片描述

七、元素间的对齐和空间分配

Flexbox 的一个关键特性是能够设置 flex 元素沿主轴方向和交叉轴方向的对齐方式,以及它们之间的空间分配。

justify-content 属性用来使元素在主轴方向上对齐,它的初始值是 flex-start,即元素从容器的起始线排列。justify-content 属性有如下 5 个不同的值:

  • flex-start(默认值):左对齐、从起始线开始排列,默认值。
  • flex-end:右对齐、从终止线开始排列。
  • center: 居中、在中间排列。
  • space-between:两端对齐,项目之间的间隔都相等。
  • space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。

7.1 justify-content

justify-content 属性用来使元素在主轴方向上对齐,主轴方向是通过 flex-direction 设置的方向。初始值是 flex-start,元素从容器的起始线排列。但是你也可以把值设置为 flex-end,从终止线开始排列,或者 center,在中间排列。

你也可以把值设置为 space-between,把元素排列好之后的剩余空间拿出来,平均分配到元素之间,所以元素之间间隔相等。或者使用 space-around,使每个元素的左右空间相等。

在这里插入图片描述

在实例中尝试下列 justify-content 属性的值:

  • flex-start(默认值):左对齐
    在这里插入图片描述

  • flex-end:右对齐
    在这里插入图片描述

  • center:居中
    在这里插入图片描述

  • space-around:每个项目两侧的间隔相等,即项目之间的间隔比项目与边框的间隔大一倍
    在这里插入图片描述

  • space-between:两端对齐,项目之间间隔相等
    在这里插入图片描述

.box {
  display: flex;
  justify-content: flex-start;
}
<div class="box">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
</div>

在这里插入图片描述

7.2 align-items

align-items 属性可以使元素在交叉轴方向对齐。

这个属性的初始值为 stretch,这就是为什么 flex 元素会默认被拉伸到最高元素的高度。实际上,它们被拉伸来填满 flex 容器——最高的元素定义了容器的高度。

在这里插入图片描述

你也可以设置 align-items 的值为 flex-start ,使 flex 元素按 flex 容器的顶部对齐,flex-end 使它们按 flex 容器的下部对齐,或者 center 使它们居中对齐。在实例中尝试——我给出了 flex 容器的高度,以便你可以看到元素在容器中移动。看看如果更改 align-items 的值为下列值会发生什么:

  • stretch:(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度
    在这里插入图片描述

  • flex-start:起点对齐
    在这里插入图片描述

  • flex-end:终点对齐
    在这里插入图片描述

  • center:中点对齐
    在这里插入图片描述

  • baseline:项目的第一行文字的基线对齐
    在这里插入图片描述

.box {
  display: flex;
  align-items: flex-start;
}
<div class="box">
  <div>One</div>
  <div>Two</div>
  <div>Three
    <br>has
    <br>extra
    <br>text
  </div>
</div>

在这里插入图片描述

评论 38
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Microi风闲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值