十分钟解决你对Flex的疑惑

1,364 阅读7分钟

我正在参加「掘金·启航计划」

前言

hi大家好,我是小鱼,一个一年前端的小菜鱼。这一年来了解到了很多技术,但平时的工作无非就是拧拧螺丝,可虽是拧螺丝,但有些时候也并不流畅,这让我深度质疑自己的基础能力。为了以后能够快速流畅的拧大螺丝,所以我决定开启涅槃计划,复习自己所学到的技术,把地基打牢。希望在这个过程中能重生并进一步升华自己。

涅槃计划CSS篇

今天复习的是Flex。相信这个大家已经非常熟悉,当下前端仔的一个主流布局方式之一,如果有小伙伴不会的或者不熟悉的今天就跟着我一起学习或者再复习一下吧。

Flex的基本概念

Flex 是 Flexible Box 的缩写,意为“弹性布局”或者“弹性盒子”,是 CSS3 中的一种新的布局模式,可以简便、完整、响应式地实现各种页面布局,当页面需要适应不同的屏幕大小以及设备类型时非常适用。目前,几乎所有的浏览器都支持 Flex 布局。想要熟练的运用Flex就必须要掌握其两个核心概念容器

1. 轴

image.png

在flex容器中默认存在两条轴,水平主轴(从左到右)垂直的交叉轴(从上到下),默认的主轴是水平的,当然你可以通过flex-direction来切换主轴和方向,这个属性下面详解。

2. 容器

首先,实现 flex 布局需要先指定一个父容器,任何一个容器都可以被指定为 flex 布局,这样容器内部的元素就可以使用 flex 来进行布局。容器分为父容器和子容器。

注意:当父容器设置 flex 布局之后,子元素的 float、clear、vertical-align 的属性将会失效。

父容器

  1. flex-direction
  2. flex-warp
  3. flex-flow
  4. justify-content
  5. align-items
  6. align-content

属性有点多,沉住气,跟着小鱼的脚步一个一个的攻破!

鱼哪有脚......

1. flex-direction

决定主轴的方向(即项目的排列方向)

.container {
    flex-direction: row | row-reverse | column | column-reverse;
}

默认值是flex-direction: row,主轴为水平方向,从左到右。

image.png flex-direction: row-reverse 主轴为水平方向,从右到左

image.png

flex-direction: column 主轴为垂直方向,从上到下

image.png

flex-direction: column-reverse 主轴为垂直方向,从下到上

image.png

2. flex-wrap

决定容器内项目是否可换行

.container {
    flex-wrap: nowrap | wrap | wrap-reverse;
}

默认值:flex-wrap: nowrap 不换行,即当主轴尺寸固定时,当空间不足时,项目尺寸会随之调整而并不会挤到下一行。

image.png

flex-wrap: wrap 项目主轴总尺寸超出容器时换行,第一行在上方

image.png

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

image.png

3. flex-flow

flex-direction 和 flex-wrap 的简写形式

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

先看一张属性图↓

image.png

大概记住这个属性是什么的简写就行了,就怕面试问你,反正我工作中几乎没用到哈哈哈。

4. justify-content

指定项目在主轴的对齐方式

.container {
    justify-content: flex-start | flex-end | center | space-between | space-around;
}

以下默认是在水平主轴上

默认值:justify-content: flex-start 左对齐

image.png

justify-content: flex-end 右对齐

image.png

justify-content: center 居中

image.png

justify-content: space-between 两端对齐,项目之间的间隔相等,即剩余空间等分成间隙。

image.png

justify-content: space-around每个项目两侧的间隔相等,所以项目之间的间隔比项目与边缘的间隔大一倍。

image.png

5. align-items

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

.container {
    align-items: flex-start | flex-end | center | baseline | stretch;
}

默认值为 align-items: stretch 即如果项目未设置高度或者设为 auto,将占满整个容器的高度。

image.png

align-items: flex-start 交叉轴的起点对齐

image.png

align-items: flex-end 交叉轴的终点对齐

image.png

align-items: center 交叉轴的中点对齐

image.png

align-items: baseline 项目的第一行文字的基线对齐,文字底部为主

image.png

6. align-content

定义了多根轴线的对齐方式,如果项目只有一根轴线,那么该属性将不起作用

.container {
    align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}

这里稍微给大家解释一下,当你 flex-wrap 设置为 nowrap 的时候,容器仅存在一根轴线,因为项目不会换行,就不会产生多条轴线。所以设置该属性不会起作用。当你 flex-wrap 设置为 wrap 的时候,容器可能会出现多条轴线,这时候你就需要去设置多条轴线之间的对齐方式了。

默认值为 align-content:stretch

image.png

align-content:flex-start 两条轴线全部在交叉轴上的起点对齐

image.png

align-content:flex-end 两条轴线全部在交叉轴上的终点对齐

image.png

align-content:center 两条轴线全部在交叉轴上的中间对齐

image.png

align-content:space-between 两条轴线两端对齐,之间的间隔相等,即剩余空间等分成间隙。和justify-content属性有点相似

image.png

align-content:space-around 每个轴线两侧的间隔相等,所以轴线之间的间隔比轴线与边缘的间隔大一倍。

image.png

父容器的属性就讲完了,别停,一鼓作气,一起深入item上的属性!!

子容器

  1. order
  2. flex-basis
  3. flex-grow
  4. flex-shrink

1. order

定义项目在容器中的排列顺序,数值越小,排列越靠前,默认值为 0,可以为负数

image.png

2. flex-basis

定义了在分配多余空间之前,项目占据的主轴空间,浏览器根据这个属性,计算主轴是否有多余空间

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

默认值:flex-basis: auto,即项目本来的大小, 这时候 item 的宽高取决于 width 或 height 的值。

这里要说明一下宽度取值优先级的问题 → max-width/min-width > flex-basis > width

  • 当 flex-basis 值为 0 时,是把该项目视为零尺寸的,即使设置其宽度为100px,也不会生效,除非设置max-width/min-width。
  • 当 flex-basis 值为 auto 时,则跟根据尺寸的设定值(假如为 100px),则这 100px 不会纳入剩余空间。

3. flex-grow

MDN上的定义是弹性盒子项(flex-item)的拉伸因子,默认值0

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

拉伸因子,那么具体是怎么拉伸的呢,或者该拉伸多少。这就要了解到一个剩余空间,剩余空间是怎么算出来的呢?上代码

<div class="warp" style="width: 500px;">
    <div class="item" style="width: 50px;">50</div>
    <div class="item" style="width: 100px;">100</div>
    <div class="item" style="width: 150px;">150</div>
</div>

image.png

现在我们来分别设置flex-grow这个属性,让子容器去瓜分剩余空间

<div class="warp" style="width: 500px;">
    <div class="item" style="width: 50px;flex-grow: 1;">50</div>
    <div class="item" style="width: 100px;flex-grow: 2;">100</div>
    <div class="item" style="width: 150px;flex-grow: 3;">150</div>
</div>

image.png

这里可以看到子容器的总宽度只有300px,但是却占满了父容器的500px,flex-grow 属性决定了子容器要占用父容器多少剩余空间。那这个flex-grow到底是怎么计算的呢

计算方式如下

  • 剩余空间:x
  • 假设有三个flex item元素,flex-grow 的值分别为a, b, c
  • 每个元素可以分配的剩余空间为: a/(a+b+c) * x,b/(a+b+c) * x,c/(a+b+c) * x

4. flex-shrink

MDN上的定义是指定了 flex 元素的收缩规则

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

默认值: 1,即如果空间不足,该项目将缩小,负值对该属性无效。废话少说上代码

<div class="warp" style="width: 150px;">
    <div class="item" style="width: 50px;">50</div>
    <div class="item" style="width: 50px;">50</div>
    <div class="item" style="width: 50px;">50</div>
    <div class="item" style="width: 50px;">50</div>
</div>

image.png

虽然每个项目都设置了宽度为 50px,但是由于自身容器宽度只有 150px,这时候每个项目会被同比例进行缩小,因为默认值为 1。

  • 如果所有项目的 flex-shrink 属性都为 1,当空间不足时,都将等比例缩小。
  • 如果一个项目的 flex-shrink 属性为 0,其他项目都为 1,则空间不足时,前者不缩小。

end

好了,今天的Flex就复习完了,小伙伴们不熟悉的一定要自己动手敲一遍哦,后面还会再出一篇关于flex的布局方式和技巧

今天是1024,祝各位程序猿们节日快乐,步步高升!

1666582795510.png