◆
CSS Flex 布局详解:flex-grow、flex-shrink、flex-basis
flex-basis
- 指定了
flex元素在主轴方向上的初始大小 - 如果不使用
box-sizing改变盒模型的话,那么这个属性就决定了flex元素的内容盒(content-box)的尺寸。 - 当一个元素同时被设置了
flex-basis(除值为auto外) 和width(或者在flex-direction: column情况下设置了height) ,flex-basis具有更高的优先级. ::: demo [vanilla]
<html>
<head>
<meta charset="UTF-8" />
<title>Title</title>
</head>
<body>
<div
id="test-basis"
style="display: flex;margin: 100px auto;width: 500px;height: 200px;background: black;;color: red"
>
<div
class="inner"
style="width: 200px;height: 100px;flex-basis: 300px;background: pink;"
></div>
<div
class="inner1"
style="height: 100px;flex-basis: 200px;background: lightcyan;"
>
inner1
</div>
</div>
<script>
const inner = document
.getElementById('test-basis')
.getElementsByClassName('inner')[0];
inner.innerText = 'inner:' + inner.offsetWidth;
const inner1 = document
.getElementById('test-basis')
.getElementsByClassName('inner1')[0];
inner1.innerText = 'inner1:' + inner1.offsetWidth;
</script>
</body>
</html>
{
"show": true
}
:::
flex-grow
- 该属性用来设置当父元素的宽度大于所有子元素的宽度的和时(即父元素会有剩余空间),子元素如何分配父元素的剩余空间。
flex-grow的默认值为0,意思是该元素不索取父元素的剩余空间,如果值大于0,表示索取。值越大,索取的越厉害。 ::: demo [vanilla]
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Title</title>
</head>
<body>
<div
id="test-grow"
style="display: flex;justify-content: space-around;flex-wrap: wrap"
>
<div
style="display: flex;width: 280px;height: 100px;background: black;color: red"
>
<div
class="inner1"
style="flex-basis: 100px;height: 100px;background: lightcyan;"
></div>
<div
class="inner2"
style="flex-basis: 50px;height: 100px;background: pink;box-sizing: border-box"
></div>
</div>
<div
style="display: flex;width: 280px;height: 100px;background: black;color: red"
>
<div
class="inner1"
style="flex-basis: 100px;flex-grow: 0;height: 100px;background: lightcyan;"
></div>
<div
class="inner2"
style="flex-basis: 50px;flex-grow: 0;width: 100px;height: 100px;background: pink;"
></div>
</div>
<div
style="display: flex;width: 280px;height: 100px;background: black;color: red"
>
<div
class="inner1"
style="flex-basis: 100px;flex-grow: 0;height: 100px;background: lightcyan;"
></div>
<div
class="inner2"
style="flex-basis: 50px;flex-grow: 1;width: 100px;height: 100px;background: pink;"
></div>
</div>
<div
style="display: flex;width: 280px;height: 100px;background: black;color: red"
>
<div
class="inner1"
style="flex-basis: 100px;flex-grow: 2;height: 100px;background: lightcyan;"
></div>
<div
class="inner2"
style="flex-basis: 50px;flex-grow: 1;width: 100px;height: 100px;background: pink;"
></div>
</div>
</div>
<script>
const inner2 = document
.getElementById('test-grow')
.getElementsByClassName('inner2');
for (let i = 0; i < inner2.length; i++) {
inner2[i].innerText = 'inner2:' + inner2[i].clientWidth;
}
const inner1 = document
.getElementById('test-grow')
.getElementsByClassName('inner1');
for (let i = 0; i < inner1.length; i++) {
inner1[i].innerText = 'inner1:' + inner1[i].offsetWidth;
}
</script>
</body>
</html>
{
"show": true
}
::: 如果 inner1,inner2 都设索取剩余空间,inner1 设置 flex-grow 为 2,inner2 设置 flex-grow 为 1。 则最终 inner1 的大小为 自身宽度 (100+ inner1 获得的剩余空间的宽度(130 * (2/(1+2))=86.666 = 187 最终 inner2 的大小为 自身宽度 (50+ inner2 获得的剩余空间的宽度 (130 * (1/(1+2))=43.333 = 93
flex-shrink
- 该属性用来设置,当父元素的宽度小于所有子元素的宽度的和时(即子元素会超出父元素),子元素如何缩小自己的宽度的。
flex-shrink的默认值为1,当父元素的宽度小于所有子元素的宽度的和时,子元素的宽度会减小。值越大,减小的越厉害。如果值为0,表示不减小。
简单示例 ::: demo [vanilla]
<html>
<head>
<meta charset="UTF-8" />
<title>Title</title>
</head>
<body>
<div
id="test-shrink"
style="display: flex;justify-content: space-around;flex-wrap: wrap"
>
<div
style="display: flex;width: 280px;height: 100px;background: black;color: red;"
>
<div
class="inner"
style="flex-basis: 100px;width: 80px;height: 100px;background: pink;"
></div>
<div
class="inner1"
style="flex-basis: 200px;height: 100px;background: lightcyan;"
></div>
</div>
<div
style="display: flex;width: 280px;height: 100px;background: black;color: red"
>
<div
class="inner"
style="flex-basis: 100px;flex-shrink: 1width: 80px;height: 100px;background: pink;"
></div>
<div
class="inner1"
style="flex-basis: 200px;flex-shrink: 1height: 100px;background: lightcyan;"
></div>
</div>
<div
style="display: flex;width: 280px;height: 100px;background: black;color: red"
>
<div
class="inner"
style="flex-basis: 100px;flex-shrink: 0;width: 80px;height: 100px;background: pink;"
></div>
<div
class="inner1"
style="flex-basis: 200px;flex-shrink: 0;height: 100px;background: lightcyan;"
></div>
</div>
<div
style="display: flex;width: 280px;height: 100px;background: black;color: red"
>
<div
class="inner"
style="flex-basis: 100px;flex-shrink: 1;width: 30px;height: 100px;background: pink;"
></div>
<div
class="inner1"
style="flex-basis: 200px;flex-shrink: 0;height: 100px;background: lightcyan;"
></div>
</div>
</div>
<script>
const inner = document
.getElementById('test-shrink')
.getElementsByClassName('inner');
for (let i = 0; i < inner.length; i++) {
inner[i].innerText = 'inner:' + inner[i].offsetWidth;
}
const inner1 = document
.getElementById('test-shrink')
.getElementsByClassName('inner1');
for (let i = 0; i < inner1.length; i++) {
inner1[i].innerText = 'inner1:' + inner1[i].offsetWidth;
}
</script>
</body>
</html>
{
"show": true
}
:::
复杂示例 ::: demo [vanilla]
<!DOCTYPE html>
<html>
<div
id="test-flex"
style="display: flex;width: 1500px;outline: 1px red solid;"
>
<div
class="flexItem"
style="flex-shrink: 2;flex-basis: 300px;margin: 0 10px;box-sizing: content-box;"
title="300 - (550*600/2770) ≈ 180.866"
>
1
</div>
<div
class="flexItem"
style="flex-shrink: 2;flex-basis: 300px;padding: 0 20px;border: 5px #ccc solid;box-sizing: content-box;"
title="300 - (550*600/2770) ≈ 180.866"
>
2
</div>
<div
class="flexItem"
style="flex-shrink: 2;flex-basis: 300px;padding: 0 20px;border: 5px #ccc solid;box-sizing: border-box;"
title="300 - (550*500/2770) ≈ 200.722 - 20*2 - 10*2 = 150.722"
>
3
</div>
<div
class="flexItem"
style="flex-shrink: 1;flex-basis: 200px;padding: 0 10px;box-sizing: content-box;"
title="200 - (550*200/2770) ≈ 160.288"
>
4
</div>
<div
class="flexItem"
style="flex-shrink: 1;flex-basis: 200px;border: 5px #ccc solid;margin: 0 10px;box-sizing: content-box;"
title="200 - (550*200/2770) ≈ 160.288"
>
5
</div>
<div
class="flexItem"
style="flex-shrink: 1;flex-basis: 200px;border: 5px #ccc solid;margin: 0 10px;box-sizing: border-box;"
title="200 - (550*190/2770) ≈ 162.274 - 5*2 = 152.274"
>
6
</div>
<div
class="flexItem"
style="flex-shrink: 2;flex-basis: 100px;border: 5px #ccc solid;box-sizing: content-box;"
title="100 - (550*200/2770) ≈ 60.288"
>
7
</div>
<div
class="flexItem"
style="flex-shrink: 2;flex-basis: 100px;padding: 0 30px;margin: 0 10px;box-sizing: content-box;"
title="100 - (550*200/2770) ≈ 60.288"
>
8
</div>
<div
class="flexItem"
style="flex-shrink: 2;flex-basis: 100px;padding: 0 30px;margin: 0 10px;box-sizing: border-box;"
title="100 - (550*80/2770) ≈ 84.115 - 30*2 = 24.115"
>
9
</div>
</div>
<script>
const flexItems = document
.getElementById('test-flex')
.getElementsByClassName('flexItem');
for (var i = 0; i < flexItems.length; i++) {
flexItems[i].innerText = flexItems[i].offsetWidth;
}
</script>
</html>
{
"show": true
}
::: 计算规则:
- 父容器宽度:
1500 - 子容器所需宽度:
(300+10*2) + (300+20*2+5*2) + (300) + (200+10*2) + (200+10*2+5*2) + (200+10*2) + (100+5*2) + (100+10*2+30*2) + (100+10*2)= 2050- 其中
box-sizing为border-box(代表IE盒模型)其width就是width + margin,否则width为width + padding + border + margin
- 其中
- 收缩系数:
300*2 + 300*2 + (300-20*2-5*2)*2 + 200*1 + 200*1 + (200-5*2)*1 + 100*2 + 100*2 + (100-30*2)*2 = 2770- 标准盒模型:
flex-basis * flex-shrink IE盒模型:(flex-basis - padding - border) * flex-shrink
- 标准盒模型:
- 所需分配的宽度:
1500 - 2050 = -550 - 每个子容器的宽度:
- 300 - 550*(600/2770) = 180.866
content-box - 300 - 550*(600/2770) =
content:180.866 +padding:20 * 2 +border:5 * 2 = 230.866content-box - 300 - 550*(500/2770) =
content:200.722border-box - 200 - 550*(200/2770) = 160.288 +
padding:10 * 2 = 180.288content-box - 200 - 550*(200/2770) = 160.288 +
border:5 * 2 = 170.288content-box - 200 - 550*(190/2770) = 162.274
border-box - 100 - 550*(200/2770) = 60.288 +
border:5 * 2 = 70.288content-box - 100 - 550*(200/2770) = 60.288 +
padding:30 * 2 = 120.288content-box - 100 - 550*(80/2770) = 84.115
border-box
- 300 - 550*(600/2770) = 180.866
flex 的简写
flex是flex-grow,flex-shrink,flex-basis的简写flex取值为none,则计算值为0 0 autoflex取值为auto,则计算值为1 1 autoflex取值为一个非负数字,则该数字为flex-grow值,flex-shrink取 1,flex-basis取0%flex取值为一个长度或百分比,则视为flex-basis值,flex-grow取 1,flex-shrink取1flex取值为两个非负数字,则视为flex-grow和flex-shrink的值,flex-basis取0%flex取值为一个非负数字和一个长度或百分比,则分别视为flex-grow和flex-basis的值,flex-shrink取1

还没有留言,来发表第一条吧~