通过和Grid布局对比学习Flex布局

945 阅读10分钟
  • flex容器
    • 基本特性(同grid容器)
    • flex容器与grid容器的富余空间管理对比
    • flex-container与其margin
    • flex-flow:如何在container中放置item?
    • align-items:在容器中统一管理item的富余空间
  • flex-item:容器中的每一项
    • flex-basis
      • 默认值:auto
      • flex-basis设置的是item在主轴上的大小
      • 与width/height、min/max-width/height
    • flex-item与margin
    • flex-grow和flex-shrink
      • 默认值
      • 关于生长和压缩的计算
        • flex-grow、flex-shrink针对的也是主轴上怎么进行伸缩
      • 和justify/align-content 的比较
    • align-self
    • 绝对项目与相对项目
  • flex和grid总结
    • 盒子模型方面
    • 富余空间
      • 容器富余空间管理
      • item富余空间管理
      • flex与侧轴
    • 其它
  • 附表:flex系统中的关键字值和默认值

notify

previously:

5分钟掌握Grid布局【多图示例】

本篇参考:

嗯,原本的标题很皮,感觉会被打,就改了个普通的

flex容器

基本特性(同grid容器)

关键词:独占一行margin自动填充

首先设置了display:flex元素容器并不会改变它本身的盒子模型(不会转换为border-box什么的,和grid-container是一致的)。

flex容器与grid容器的富余空间管理对比

flex容器和grid容器的富余空间管理都是针对flex/grid容器所开辟的空间的。

flex容器的富余空间是指除去所有flex-item项所占据的空间外的剩余空间。

[danger] 注意: 富余空间并不是图中flex-container的margin部分。

grid容器的富余空间是指除去grid网格外的剩余空间(注意,不是gird-item,嗯,是所有grid-item的集合再加上grid-gap)

[danger] 注意: 富余空间并不是图中grid-container的margin部分。


上面我们知道了富余空间是什么,那么怎么操作富余空间呢,

我们可以通过justify-content/align-content(grid/flex都有)来操作父容器的富余空间

另外在API记忆上,flex和grid系统一样都些个类似的属性,它们对应的效果分别是:

  • 靠左 grid是start flex要带前缀 flex-start
  • 居中 都是center
  • 靠右 grid是end flex要带前缀 flex-end
  • 让每一个item大小一样(space-around)
  • 第一个和最后一个item分别占据容器开辟的空间的首尾,中间的item之间间距相等(space-between)
  • space-evenly:让每个item之间的间距相等(包括首尾)

以上是几个最常用的,除此之外还有很多点我

还需要注意的一点是,grid的align/justify-content都还有一个stretch的值(虽然貌似毫无卵用)

,而flex只有align-content有这个值,且这个值是align-content的初始值

flex-container与其margin

我们已经知道一旦元素设置了display:flex就会成为一个flex-container,它会独占一行,且如果border-box的大小不足以独占一行会用margin填充。

So我们仍然可以对flex-container使用margin:auto来使其居中什么的。

再次强调: 请注意区分flex-container的富余空间和margin,他们并不是同一个东西

flex-flow:如何在container中放置item?

flex-flowflex-directionflex-wrap的复合起来的属性。

其中flex-direction决定的是内部item是从左往右排列(row)还是从上往下排列(column),一旦决定了direction,我们也就顺道决定了这个flex的主轴

而flex-wrap决定的是item排列时,若空间不够了,换不换行。(若不换行就会被压缩)

并且这两个属性都值都可以添加一个-reverse后缀,这表示颠倒排列的顺序。

align-items:在容器中统一管理item的富余空间

align-items 这个属性能统一处理item中的侧轴的富余空间。(注意是item自己内部的富余空间

注意,这个属性并不能对某个item进行订制,而是会对所有item的富余空间进行相同的安排(操作)。

另外它和grid系统的api不同,这货只有align-items,是的,只有,并没有justify-items!!。(grid是有的)

MDN官网截图为证

flex-item:容器中的每一项

flex-basis

默认值:auto

一个flex-item的基础大小,默认值为auto,也就是每个item自己的内容大小。

需要注意的是,flex-item并不像gird-item,它并不是一个margin-box,而是一个正常的盒模型。

flex-basis设置的是item在主轴上的大小

flex-basis指定并不一定是一个item的宽度,确切的说它决定的是一个item在主轴上的长度。

例如我们将flex-direction设置为column时(主轴变更为y轴)

与width/height、min/max-width/height

嘛,其实basis就是width or height(根据主轴不同,有肯能是width也有可能是height)。

当设置了basis你最好就不要再设置width or height,嗯,貌似有什么兼容性bug一类的。

另外你最好也不要给这些item设置border、padding、margin,特别是当你想要使用grow或则shrink的时候,这会导致效果的不可预期。

flex-item与margin

给flex-item设置相应的margin auto能达到和justify-content相同的效果,不过这样的话,父容器若还有justify-content就不再影响到flex-item了。

flex-grow和flex-shrink

嗯,这是整个flex布局中最精华的部分了,正是因为这两个属性,才让Flex所代表的伸缩二字名副其实。

默认值

flex-grow:0;
flex-shrink:1;

其中grow是生长的意思,shrink是压缩的意思,默认情况下,item不会生长(即使存在富余空间),但是会被压缩(flex-container开辟的空间<items所占据的空间时)

关于生长和压缩的计算

当设置了生长时,每个item增加的大小是按照下面这样一个计算公式来计算的

可用空间 =(容器大小 - 所有相邻项目flex-basis总和) 
每项伸缩大小 = 伸缩基准值 + ((可用空间 / 所有相邻项目flex-grow总和) x 此项的flex-basis值)

而压缩时,是按照下面这样计算的

//假如tem1-4的basis依次为100、200、200、200
//item1-4的shrink依次为1、2、3、1

所有项目之和 = 项目一(1x100) + 项目二(2x200) + 项目三(3x200) + 项目四(1 x 200) = 所有项目总和(1400)

项目二收缩因数 = 项目二(2 x 200px)/所有项目之和(1400) = 0.286

第二项移除空间 = 项目二收缩因数(0.286) x 负可用空间(-200px) = -57.142向下舍入为57。
flex-grow、flex-shrink针对的也是主轴上怎么进行伸缩

和justify/align-content 的比较

首先justify/align-content是针对flex容器的富余空间的,

flex-grow其实也是针对的其父,flex容器的,只不过相较于justify-content只是分配富余空间给item(分配的富余空间并不算在每一项的content里),它是对富余空间的利用的另外一种形式,它会消耗掉富余空间。

虽然说justify-content/align-content中的stretch也能达到差不多的效果,但它们最主要的作用还是分配富余空间给每个item。

另外flex-grow 并不能影响侧轴(的富余空间),align-content才能,并且它的默认值为stretch(也就是会让item铺满整个侧轴的富余空间)。

实际上关于侧轴的富余空间,因为flex只是一个一维布局,所以要是侧轴的富余空间被消耗,只会存在一种效果,那就是stretch平铺侧轴上只会有一个item)。


flex-shrink的功效则和富余空间完全没有关系,它是当父容器(flex-container)开辟的空间不够用的时候的选择。默认情况下,它会等比例的压缩所有item。

align-self

首先要声明的一点是,在flex系统中,我们只能管理flex-item侧轴上的富余空间,so只有align-self这一个api没有什么justify-self!!

相较于align-item,align-self能允许我们单独管理某一个item中的富余空间

绝对项目与相对项目

相对项目

flex:auto,即flex:1 1 auto时,flex-item既可伸又可缩,但它的实际宽度是基于basis之上的。

绝对项目

flex:1,即flex: 1 1 0时,flex-item既可伸又可缩,并且它的basis为0,这意味着flex-item的宽度只基于flex的生长

flex和grid总结

盒子模型方面

相同之处:

flex系统的flex-container和grid系统的grid-container一样,都会让元素起到block化的效果独占一行(如果手动设定了固定宽度,不够一行的部分会被margin填充)

不同之处:

grid系统的grid-item你可以把它当做一个margin-box(不乱给grid-item设置grid系统中没什么意义的宽高的话)

而flex系统的flex-item只是一个普通的盒子模型。

富余空间

容器富余空间管理

相同之处:

都能够用justify-contentalign-content管理container父容器的富余空间。

不同之处:

  1. grid的富余空间是除却网格的部分,这里的网格,不仅包括每一项item,还包括网格的gap

  2. flex系统中justify-content和align-content的start、end不叫start、end而叫flex-startflex-end

  3. flex系统中只有align-contentstretch值,而grid系统中justify-content和align-content都有?(但貌似grid justify-content的stretch无效?可以在template的时候使用fr达到stretch效果,或则在template中只用grid-line分区)

  4. flex系统还能通过在item上设置grow来利用富余空间,虽然只是主轴上的富余空间,侧轴上的仍然需要使用align-content。

item富余空间管理

flex的item只能进行侧轴上的富余空间管理。

它只有align-self,而没有justify-self

flex与侧轴

flex系统中的侧轴默认是平铺的stetch,不论是align-content还是align-item,flex-item在侧轴上永远是从头躺到尾。

其它

grid系统中的主轴侧轴并不会发生交换,主轴永远是x轴,侧轴永远是y轴。

附表:flex系统中的关键字值和默认值

flex:none | <' flex-grow '> <' flex-shrink >'? || <' flex-basis '>

如果「flex: 0 auto」或者「flex: initial」, 则其计算值为「0 1 auto」,即「flex」默认值

如果缩写「flex: 1」, 则其计算值为「1 1 0%」

如果缩写「flex: auto」, 则其计算值为「1 1 auto」

如果「flex: none」, 则其计算值为「0 0 auto」

flex-grow:

默认值:flex-grow:0

flex-shrink:

默认值:flex-shrink:1

flex-basis: | | auto | content

默认值 flex-basis:auto

<length>:用长度值来定义宽度,不允许负值

<percentage>:用百分比来定义宽度,不允许负值

auto:无特定宽度值,取决于其它属性值

content:基于内容自动计算宽度

flex-flow:<' flex-direction '> || <' flex-wrap '>

flex-direction:row | row-reverse | column | column-reverse 默认:row

flex-wrap:wrap | wrap-reverse | nowrap | nowrap-reverse 默认:nowrap

justify-content:flex-start | flex-end | center | space-between | space-around

默认值 :flex-start

align-content:flex-start | flex-end | center | space-between | space-around | stretch

默认值:stretch

align-items:flex-start | flex-end | center | baseline | stretch

默认值:stretch

align-self:auto | flex-start | flex-end | center | baseline | stretch

默认值:auto

order:

默认值0,可以为负值