Flex布局与缩放比例计算

45次阅读

共计 5284 个字符,预计需要花费 14 分钟才能阅读完成。

一、Flex 布局简介

Flex 是 Flexible Box 的缩写,意为 ”弹性布局“,用来为盒状模型提供最大的灵活性。

任何一个容器 都可以指定为 Flex 布局,也就是说,行内元素也可以设置成 Flex 布局

// 将块级元素 div 设置为 flex 布局
div {display: flex;}
// 将行内元素 span 设置为 flex 布局
span {display: flex;}

采用 Flex 布局的元素,称为 Flex 容器 flex container),简称 ” 容器 “。它的 所有子元素自动成为容器成员 ,称为 Flex 项目flex item),简称 ” 项目“。

二、Flex 布局的默认特性

默认情况下,容器中的所有子元素都将进行水平排列 ,类似于强制进行了一个左浮动,所以 容器子元素的 float 和 clear 属性会失效 。同时, 容器中的子元素的对齐方式将不受 vertical-align 控制,即vertical-align 也会失效

<style>
#main{
    width:800px;
    height:300px;
    display:flex;
    font-size: 20px;
    background: red;
}
</style>

<div id="main">
  <div style="background-color:coral;" class="item-1"> 红色 </div>
  <div style="background-color:lightblue;" class="item-2"> 蓝色 </div>  
  <div style="background-color:lightgreen;" class="item-3"> 带有更多内容的绿色啊 </div>
</div>

没有给容器设置垂直方向对齐方式 同时 容器子元素也没有设置高度 ,那么 容器子元素的高度是和容器的高度是一样的,如上,容器中所有的子元素的高度都会变为 300px。

默认情况下,容器下的子元素的宽度是不会自动放大的 ,即 默认以元素自身的实际宽度显示。如图所示:

默认情况下,容器下的子元素的宽度是可以缩小的 ,当容器中所有子元素的宽度之和超过了容器的宽度, 默认不会换行显示 ,那么就需要 缩小容器子元素的宽度以保证容器能够容纳下所有的子元素 。但容器子元素的宽度并不是无限缩小的,即 缩小到不能缩小为止

.item-1 {width: 200px;}
.item-2 {width: 8800px;}
.item-3 {width: 8800px;}

比如上面,item2、item3 宽度设置成了 8800px,容器中所有子元素的宽度和为 17800px,远远超出了容器的宽度 800px,所以 容器中的所有子元素必须按比例压缩,item1 元素的宽度应变为200 – 191.01 = 8.99px,而item1 最小被压缩为存放一个字所需要的宽度,即刚好等于字体的大小,即 20px,所以 item1 的宽度将变为 20px。

默认情况下,容器中的子元素可以被压缩到最小为止,但是 当压缩到最小后仍然放不下所有的子元素 ,那么 子元素就会被放到容器的外面

如果给容器添加一个垂直方向的对齐方式,那么容器中所有子元素的高度将变为实际的高度, 不会与容器等高

#main{
    width:800px;
    height:300px;
    display:flex;
    font-size: 20px;
    background: red;
    align-items: flex-start;/* 添加垂直方向对齐方式 */
}

三、容器属性设置

容器默认存在两根轴:水平的主轴 垂直的交叉轴 。主要就是设置 容器的主轴方向 超过容器后是否换行显示 水平对齐方式 垂直对齐方式
① flex-direction : 用于 设置主轴的方向 ,默认值为row,即 容器中所有子元素水平排列

column: 表示 容器中所有子元素垂直排列

row-reverse: 表示 反转容器中所有子元素的顺序 ,并且起点靠右,即 靠右对齐

column-reverse: 表示 反转容器中所有子元素的顺序 ,并且起点靠下,即 靠容器底部对齐

② flex-wrap: 用于 设置容器中子元素放不下的时候是否换行 。默认值为nowrap,即 不换行,即使放不下也不换行

wrap : 表示 可以换行 ,当设置为 wrap 可以换行的时候, 容器中的元素就不会被压缩,而是采用换行显示。

#main {
    width:800px;
    height:300px;
    display:flex;
    background: red;
    flex-wrap: wrap; /* 放不下的时候可以换行 */
    font-size: 20px;
}
.item-1 {width: 300px;}
.item-2 {width: 300px;}
.item-3 {width: 300px;}

wrap-reverse : 表示 换行显示之后对行排列顺序进行反转

wrap:

wrap-reverse:

flex-flow: 是 flex-direction 属性和 flex-wrap 属性的简写形式,默认值为row nowrap,即主轴为水平方向,不换行。

justify-content: 用于设置 主轴方向 的对齐方式。

align-items: 用于设置项目在 交叉轴 (非主轴) 上对齐方式。

四、容器中元素 (项目) 属性设置

① order: 用于 设置容器元素的排列顺序 默认值为 0 数值越小,排列越靠前

.item-2 {order: -1; /* 将 item- 2 的 order 设置为 -1,可以让 item- 2 排在前面 */}

② flex-grow: 用于 设置容器元素的放大比例 默认值为 0 ,即 如果存在剩余空间,也不放大

③ flex-shrink: 用于 设置容器元素的缩小比例 默认值为 1 ,即 如果空间不足,该项目将缩小

④ flex-basis: 用于 设置容器元素占的大小 默认值为 auto,即 与容器元素的实际大小一致 进行缩放的时候会根据该值来进行计算是否有多余的缩放空间

⑤ flex: 是 flex-grow、flex-shrink、flex-basis 的简写,默认值为 0 1 auto,即 不可放大 可缩小 大小与容器元素大小一致,后两个属性可选。

.item-2 {flex: 0 1 auto;/* 注意三个值之间是空格二不是逗号 */}

⑥ align-self: 用于 单独设置某个容器元素的对齐方式 默认值为 auto,表示 继承父元素的对齐方式

.item-2 {align-self: center;/* 单独设置 item- 2 居中对齐 */}

五、felx:1 和 flex: auto 的区别

从上面可知,flex 的默认值为 0 1 auto。flex 的值比较灵活,可以设置很多种值,如:
none: 此时等于 0 0 auto

.item {flex: none; // 值为 none}
// 等价于
.item {
    flex-grow: 0;
    flex-shrink: 0;
    flex-basis: auto;
}

② auto: 此时等于 1 1 auto

.item {flex: auto; // 值为 auto}
// 等价于
.item {
    flex-grow: 1;
    flex-shrink: 1;
    flex-basis: auto;
}

一个非负数字 : 此时 这个非负数字指的是 flex-grow 的值,flex-shrink 采用默认值 1,但是flex-basis 值为 0%,如:

.item {flex: 1; // 值为一个非负数字}
// 等价于
.item {
    flex-grow: 1;
    flex-shrink: 1;
    flex-basis: 0%; /* 这里比较特殊为 0%*/
}

取值为两个非负数字: 此时分别代表的是 flex-grow 和 flex-shrink 的值,flex-basis 取值为 0%

.item {flex: 6 8; // 值为两个非负数字}
// 等价于
.item {
    flex-grow: 6;
    flex-shrink: 8;
    flex-basis: 0%; /* 这里比较特殊为 0%*/
}

一个长度或百分比 : 此时 这个值为 flex-basis 的值flex-grow 取值为 1flex-shrink 取值为 1

.item {flex: 200px; // 值为一个像素值}
// 等价于
.item {
    flex-grow: 1;
    flex-shrink: 1;
    flex-basis: 200px;
}
.item {flex: 100%; // 值为一个百分数}
// 等价于
.item {
    flex-grow: 1;
    flex-shrink: 1;
    flex-basis: 100%;
}

需要注意的是,如果 flex-basis 设置为百分比,那么 其相对的是容器的大小的百分比 而不是自身的大小的百分比

从上可以看到,当 flex 的值为 none 或者 auto 或者 不设置 的时候,flex-basis 的值才是 auto;其他情况如 flex 的值为数字 的时候,flex-basis 的值则为 0%

所以 flex: 1 和 flex: auto 的区别就是,flex-basis 的值不同flex:1 的时候 flex-basis 值为 0%flex: auto 的时候,flex-basis 的值为 auto

六、容器元素放大或缩小值计算

① 放大的情况
主要就是根据 flex-basis 的值计算出容器是否有剩余空间,如果 有剩余空间 ,并且 该容器中某个子元素是可以放大的 ,那么用该子元素的flex-grow 值比上容器中所有子元素的 flex-grow 值之和计算出该容器子元素的放大系数,然后 乘以剩余空间的大小 即是该容器子元素需要放大的像素值。

#main{
    width:800px;
    height:300px;
    display:flex;
    background: red;
    font-size: 20px;
}
.item-1 {
    width: 200px;
    flex: 2 1 auto;
}
.item-2 {
    width: 200px;
    flex: 3 1 10%;/* 这里 flex-basis 值相当于是 80px*/
}
.item-3 {
    width: 100px;
    flex: 0 1 220px;
}

itme- 1 的 flex-basis 为 auto,所以值和元素本身大小一致,即 200px;
item- 2 的 flex-basis 为 10%,其相对的是容器自身的大小,即800px * 10% = 80px;
item- 3 的 flex-basis 为 设置的 220px,这里需要注意的是,虽然 width 设置的为 100px,但是 width 不会其作用,仍然会以 flex-basis 为基准
首先根据 flex-basis 计算出剩余空间 = 800px – (200px + 80px + 220px) = 300px;
由于剩余空间为 300px > 0,所以 容器中的子元素可以放大 ,由于 item- 3 的 flex-grow 值为 0,所以 item- 3 不会放大, 仍然以 220px 显示
item- 1 的放大值 = 2 / (2 + 3) * 300px = 120px;
item- 2 的放大值 = 3 / (2 + 3) * 300px = 180px;
所以,最终 item- 1 的大小 = 200px + 120px = 320px;
item- 2 的大小 = 80px + 180px = 260px;
item- 3 的大小 = 220px;



② 缩小的情况
缩小的情况也是先根据 flex-basis 的值计算出容器超出容器多少空间,但是其不是简单的根据 flex-shrink 的值计算出缩放比例,而是 根据容器中某个元素的 flex-basis 值乘以 flex-shrink 的值占容器中所有子元素的 flex-basis 乘以 flex-shrink 的值之和来计算缩放比例的

#main{
    width:800px;
    height:300px;
    display:flex;
    background: red;
    font-size: 20px;
}
.item-1 {
    width: 200px;
    flex: 0 2 auto;
}
.item-2 {
    width: 200px;
    flex: 0 3 100%;/* 这里 flex-basis 值相当于是 800px*/
}
.item-3 {
    width: 100px;
    flex: 0 0 200px;
}

itme- 1 的 flex-basis 为 auto,所以值和元素本身大小一致,即 200px;
item- 2 的 flex-basis 为 100%,其相对的是容器自身的大小,即800px * 100% = 800px;
item- 3 的 flex-basis 为 设置的 200px,这里需要注意的是,虽然 width 设置的为 100px,但是 width 不会其作用,仍然会以 flex-basis 为基准
首先根据 flex-basis 计算出超出空间 = (200px + 800px + 200px) – 800px = 400px;
由于超出空间为 400px > 0,所以 容器中的子元素需要缩小 ,由于 item- 3 的 flex-shrink 值为 0,所以 item- 3 不会缩小, 仍然以 200px 显示
item- 1 的缩小值 = (2 200px / (2 200px + 3 800px + 0 200px)) * 400px = 57.14px;
item- 2 的放大值 = (3 800px / (2 200px + 3 800px + 0 200px)) * 400px = 342.86px;
所以,最终 item- 1 的大小 = 200px – 57.14px = 142.86px;
item- 2 的大小 = 800px – 342.86px = 457.14px;
item- 3 的大小 = 200px;


正文完
 0