领略flex的布局之美

163 阅读10分钟

flex布局 在某种程度上,简便我们布局的一个难题,接下来的篇幅将介绍它的使用👇

![flex-布局详解](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/cad4dc9d88834a8e831c03de2b9e624c~tplv-k3u1fbpfcp-zoom-1.image)

需要本文的Xmind导图的话,移步公众号--前端UpUp,回复flex关键字即可。

flex基本概念

要想熟练掌握flex布局的话,你需要理解两个概念:容器👇

![flex布局基本概念](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/30ae5302cb1c4488af8e011bcdb9a64b~tplv-k3u1fbpfcp-zoom-1.image)

从上面图来看,我们将flex布局分为两部分讲,容器

  • 主轴(mian axis)
  • 交叉轴(cross axis)

容器

  • 父容器(container)
  • 子容器(item)

打个预防针,flex布局涉及到12个CSS属性,父容器,子容器各6个。

接下来先梳理常见的属性,不常见的放在进阶部分来梳理。

我们知道,包括主轴交叉轴,那么它们的方向是如何决定呢?我们直接从一张图看懂它👇

![flex轴的概念](data:image/svg+xml;utf8,)

默认情况下,主轴的方向是从左向右的,交叉轴垂直于主轴,逆时针方向90度,那么接下来我们看flex-direction是如何决定主轴的。讲这个之前,我们需要明白👇

  • 交叉轴是由主轴决定的,主轴又是由flex-direction决定的。

  • flex-direction属性设置在父容器上,这样子才可以生效。

    flex-direction: row | row-reverse | column | column-reverse 复制代码

![flex-direction取值](data:image/svg+xml;utf8,)

首先布局如下👇

<div class="wrapper">
        <div class="flex1">子盒子#flex1: 1 </div>
        <div class="flex2">子盒子#flex2: 1 </div>
</div>
复制代码

接下来,我们看看他们的效果吧👇

flex-direction: row

当你给父盒子(wrapper)设置属性
flex-direction: row
复制代码

效果👇

![flex-direction-row](data:image/svg+xml;utf8,)

结论

  • flex容器的主轴被定义为与文本方向相同。 主轴起点和主轴终点与内容方向相同。
  • 简单理解就是主轴沿着水平方向向右

flex-direction: row-reverse

当你给父盒子(wrapper)设置属性
flex-direction: row-reverse
复制代码

效果👇

![](data:image/svg+xml;utf8,)

我们可以看到这两个盒子的位置发生了变化,这个就是主轴起点和主轴终点位置置换的原因。

结论

  • 表现和row相同,但是置换了主轴起点和主轴终点。
  • 简单理解就是主轴沿着水平方向向左,与文本方向相反。

flex-direction: column

当你给父盒子(wrapper)设置属性
flex-direction: column
复制代码

效果👇

![flex-direction-column](data:image/svg+xml;utf8,)

可以看到,子盒子的布局发生了变化,形成了在Y轴上的布局方式,并且书写方式跟布局一样。

结论

  • flex容器的主轴和块轴相同。主轴起点与主轴终点和书写模式的前后点相同
  • 简单的理解,就是主轴变成Y轴方向,方向从上到下布局。

flex-direction: column-reverse

当你给父盒子(wrapper)设置属性
flex-direction: column-reverse
复制代码

效果👇

![flex-direction-column-reverse](data:image/svg+xml;utf8,)

可以看到,子盒子的布局跟column差不多,唯一不同的是,方向上发生了变化。

结论

  • 表现和column相同,但是置换了主轴起点和主轴终点
  • 简单的理解,就是主轴变成Y轴方向,方向从下到上,与书写的方向相反。

容器

这里就分为父容器子容器,我们先来看看父容器👇

父容器

  • justify-content: 设置子元素在主轴方向上的对齐方式
  • align-items: 设置子元素在交叉轴方向上的对齐方式
![父容器常见属性](data:image/svg+xml;utf8,)

justify-content

这个属性设置在父容器上,决定子元素在主轴方向上的对齐方式,我们看看它们具体表现吧👇

justify-content: flex-start

当你给父盒子(wrapper)设置属性
justify-content: flex-start
复制代码

效果👇

![justify-content-flex-start](data:image/svg+xml;utf8,)

结论,子元素沿着主轴方向开始对齐。

justify-content: flex-end

当你给父盒子(wrapper)设置属性
justify-content: flex-end
复制代码

效果👇

![justify-content-flex-end](data:image/svg+xml;utf8,)

结论,子元素沿着主轴方向终点对齐。

justify-content: center

当你给父盒子(wrapper)设置属性
justify-content: center
复制代码

效果👇

![justify-content-center](data:image/svg+xml;utf8,)

结论,子元素在主轴方向上水平居中。

justify-content: space-between

当你给父盒子(wrapper)设置属性
justify-content: space-between
复制代码

效果👇

![justify-content-space-between](data:image/svg+xml;utf8,)

结论,子元素在主轴方向上两端对齐,项目之间间隔相等

justify-content: space-around

当你给父盒子(wrapper)设置属性
justify-content: space-around
复制代码

效果👇

![justify-content-space-around](data:image/svg+xml;utf8,)

结论,子元素在主轴方向上均匀排列每个元素,每个元素周围分配相同的空间

align-items

这个属性设置在父容器上,决定子元素在交叉轴方向上的对齐方式,我们看看它们具体表现吧👇

align-items: flex-start

当你给父盒子(wrapper)设置属性
align-items: flex-start
复制代码
![align-items-flex-start](data:image/svg+xml;utf8,)

结论,子元素在交叉轴方向上起点对齐。

align-items: flex-end

当你给父盒子(wrapper)设置属性
align-items: flex-end
复制代码
![align-items-flexend](data:image/svg+xml;utf8,)

结论,子元素在交叉轴方向上终点对齐。

align-items: center

当你给父盒子(wrapper)设置属性
align-items: center
复制代码
![align-items-center](data:image/svg+xml;utf8,)

结论,子元素在交叉轴方向上居中对齐。

align-items: baseline

当你给父盒子(wrapper)设置属性
align-items: baseline
复制代码
![align-items--baseline](data:image/svg+xml;utf8,)

结论,子元素在交叉轴方向上以文字基线对齐,具体不清楚的,可以自行百度。

align-items: stretch

当你给父盒子(wrapper)设置属性
align-items: stretch
复制代码
![align-items--stretch](data:image/svg+xml;utf8,)

结论,这个属性是默认的,如果项目未设置高度或者设为 auto,将占满整个容器的高度。

子容器

先看张图片

![子容器常见的属性](data:image/svg+xml;utf8,)

子容器的话,这里就介绍两个属性👇

  • flex属性 定义在主轴是如何伸缩的
    • 子容器是有弹性的,它们会自动填充剩余空间,子容器的伸缩比由flex属性决定。
    • flex是多个属性的缩写,允许1-3个值的连写,具体参考上面的图。
  • align-self属性 单独设置子容器如何沿交叉轴排列
    • 每个子容器都可以单独定义沿交叉轴排列方式。
    • 该属性的取值跟父容器中的align-items属性一致,如果两者相同的话,则以子容器align-self属性为主。

flex作用规则

  • 三个属性的简写,是flex-grow flex-shrink flex-basis的简写

  • 常用简化写法👇

    • flex:1 —> flex:1 1 0%;
    • flex:3 —> flex:3 1 0%;
    • 注意:flexbox布局和原来的布局是两个概念,部分css属性在flexbox盒子里面不起作用,eg:float, clear, column,vertical-align 等等

    注意👉flex-grow flex-shrink flex-basis 这三个属性会在后续介绍 复制代码

具体的flex取值问题,可以参照下面的图👇

![flex取值问题](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7d9db21dde9249ecbaa9204fd2397e4e~tplv-k3u1fbpfcp-zoom-1.image)

align-self作用规则

// 起始端对齐
align-self : flex-start;
复制代码
![align-self-flexStart](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/aa6a46b24f2b45d3ac93f9a9fffad31e~tplv-k3u1fbpfcp-zoom-1.image)
// 末尾段对齐
align-self : flex-end;
复制代码
![align-self-flex-end](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e986cd6721f0486aaeb54ffe2dc93591~tplv-k3u1fbpfcp-zoom-1.image)
基线对齐// 末尾段对齐
align-self : baseline;
复制代码
![align-self-baseline](data:image/svg+xml;utf8,)

可以看到的话,它们对齐的方式是第一行文字的基线。

拉伸对齐
align-self : stretch;
复制代码
![align-items-stretch](data:image/svg+xml;utf8,)

flex更深入了解

上面介绍的常见几个属性掌握的话,基本上可以满足日常的开发布局需求,剩下的一些属性,接下来将梳理一遍,这样子的话,早日成为flex布局进阶者

父容器

  • flex-wrap 设置换行方式

    • 绝对子容器是否可以选择换行,一般而言有三种状态,支持换行的话,也支持逆序换行。
  • flex-flow 设置轴向与换行组合

    • 是 flex-direction 和 flex-wrap 的简写。
    • 所以只要掌握,flex-directionflex-wrap即可。
  • align-content 多行沿交叉轴对齐方式

    • 当子容器多行排列时,设置行与行之间的对齐方式。

flex-wrap

设置子容器的换行方式,通常有三个取值👇

flex-wrap: wrap | nowrap | wrap-reverse
复制代码

三种情况👇

// 允许换行
flex-wrap : wrap
复制代码

效果👇

![flex-wrap-wrap](data:image/svg+xml;utf8,)
// 不允许换行
flex-wrap : nowrap
复制代码

效果👇

![flex-wrap-nowrap](data:image/svg+xml;utf8,)
// 允许逆向换行
flex-wrap : wrap-reverse
复制代码

效果👇

![flex-wrap-wrapReverse](data:image/svg+xml;utf8,)

flex-flow

先来一张图👇

![flex-flow取值](data:image/svg+xml;utf8,)

更多取值信息请查看 flex-directionflex-wrap

可以查看MDN上,或者把之前的flex-directionflex-wrap 两者取值看过一遍,那么使用这个属性就没有问题啦,这里也就不过多的举例子了,取值有三种情况👇

  • 单独设置flex-direction取值,比如

    • flex-flow: row | column 复制代码
  • 单独设置flex-wrap取值

    • flex-flow: wrap | nowrap | wrap-reverse 复制代码
  • 同时设置两者取值

    • flex-flow: row wrap flex-flow: column nowrap 复制代码

align-content

这个属性是定义子容器在交叉轴的排列方式,也就是对齐方式。

首先上一张图👇

![align-content取值](data:image/svg+xml;utf8,)

根据这些取值,我们来看看布局效果吧👇

// 起始端对齐
align-content: flex-start
复制代码

效果👇

![align-content-flex-start](data:image/svg+xml;utf8,)
// 末尾段对齐
align-content: flex-end
复制代码

效果👇

![align-content-flex-end](data:image/svg+xml;utf8,)
// 居中对齐
align-content: center
复制代码

效果👇

![align-content-center](data:image/svg+xml;utf8,)
// 等间距均匀分布
align-content: space-between
复制代码

效果👇

![align-content-space-around](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/145a1df4a0ca4a13b7320b762bf01a33~tplv-k3u1fbpfcp-zoom-1.image)
// 等边距均匀分布
align-content: space-around
复制代码

效果👇

![align-content-space-around](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/666d82d1ba6142599a534f47c45e99ba~tplv-k3u1fbpfcp-zoom-1.image)
// 拉伸对齐
align-content: stretch
复制代码

效果👇

![align-content-stretch](data:image/svg+xml;utf8,)
// 基线对齐
align-content: baseline
复制代码

效果👇

![align-content-baseline](data:image/svg+xml;utf8,)

子容器

  • flex-grow 设置扩展比例

  • flex-shrink 设置收缩比例

  • flex-basis 设置基准大小

  • order 设置排列顺序

flex-grow

子容器弹性伸展的比例,简单理解,就是把剩余的空间按比例分配给子容器。

我们看个例子

![flex-grow取值](data:image/svg+xml;utf8,)

flex-shrink

子容器弹性收缩的比例。简单理解,就是当你子容器超出的部分,会按照对应的比例给子容器减去对应的值。

我们来看下效果👇

![flex-shrink-取值为0](data:image/svg+xml;utf8,)

当取值为0时,就会溢出,那么我们给它们设置一个值👇

![flex-shrink-取值为1](data:image/svg+xml;utf8,)

这样子的超出的部分就会按照比列减去。

flex-basis

有几个点需要注意的是👇

  • 在不伸缩的情况下,flex-basis给子容器设置大小才有作用。

  • 当主轴为横向时,即👇

    • flex-direction:row | row-reverse 复制代码

    • flex-basis设置的大小为宽度,并且会覆盖witdh值

  • 当主轴为纵向时,即👇

    • flex-direction:column | column-reverse 复制代码

    • flex-basis设置的大小为高度,并且会覆盖height值

我们来看看两种情况👇

当主轴为横向时
flex-direction:row | row-reverse
复制代码

效果👇

![flex-basis-主轴横向时](data:image/svg+xml;utf8,)
当主轴为纵向时
flex-direction:column | column-reverse
复制代码

效果👇

![flex-basis-主轴纵向时](data:image/svg+xml;utf8,)

order

  • 每个子容器的order属性默认为0
  • 通过设置order属性值,改变子容器的排列顺序。
  • 可以是负值,数值越小的话,排的越靠前。

直接看效果图👇

![flex-order](data:image/svg+xml;utf8,)

总结

这个时候,是不是需要总结一下呢👇

先看看子容器属性👇

![flex-子容器属性](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0c5e529f03d345dab4534bf84b1cfd1d~tplv-k3u1fbpfcp-zoom-1.image)

再看看父容器属性👇

![flex-父容器属性](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e2e9733b84e040f296f827ff4148f235~tplv-k3u1fbpfcp-zoom-1.image)

作者:TianTianUp
链接:juejin.cn/post/686691…
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。