首页 > 编程知识 正文

flex详解,简述flex布局的原理

时间:2023-05-03 21:46:26 阅读:190287 作者:191

新的flexbox规范分为两个部分。 一个是容器,另一个是项目。 flexbox是一套布局规格,包含多个css属性,所以` float: left; `这样简单的布局更复杂。

基本原理

容器有主轴和纵轴的概念,缺省主轴(main-axis )为横向,从左到右,纵轴为纵向,从上到下。 其中所有孩子的布局都受这两个轴的影响。 如下所述,有很多相关的css属性通过改变主轴和纵轴的方向来实现不同的布局效果。

在div上设置` display: flex `或` display: inline-flex `制成flex容器。 然后为其中的每个孩子设置` flex: [number] `,使容器的宽度按比例分配。 例如,在3个item分别被设置了` flex :1 ` ` flex :2 ` ` flex :1 `的情况下,他们以1-2-1的比例分配宽度。

如果item没有设置` flex `而是设置了宽度,例如` width: 100px `的话,其宽度不受flex容器的影响,但是其他设置了` flex: [number] `的容器将其余部分按比例分配即使采用(width: 100px )方式确定宽度,除了与flex: 1的宽度计算方式不同以外,其他方式也不会改变。 实际上,如果某个孩子没有用flex: 1方式定义宽度,那么应该根据flex以外的方式优先计算其宽度,声明flex的其他孩子应该按比例分配剩馀的宽度。 如下图所示,其中只有第一个孩子声明` flex:1 `,后面的孩子没有声明宽度。 那么,在flexbox容器中,后面的7个孩子都是由他们中的文字展开的宽度,剩下的宽度都分配给了第一个孩子。

接下来我也会好好谈谈` flex: 1`定义孩子宽度的详细情况。

container

在display `display: flex `或display: inline-flex `中声明flexbox容器

灵活目录

items的排列方向实际上改变了上述主轴方向,因此此属性会影响其他属性。 因为整个flexbox的布局由主轴和纵轴决定。

行:从左向右行:从右向左行:从上到下行:从下到上

以下是这四个值的结果

flex-wrap在内容超过后是否换行。

nowrap :不换行,缩小每个孩子的宽度,挤成一行。 wrap:换行符。 wrap-inverse:会换行,但换行方向相反。 (例如,默认情况下,它会换行到下一行,但此属性会换行到上一行。

如下图所示,分别是上述3个值的效果,每个孩子的宽度为40px,8个孩子已经超过了容器200px的宽度。

flex-flow flex-direction和flex-wrap的组合写法。

justify-content不知道如何正确翻译justify这个词。 其作用是定义如何分配剩余的空白空间。

flex-start :主轴方向flex-end:主轴相反方向center:在中间的space-between:之间有空白。 space-around:的中央和两侧有空白。 其中两边的空白是中间的一半宽,可以理解为每个孩子两边都有同样宽的空白,且空白不合并。

如上所述,flex-direction会改变主轴的方向。 接下来,我们来看一下flex-direction是默认的五个不同值之间的差异。

发现了错误。 在chrome下,在调试器下直接切换space-between space-around无效。 然后设置` flex-direction: column `,可以看到他们的主轴从上下变化:

align-items的孩子对齐方法,这个很容易理解。 是孩子的对齐方式。 请注意,此处的“对齐”是指垂直对齐方法。 因此,此属性也受` flex-direction `的影响。

例如,我有一个100 px高的容器,默认为scratch。 纵轴表示装满容器。

如上图所示,只定义了容器的高度,缺省情况下儿童的高度会填满容器。 如果我改成` align-items:flexstart `,就会变成这样

对齐项目的所有属性值是flex-start:纵轴开始flex-end:纵轴结束center:纵轴中心baseline:纵轴的baseline

scratch: 填满容器。
align-content 当有多行内容的时候,这个属性决定了如何对多行内容进行对齐。 注意,上面的每一个属性都是以每一个item为单位进行布局,而这个属性是以一行为单位进行布局。感觉这个属性应该叫 align-lines 比较合适。 如果只有一行的话,这个属性是不生效的,所以一定要配合 `flex-wrap: wrap` 来使用。



items
order 很简单,排列顺序,没什么好讲的。
flex-grow 定义了主轴上,孩子分配剩余空白区域的比例。 比如现在有三个孩子,宽度是 40px,并且`margin: 2px`,容器宽度 200px,那么默认情况下,有 `(200-44)/3=68` 空白的宽度。
如果你给每个孩子都定义了 `flex-grow: 1`,那么他们平分剩余的空白区域,就是这样:

这时候,如果我给第二个孩子定义 `flex-grow: 2`,那么它的宽度是怎么计算的? 其实就是把 68px 的空白按照`1:1:2` 的比例分配给他们,也就是 `17:17:34` 的大小来分配,所以三个孩子的宽度分别为 `57,57,74`:

如果你给一个孩子设置为 `flex-grow: 0` 那么它不会参与剩余空白的分配。
flex-shrink 如果孩子的总宽度超过了容器宽度(主轴),那么这个属性定义了如何把超过的那部分平分到每个孩子身上,然他们按比例来缩小一定的宽度从而可以在容器中装得下。
假设我们现在有一个容器,宽度为 `200px`,有三个孩子宽度为 `100px`,并且每个海泽有 `margin: 2px`,那么三个孩子总宽度 `(100+2*2)*3 = 312px` ,超过了 112px。 所以我们从这三个孩子身上砍下 `112px` 宽度,以让他们能装进容器中。 默认情况下,是 按 `1:1:1` 的比例来砍,也就是每个孩子各砍下 “112/3=37.3“,所以默认每个孩子宽度是 100-37.3=62.7。 那么现在我们定义第二个孩子 `flex-shrink: 2`,其他两个为 1,那么他们会把 `112px` 的宽度按 `1:2:1` 来平分。于是第二个孩子宽度为 `100-(112/4*2)=44px` 宽度,另外两个为`100-(112/4*1)=72px`:

flex-basis 在分配空白之前,孩子的宽度,默认是 `auto`,也就是孩子本身的宽度,如果你定义了 `flex-basis: 50px;` ,那么它就会覆盖掉孩子的宽度。
flex 他是 flex-grow, flex-shrink, flex-basis三个属性的快捷方式。默认是 0, 1, auto。 强烈建议用这个属性,而不是分别设定三个属性,因为这个属性可以“聪明地”设定三个属性来达到你要的效果。 你可以认为 flex 属性就是定义了每个孩子分隔父容器宽度的比例。 比如容器 200px,三个孩子设置了 flex 分别是 1-2-1,那么他们实际上宽度是 50px 100px 50px。
如果你比较较真,这个flex属性到底是如何工作的? 实际上他是自动设置了三个属性:flex-grow, flex-shrink, flex-basis。 而且为什么强烈推荐用flex,而不是分别设定三个属性,是因为 flex 属性会自动计算 flex-basis 属性的值。 比如容器宽度为 200px,然后你给三个孩子分别设置了 .item1 { flex: 1;} .item2 { flex: 2;} .item3 { flex: 1;} 那么他们的宽度将是 50-100-50 如果你想单独设置每一个孩子的三个属性,你会发现竟然无法按照 1-2-1 的比例平分了。 因为flexbox的计算每个孩子的宽度分两部分: 1,计算出孩子本身的宽度 2,将剩余的空白按比例平分给每一个孩子。 所以你如果这样定义: .item1 { flex-grow: 1;flex-shrink:1;} .item2 { flex-grow: 2;flex-shrink:2;} .item3 { flex-grow: 1;flex-shrink:1;} 你会发现孩子不是 50-100-50 的宽度,因为他们是按照 1-2-1 平分了剩余的空白。 假设每个孩子本身是 20px 宽度,那么这么定义之后,他们其实按 1-2-1 平分了 140px 的空白。加上自身宽度之后比例 显然不是 1-2-1。 所以你还需要把它们的flex-basis也设置成 1-2-2,这么写才行: .item1 { flex-grow: 1;flex-shrink:1;flex-basis: 20px;} .item2 { flex-grow: 2;flex-shrink:2;flex-basis: 40px;} .item3 { flex-grow: 1;flex-shrink:1;flex-basis: 20px;}
而这样就很麻烦,不如直接用 flex 属性来定义。而事实上,你可以认为 flex 属性就是帮你做了上面的计算。
align-self 单独在当前孩子上覆盖了 align-items 属性。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。