目錄
一. CSS布局
二. Flex布局
?1. 容器(父視圖)的屬性
?2. item(子視圖)的屬性
三. 幾個小練習(xí)
一. CSS布局
我們只會用到一點點兒CSS布局的屬性,雖然少,但既然要用到衅金,就得把它們總結(jié)在這里大猛,搞明白眨业。
在了解CSS布局的相關(guān)屬性之前,我們先了解一下盒子模型——CSS會把每個組件都看作是一個盒子厢汹,每個盒子從內(nèi)往外有三個部分:
-
content
:盒子的內(nèi)容课舍,如文字塌西、圖片、子視圖等 -
padding
:內(nèi)邊距筝尾,即盒子的內(nèi)容距離盒子內(nèi)邊框的距離 -
border
:盒子的邊框
1捡需、寬和高
組件的寬度和高度決定了它在屏幕上顯示的尺寸,一個組件的寬度和高度就是它外邊框所包圍矩形的寬度和高度筹淫,iOS里也是這樣的站辉。
- 固定寬高(
width
和height
屬性)
我們可以通過width
和height
屬性給一個組件設(shè)置固定的寬度,不過需要注意這兩個屬性只能接收數(shù)值损姜,不能帶單位饰剥,這是因為RN要自己去適配安卓和iOS的單位。
- 自適應(yīng)寬高(多個屬性組合實現(xiàn))
在RN里摧阅,我們想讓一個組件自適應(yīng)寬高汰蓉,要分兩步。首先我們要讓該組件撐滿它的父視圖棒卷,即如果我們想自適應(yīng)寬度顾孽,就得先讓子視圖的寬度撐滿它父視圖的寬度,如果我們想自適應(yīng)高度比规,就得先讓子視圖撐滿它父視圖的高度若厚,如果我們寬度和高度都想自適應(yīng),就得先讓子視圖把它父視圖的寬度和高度都撐滿蜒什。然后才能像我們iOS里使用Masonry那樣测秸,通過給組件添加上邊距、左邊距、下邊距霎冯、右邊距等約束來實現(xiàn)寬度和高度的自適應(yīng)铃拇。
這里再對第一步做個解釋,item的flex: 1
屬性可以讓item在主軸上撐滿它的容器肃晚,容器的alignItems: 'stretch'
屬性 + item在側(cè)軸上不設(shè)置空間可以讓item在側(cè)軸上撐滿它的容器锚贱。好像有點不明白是吧,我們再通過一個例子來說得明了點关串,RN里不是默認主軸為豎向、側(cè)軸為橫向嘛监徘,我們就采取這個默認狀態(tài)來舉例子晋修。在RN里,默認主軸為豎向凰盔、側(cè)軸為橫向的狀態(tài)下墓卦,如果我們想讓某個組件自適應(yīng)高度,就得首先在它自身上設(shè)置flex: 1
屬性户敬,來讓它的高度撐滿它的父視圖落剪;如果我們想讓某個組件自適應(yīng)寬度,就得首先在它父視圖身上設(shè)置alignItems: 'stretch'
屬性(當然默認就是這個值)尿庐,這還不夠忠怖,你還得確保不給這個組件設(shè)置width
屬性或者width
屬性的值設(shè)為auto
;如果我們想讓一個組件自適應(yīng)寬高抄瑟,則兩者都得做凡泣。當然,如果我們設(shè)置了主軸為橫向皮假、側(cè)軸為豎向鞋拟,其實也是一樣的道理,自己捋一下就知道怎么做了惹资。如果還是看不懂的話贺纲,沒有關(guān)系,下面我們會詳細談到這幾個屬性褪测,等你學(xué)了這幾個屬性猴誊,反過頭來看這里就明白了。
2汰扭、外邊距
-
marginTop
:上邊距稠肘,類似于Masonry里的top
,接收一個數(shù)值 -
marginRight
:右邊距萝毛,類似于Masonry里的right
项阴,接收一個數(shù)值 -
marginBottom
:下邊距,類似于Masonry里的bottom
,接收一個數(shù)值 -
marginLeft
:左邊距环揽,類似于Masonry里的left
略荡,接收一個數(shù)值 -
margin
:外邊距,類似于Masonry里的edges
歉胶,接收一個數(shù)值汛兜,同時設(shè)置上右下左邊距
二. Flex布局
Flex是Flexible Box的縮寫,可譯為靈活的通今、有彈性的盒子粥谬。那Flex布局就是Flexible Box布局的縮寫,就譯為彈性盒子布局辫塌,用來對一個盒子進行靈活的布局漏策。
在了解Flex布局之前,我們得先了解一下Flex布局里的兩對兒重要的概念臼氨。
- 容器和item
采用Flex布局的組件掺喻,被稱為Flex容器(flex container),簡稱容器(container)储矩。
這個組件上的子組件感耙,被稱為Flex項目(flex item),簡稱item(項目)持隧。
我們可以把容器和item看做是父視圖和子視圖的關(guān)系即硼,因此下文中的容器、父組件舆蝴、父視圖將是一樣的概念谦絮,item、組件洁仗、子視圖將是一樣的概念层皱,組件和視圖將是一樣的概念。
- 主軸和側(cè)軸
每個容器都有兩根軸赠潦,一個是主軸叫胖,一個是側(cè)軸。
容器里眾多的item自動沿主軸進行排列她奥。
一個item在主軸方向上所占據(jù)的空間稱為main size
瓮增,一個item在側(cè)軸方向上所占據(jù)的空間稱為cross size
。
RN里主軸的默認方向為豎向哩俭,側(cè)軸為橫向绷跑。瀏覽器里主軸的默認方向為橫向,側(cè)軸為豎向凡资,下面我們講Flex布局的屬性時會采用瀏覽器的狀態(tài)砸捏,學(xué)會后對應(yīng)到RN里,換個主軸方向就可以了。
1. 容器(父視圖)的屬性
用在容器上的屬性垦藏,最常用的有5個梆暖,而且這些屬性還都不是從來設(shè)置容器自己的布局,而是用來設(shè)置容器里item的布局掂骏。
flex-direction
justify-content
align-items
flex-wrap
align-content
1.1 flex-direction
屬性
flex-direction
屬性用來設(shè)置主軸的方向轰驳,即容器里item自動排列的方向。在瀏覽器里弟灼,主軸的方向默認為橫向级解,所以flex-direction
屬性的默認值為row
。
它有4種取值田绑。
row
(默認值):橫向row-reverse
:橫向蠕趁,逆向column
:豎向column-reverse
:豎向,逆向
1.2 justify-content
屬性
justify-content
屬性用來設(shè)置item在主軸上的對齊方式辛馆。
它有5種取值。
flex-start
(默認值):左對齊flex-end
:右對齊center
: 居中(justify-content
屬性設(shè)置為這個值豁延,可以勉強類似于Masonry里的centerX
昙篙,畢竟centerX
一般就用來做做居中效果)space-between
:兩端對齊,item等間隔布局诱咏,但是第一個和最后一個item貼邊苔可。(這種對齊方式會把容器主軸上多余出來的space平均分配,作為每兩個item之間的間隔(between)袋狞,也就是說item是等間隔布局的焚辅,但是如果我們不特別設(shè)置,那么第一個和最后一個item都是緊貼容器邊兒的苟鸯。這種方式一般用在有多個item的情況下同蜻。)space-around
:兩端對齊,item兩側(cè)等間隔布局早处,第一個和最后一個不會貼邊湾蔓,但是會比item之間的間隔小一倍。(這種對齊方式會把容器主軸上多余出來的space平均分配砌梆,around到每個item的兩側(cè)默责,所以說第一個和最后一個item不會緊貼容器的邊兒,但是item與容器邊兒的間隔會比item之間的間隔小一倍咸包。這種方式一般用在有多個item的情況下桃序。)
1.3 align-items
align-items
屬性用來設(shè)置item在側(cè)軸上的對齊方式。
它有5種取值烂瘫。
flex-start
:上對齊flex-end
:下對齊center
:居中(align-items
屬性設(shè)置為這個值媒熊,可以勉強類似于Masonry里的centerY
,畢竟centerY
一般就用來做做居中效果)baseline
: item的第一行文字的基線對齊stretch
(默認值):如果item未設(shè)置height
屬性或height
屬性的值設(shè)為auto
,那它的高度會撐滿父視圖的高度泛释。我剛開始疑惑這明明是把一個item拉伸了滤愕,怎么把它歸類為對齊方式呢?后來一想怜校,item拉伸撐滿父視圖了间影,那可不就是一種對齊方式嘛,你說它上對齊也好茄茁、下對齊也好魂贬、居中也好,怎么都行裙顽。(這個屬性很重要付燥,在組件自適應(yīng)寬高的時候會用到,要用心理解它:item父視圖的alignItems
屬性設(shè)置為stretch
值時愈犹,只要item在側(cè)軸上不設(shè)置空間或空間值設(shè)為auto
键科,那item就會在側(cè)軸上撐滿它的父視圖。)
1.4 flex-wrap
屬性
默認情況下漩怎,一個容器只有一條主軸勋颖,所有的item都會沿著這條主軸自動排列下去,但是如果item太多了勋锤,一個屏幕長度的主軸根本串兒不下這么多item饭玲,那后面的item就會溢出屏幕,而界面還不是ScrollView
叁执,不能滾動茄厘,怎么辦呢?
flex-wrap
屬性用來設(shè)置換行谈宛,即當容器主軸上顯示不下那么多的item時次哈,我們可以讓item換行來顯示,并且一旦設(shè)置了換行入挣,那么這個容器就不再是一條主軸了亿乳,而是會有多條平行的主軸。
它有3種取值径筏。
nowrap
(默認):不換行葛假。
wrap
:換行,第一行在上方滋恬,第二行折下去聊训。
wrap-reverse
:換行,第一行在下方恢氯,第二行折上去带斑。
1.5 align-content
屬性
align-content
屬性用來設(shè)置多條主軸的對齊方式鼓寺,如果項目只有一根軸線,該屬性不起作用勋磕,即align-content
屬性要基于flex-wrap
屬性設(shè)置了換行才有使用的意義妈候。
它有6種取值。
flex-start
:與側(cè)軸的起點對齊flex-end
:與側(cè)軸的終點對齊center
:與側(cè)軸的中點對齊space-between
:與側(cè)軸兩端對齊挂滓,軸線等間隔布局space-around
:與側(cè)軸兩端對齊苦银,軸線兩側(cè)等間隔布局stretch
(默認值):軸線撐滿整個側(cè)軸
2. item(子視圖)的屬性
用在item上的屬性,最常用的有2個赶站,這些屬性都是用來設(shè)置item自己的布局幔虏。
align-self
flex
2.1 align-self
屬性
在第1小節(jié)容器的屬性,我們已經(jīng)通過align-items
屬性統(tǒng)一設(shè)置了容器里item在側(cè)軸上的對齊方式贝椿,但如果其中某個item不想遵循這個對齊方式怎么辦呢想括?我們會常見到這種場景,10個里有8個item是一樣的對齊方式烙博,就有1瑟蜈、2個item特立獨行,那我們就得用item自己的align-self
屬性來單獨給它們設(shè)置對齊方式了渣窜。
align-self
屬性用來設(shè)置單個item在側(cè)軸上的對齊方式踪栋,注意是給特立獨行的單個item設(shè)置哦,而且是側(cè)軸图毕,它會覆蓋它容器的align-items
屬性,當然如果不設(shè)置這個屬性眷唉,默認值就為auto
予颤,即item會默認使用容器的align-items
屬性給它設(shè)置的對齊方式。
它有6種取值冬阳,除了auto
蛤虐,其他都與align-items
屬性完全一致。怎么說呢肝陪,item的align-self
屬性似乎是用來造反的驳庭,反抗它容器的align-items
屬性。
注意:這個屬性是負責(zé)item在側(cè)軸上的對齊方式的氯窍,所以它也可以自適應(yīng)寬或高饲常,只不過通常情況下,我們通過它父視圖的
align-items
屬性做了狼讨,畢竟它是用來造反的贝淤,如果真遇見某種情況必須得用它來做自適應(yīng)寬高,那才用它政供。
2.2 flex
屬性
flex
屬性接收一個整數(shù)值播聪,flex
屬性描述起來太麻煩了朽基,可以自行去搜索加深理解,我這里只列舉出它的用途及注意事項离陶。
(1)flex
屬性有三個用途
-
單個item撐滿父視圖主軸剩余空間:只有一個item時稼虎,我們會用
flex: 1
來讓item撐滿父視圖主軸上的剩余空間。(注意是主軸哦招刨,flex
屬性只能保證item撐滿它父視圖主軸上的剩余空間霎俩,側(cè)軸它是不負責(zé)的,要想撐滿側(cè)軸计济,則是用容器的屬性align-items
屬性+item不設(shè)置cross size
或cross size
設(shè)為auto
茸苇。) -
單個item自適應(yīng)寬或高:只有一個item時,我們會用
flex: 1
來讓item首先撐滿它父視圖主軸上的剩余空間沦寂,這同時就使得item具備了可變寬高的能力学密,然后我們就可以結(jié)合使用item的外邊距屬性來讓item自適應(yīng)寬或高了。 -
多個item按比例分配父視圖主軸上的剩余空間:有多個item時传藏,我們通過設(shè)置各個item的
flex
屬性為不同的值腻暮,來讓系統(tǒng)按比例分配各個item該占用多少父視圖主軸上的剩余空間。
(2)使用flex
屬性需注意
-
flex
屬性的默認值為0毯侦,代表item不自適應(yīng)寬或高哭靖,此時item就必須通過width
或height
屬性來指定寬高。 - 在進行布局的時候侈离,F(xiàn)lex布局會優(yōu)先去布局那些通過
width
或height
屬性設(shè)置固定寬高的item试幽,這樣就知道了主軸上的剩余空間,然后才會去按比例布局那些通過flex
屬性設(shè)置自適應(yīng)寬高的item卦碾,通過flex
屬性設(shè)置的寬高會覆蓋通過width
和height
屬性設(shè)置的寬高铺坞。
三. 幾個小練習(xí)
iOS里怎么使用Masonry布局的,RN里就怎么使用Flex布局+CSS布局來做布局就行了洲胖,它們布局的思路是一樣的济榨,一個組件也同樣至少需要四個約束。
當然绿映,它們之間有一個極其細小的差別擒滑,那就是:上面提到的“RN里組件自適應(yīng)寬高分兩步”,而iOS里Masonry才不管你什么撐滿不撐滿呢叉弦。
當然丐一,它們之間有一個極其巨大的差別,那就是:iOS里是沒有主軸和側(cè)軸之分的淹冰,你可以在一個父視圖上橫向钝诚、豎向同時放控件,并同時完成橫向和豎向的布局榄棵。但RN里有主軸和側(cè)軸之分凝颇,我們添加的組件只會沿著主軸排列潘拱,不可能同時出現(xiàn)橫向和豎向排列,并且布局的時候也只能是沿著主軸布局拧略,不可能同時完成兩個方向的布局芦岂。
下面我們就通過幾個小練習(xí),來對比一下Masonry布局和Flex布局+CSS布局的思路垫蛆,加深對RN里怎么布局組件的理解禽最。
- 練習(xí)1:寬高都是固定值。居中顯示一個View
Masonry:
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
UIView *blackView = [UIView new];
blackView.backgroundColor = [UIColor blackColor];
[self.view addSubview:blackView];
[blackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.view);// 約束1:橫向居中
make.centerY.equalTo(self.view);// 約束2:豎向居中
make.width.mas_equalTo(300);// 約束3:寬度
make.height.mas_equalTo(300);// 約束4:高度
}];
}
Flex布局+CSS布局:
const styles = StyleSheet.create({
containerStyle: {
flex: 1,// 這個container類似于我們iOS里的ViewController.view袱饭,它們都添加在window上川无,但我們iOS里的會自動撐滿window,RN里需要手動設(shè)置一下
backgroundColor: 'white',
justifyContent: 'center',// 約束1:子視圖豎向居中
alignItems: 'center',// 約束2:子視圖橫向居中
},
blackViewStyle: {
backgroundColor: 'black',
width: 300,// 約束3:寬度
height: 300,// 約束4:高度
},
});
- 練習(xí)2:寬高都自適應(yīng)虑乖。讓一個view略小于其superView居中顯示(邊距為10)
Masonry:
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
UIView *blackView = [UIView new];
blackView.backgroundColor = [UIColor blackColor];
[self.view addSubview:blackView];
[blackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.view);
make.centerY.equalTo(self.view);
make.width.mas_equalTo(300);
make.height.mas_equalTo(300);
}];
UIView *redView = [UIView new];
redView.backgroundColor = [UIColor redColor];
[blackView addSubview:redView];
[redView mas_makeConstraints:^(MASConstraintMaker *make) {
// make.top.equalTo(blackView).offset(10);// 約束1:上邊距
// make.left.equalTo(blackView).offset(10);// 約束2:左邊距
// make.bottom.equalTo(blackView).offset(-10);// 約束3:下邊距
// make.right.equalTo(blackView).offset(-10);// 約束4:右邊距
// 逆時針:上左下右
make.edges.mas_equalTo(UIEdgeInsetsMake(10, 10, 10, 10));// 約束1懦趋、2、3疹味、4
}];
}
Flex布局+CSS布局:
const styles = StyleSheet.create({
containerStyle: {
flex: 1,
backgroundColor: 'white',
justifyContent: 'center',
alignItems: 'center',
},
blackViewStyle: {
backgroundColor: 'black',
width: 300,
height: 300,
},
redViewStyle: {
backgroundColor: 'red',
flex: 1,// 這行代碼用來使redView撐滿父視圖的高度仅叫,以便redView能自適應(yīng)高度
// 那寬度額?因為父視圖的alignItems屬性默認為'stretch'糙捺,所以只要這里不設(shè)置redView的寬度诫咱,它的寬度就會默認撐滿父視圖,那寬度也能自適應(yīng)了
// marginTop: 10,// 約束1:上邊距
// marginRight: 10,// 約束2:右邊距
// marginBottom: 10,// 約束3:下邊距
// marginLeft: 10,// 約束4:左邊距
// 順時針:上右下左洪灯,這個屬性只接收一個數(shù)值坎缭,同時設(shè)置4個方向
margin: 10,
},
});
注意:這里用到了
flex
屬性的第二個用途签钩。
- 練習(xí)3:寬度自適應(yīng)幻锁,高度固定值。讓兩個view垂直居中且等寬且等間隔排列(間隔為10边臼,自動計算其寬度)
Masonry:
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
UIView *blackView = [UIView new];
blackView.backgroundColor = [UIColor blackColor];
[self.view addSubview:blackView];
[blackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.view);
make.centerY.equalTo(self.view);
make.width.mas_equalTo(300);
make.height.mas_equalTo(300);
}];
UIView *orangeView1 = [UIView new];
orangeView1.backgroundColor = [UIColor orangeColor];
[blackView addSubview:orangeView1];
UIView *orangeView2 = [UIView new];
orangeView2.backgroundColor = [UIColor orangeColor];
[blackView addSubview:orangeView2];
[orangeView1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(blackView);// 約束1:豎向居中
make.left.equalTo(blackView).offset(10);// 約束2:左邊距
make.right.equalTo(orangeView2.mas_left).offset(-10);// 約束3:右邊距,距離后面一個兄弟視圖的左邊框
make.height.mas_equalTo(150);// 約束4:高度
}];
[orangeView2 mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(blackView);// 約束1:豎向居中
make.right.equalTo(blackView).offset(-10);// 約束2:右邊距假消,距離父視圖的右邊框
make.height.mas_equalTo(150);// 約束3:高度
make.width.equalTo(orangeView1);// 約束4:和orangeView1等寬柠并,這是非常重要的一個約束,這樣系統(tǒng)就知道怎么給orangeView1和orangeView2分配空間了
}];
}
Flex布局+CSS布局:
const styles = StyleSheet.create({
containerStyle: {
flex: 1,
backgroundColor: 'white',
justifyContent: 'center',
alignItems: 'center',
},
blackViewStyle: {
backgroundColor: 'black',
width: 300,
height: 300,
flexDirection: 'row',// 先讓這兩個橙色視圖橫向排列
alignItems: 'center',// 約束1:豎向居中
},
orangeView1Style: {
backgroundColor: 'orange',
flex: 1,// 功能1:讓視圖可以通過外邊距自適應(yīng)寬高富拗。功能2:和orangeView2設(shè)置為一樣的數(shù)值臼予,讓系統(tǒng)知道怎么給orangeView1和orangeView2分配空間,達到等寬的效果啃沪。
marginLeft: 10,// 約束2:左邊距
marginRight: 10,// 約束3:右邊距粘拾,距離后面一個兄弟視圖的左邊框
height: 150,// 約束4:高度
},
orangeView2Style: {
backgroundColor: 'orange',
marginRight: 10,// 約束2:右邊距,距離父視圖的右邊框
height: 150,// 約束3:高度
flex: 1,// 功能1:讓視圖可以通過外邊距自適應(yīng)寬高创千。功能2:和orangeView1設(shè)置為一樣的數(shù)值缰雇,讓系統(tǒng)知道怎么給orangeView1和orangeView2分配空間入偷,達到等寬的效果。
},
});
注意:這里用到了
flex
屬性的第三個用途械哟。
- 練習(xí)4:寬度自適應(yīng)疏之,高度固定值。紅色視圖的寬度自適應(yīng)(左右邊距為10)暇咆,高度給個固定值150
Masonry:
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
UIView *blackView = [UIView new];
blackView.backgroundColor = [UIColor blackColor];
[self.view addSubview:blackView];
[blackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.view);
make.centerY.equalTo(self.view);
make.width.mas_equalTo(300);
make.height.mas_equalTo(300);
}];
UIView *redView = [UIView new];
redView.backgroundColor = [UIColor redColor];
[blackView addSubview:redView];
[redView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(blackView);// 約束1:豎向居中
make.left.equalTo(blackView).offset(10);// 約束2:左邊距
make.right.equalTo(blackView).offset(-10);// 約束3:右邊距
make.height.mas_equalTo(150);// 約束4:高度
}];
}
Flex布局+CSS布局:
const styles = StyleSheet.create({
containerStyle: {
flex: 1,
backgroundColor: 'white',
justifyContent: 'center',
alignItems: 'center',
},
blackViewStyle: {
backgroundColor: 'black',
width: 360,
height: 300,
justifyContent: 'center',// 約束1:豎向居中
},
redViewStyle: {
backgroundColor: 'red',
// flex: 1,// 注意這里千萬不能寫這句話哦锋爪,因為這個時候主軸是豎向的脚祟,它是用來做高度自適應(yīng)的础米,然而我們現(xiàn)在不需要做高度自適應(yīng),所以不能寫腊满,一旦寫了就會覆蓋掉height屬性扯旷,達不到固定值的效果
// 同時拯爽,因為父視圖的alignItems屬性默認為'stretch',所以只要這里不設(shè)置redView的寬度薄霜,它的寬度就會默認撐滿父視圖某抓,那寬度也能自適應(yīng)了
marginLeft: 10,// 約束2:左邊距
marginRight: 10,// 約束3:右邊距
height: 150,// 約束4:高度
},
});
總結(jié):
可以看到,我們iOS里用Masonry布局無非也就用到
width
惰瓜、height
否副、top
、left
崎坊、bottom
备禀、right
、centerX
奈揍、centerY
這幾個屬性就完成了大多數(shù)的布局曲尸。與此相對應(yīng),RN里用Flex布局+CSS布局無非也就用到
width
男翰、height
另患、marginTop
、marginLeft
蛾绎、marginBottom
昆箕、marginRight
、justify-content
租冠、align-items
鹏倘、flex
這幾個屬性就完成了大多數(shù)的布局。當然了顽爹,和iOS里一樣纤泵,還有很多其它的布局屬性這里都沒有列出來,我們遇到的時候去一查就ok了镜粤,以上這幾個屬性就可以應(yīng)對絕大多數(shù)的布局了捏题。
參考博客:
阮一峰的《Flex布局:語法篇》
阮一峰的《Flex布局:實例篇》