flexbox布局 - pod4g/tool GitHub Wiki
例如:
.container {
background-color: #eceaec;
width:500px;
height:400px;
display:flex;
}
.item:nth-child(1){
background-color: #6f5499;
width: 300px;
flex-grow: 5; // 不起作用,相当于没有设置
}
.item:nth-child(2){
background-color: #0275d8;
width: 100px;
flex-grow: 1; // 不起作用,相当于没有设置
}
.item:nth-child(3){
background-color: #ce4844;
width: 101px;
flex-grow: 1; // 不起作用,相当于没有设置
}
这个例子的计算规则如下:
容器总宽度:container.width = 500;
item1的宽度:item1.width = 300;
item2的宽度:item2.width = 100;
item3的宽度:item3.width = 101;
则,item的总宽度:item.totalWidth = item1.width + item2.width + item3.width = 501
则 item.totalWidth > container.width
故,flex-grow不再起作用,
则
item1的真实宽度为:300 * 300/501 = 299.401
item2的真实宽度为:100 * 300/501 = 99.800
item3的真实宽度为:101 * 300/501 = 100.788
由上面可知,当item宽度只和大于容器宽度时,各个容器的width属性就相当于比例。
flex-basis
用来设置item在主轴方向的尺寸,
如果flex-direction:row;
,则flex-basis
相当于width
如果flex-direction:column;
,则flex-basis
相当于height
width
和height
能用的单位flex-basis
一样能用。
假设主轴是水平方向,
如果同时指定flex-basis和width且值都不是auto,则听flex-basis的;
如果两者同时指定,且有值是auto,则听另一个非auto的值,哪怕另外一个值为0;
flex-grow的默认值是0
flex-shrink的默认值是1
flex-basis的默认值是auto
flex:1; -> flex: 1 1 0; -> flex-grow:1; flex-shrink:1; flex-basis:0;
flex:auto; -> flex: 1 1 auto;
flex:none; -> flex: 0 0 auto;
由于flex-shrink的默认值为1,所以当items.totalWidth超过container.width时,并不会超出。
当items.totalWidth < container.width 时,item's flex-grow按照其值瓜分剩下的空间;
当items.totalWidth > container.width 是,item's flex-shrink按照其值缩小多出的部分,使父容器正好包含所有的items;
遇到一个容易让人迷惑的例子:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
.container{
width: 600px;
height: 400px;
background-color: aliceblue;
color:#fff;
font-size: 20px;
display: flex;
}
.one{
background-color: red;
flex:1;
}
.two{
background-color: green;
flex-grow: 1;
}
</style>
</head>
<body>
<div class="container">
<div class="one">壹</div>
<div class="two">贰</div>
</div>
</body>
</html>
上面这个例子中,
.one
的flex
值为1,相当于flex: 1 1 0;
,那么有flex-basis: 0
,而
.two
的flex
相当于flex:1 1 auto;
,此时有flex-basis: auto
,
那么问题来了,flex-basis
的值是0和auto,有什么区别呢?
上面的例子中.one
最终计算出来的width: 290px
,.two
最终计算出来的width: 310px
,原来我认为.one
和.two
的flex-grow
值都为1,那么这两者显然应该平分所有剩余空间,计算出来两者都应该为width: 300px
,但是结果确显然不是,问题出在哪儿呢?
先看.one
,由于flex-basis: 0
,则其初始分得的width
就是0,
然后.two
,他的flex-basis
为auto
,那么.two
的初始width
,应该正好容纳下它的内容为止,
由于font-size: 20px
,那么.two
的初始width
就是20px
(正好容下汉字“贰”),
下面进行计算:
container.width = 600;
items.totalWidth = 0 + 20 = 20;
remining space = container.width - items.totalWidth = 600 - 20 = 580;
flex-grow total value = 1 + 1 = 2;
one flex-grow size = 580 / 2 = 290;
one.width = 0 + 1 * 290 = 290;
two.width = 20 + 1 * 290 = 310;
下面我们改一下:
.two{
background-color: green;
flex-grow: 1;
flex-basis: 50px;
}
/*或*/
.two{
/*
由于 flex-basis 没有设置,故其值为默认值,即auto。然后设置了width:50px;
根据规则可知,两者都存在的话,听值不为auto的。此种情况下,听width的。
*/
background-color: green;
flex-grow: 1;
width: 50px;
}
根据公式进行计算:
container.width = 600;
items.totalWidth = 0 + 50 = 50;
remining space = container.width - items.totalWidth = 600 - 50 = 550;
flex-grow total value = 1 + 1 = 2;
one flex-grow size = 550 / 2 = 225;
one.width = 0 + 1 * 225 = 225;
two.width = 50 + 1 * 225 = 275;
如果改变.one
的样式:
.one{
background-color: red;
flex:1;
flex-basis: 112px;
}
根据公式进行计算:
container.width = 600;
items.totalWidth = 112 + 20 = 132;
remining space = container.width - items.totalWidth = 600 - 132 = 468;
flex-grow total value = 1 + 1 = 2;
one flex-grow size = 468 / 2 = 234;
one.width = 112 + 1 * 234 = 346;
two.width = 20 + 1 * 234 = 254;
但是如果改成这样:
.one{
background-color: red;
flex:1;
width: 112px;
}
经过计算,.one
和.two
的width分别为290px
和310px
,跟没有width
属性的结果一致。原因是:flex-basis
和width
都有值,且值都不为auto
,所以听flex-basis
的,而flex-basis
的值为0,所以计算出来的值就跟width
不存在一样。
下面的例子中,图片原始尺寸为400 x 300
,图片所在容器大小为800 x 700
,
设置img标签width: 100%
,根据img标签尺寸计算可知,指定了一个css属性,则
图片不会被拉伸,会根据比例计算另一个属性。但是在这个例子中,图片却被拉伸了。原因在于
父容器的align-items: stretch;
,会在侧轴(即图片的height方向)方向拉伸图片以填满整个容器。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.container{
width: 800px;
height: 700px;
background-color: aliceblue;
display: flex;
/* 如果加上下面的属性则图片在height方向才不会被拉伸 */
/* align-items: flex-start; */
}
.container img{
width: 100%;
}
</style>
</head>
<body>
<div class="container">
<img src="http://www.placebacon.net/400/300">
</div>
</body>
</html>
justify-content: space-around;
并不会平分容器剩余的空间