最近在使用react native的過程中,遇到一個問題。父子元素均使用flex布局,子元素按設(shè)置的比例“分享”父元素的空間,顯示效果符合預(yù)期。但如果父元素設(shè)置了 alignItem: center ,子元素就不再顯示(在子元素使用alignSelf: center 亦是如此)。下面用一個簡單的例子直觀地描述問題。
問題描述
布局很簡單,藍(lán)色父容器占滿屏,黃色、紅色兩個子元素上下排列,分享父容器空間。
- 默認(rèn)情況的布局代碼:
<View style={{ flexDirection: 'column', flex: 1, backgroundColor: 'blue' }}>
<View style={{ backgroundColor: 'yellow', flex: 1 }} />
<View style={{ backgroundColor: 'red', flex: 1 }} />
</View>

- 父容器設(shè)置
alignItem: center, 子元素不顯示
<View style={{ alignItems: 'center', flexDirection: 'column', flex: 1, backgroundColor: 'blue' }}>
<View style={{ backgroundColor: 'yellow', flex: 1 }} />
<View style={{ backgroundColor: 'red', flex: 1 }} />
</View>

- 子元素必須要指定寬度,或者元素內(nèi)部有撐起容器的內(nèi)容,才能顯示。
<View style={{ alignItems: 'center', flexDirection: 'column', flex: 1, backgroundColor: 'blue' }}>
<View style={{ width: 100, backgroundColor: 'yellow', flex: 1 }} />
<View style={{ backgroundColor: 'red', flex: 1 }}>
<Text>Hello World!</Text>
</View>
</View>

這個問題困擾了我很久,按我原先的理解,元素設(shè)置了flex: 1,就應(yīng)該占滿剩余空間,但結(jié)果卻和預(yù)想的不一樣。最終在這里找到了答案。
問題探究
讓我豁然開朗的就是w3schools中的一句話:
The
align-itemsproperty vertically aligns the flexible container's items when the items do not use all available space on the cross-axis.
根本原因是從句的內(nèi)容,當(dāng)子元素不需要使用交叉軸的所有空間時,才應(yīng)該設(shè)置這個屬性。
該屬性默認(rèn)的是stretch ,填充交叉軸的全部長度。如果設(shè)置其他屬性,例如center,就需要顯式地指定元素在交叉軸方向上的大小,或者有內(nèi)容,否則元素就不會顯示。
此處還糾正了我一個錯誤的認(rèn)識。設(shè)置flex屬性時,并不是彈性填滿元素剩余的可用空間,僅僅是在主軸方向分配剩余空間,至于顯示大小,還要靠交叉軸的配合。舉個例子:
<View style={{ alignItems: 'center', flexDirection: 'column', flex: 1, backgroundColor: 'blue' }}>
<View style={{ width: 100, backgroundColor: 'yellow', flex: 1 }} />
<View style={{ backgroundColor: 'red', flex: 1 }} />
</View>
給上方元素指定寬度,下方元素沒有寬度和內(nèi)容。顯示效果如下圖:

可以看到,雖然下方元素沒有顯示,但在主軸方向上還是占據(jù)了一半空間(設(shè)置了flex:1 屬性)。所以主軸的剩余空間還是按比例分配了,只是交叉軸長度為0,導(dǎo)致下方元素不顯示。
總結(jié)
雖然是針對React Native的探究,但經(jīng)過我的簡單測試,網(wǎng)頁上的flex布局也遵循這個原理。
這次學(xué)習(xí)的過程,讓我有兩個很深刻的體會。
- 不能只關(guān)注效果,忽略了場景。因為彈性盒模型上手非常容易, alignItem屬性描述又通俗易懂——元素在交叉軸方向上的對齊方式。所以就忽略了使用這個屬性的具體場景。對于技術(shù)的使用,效果很重要,但適用的場景也必須清楚才行。 (仔細(xì)想想自己有點傻,當(dāng)然是不使用交叉軸所有空間時,對齊方式才有意義,都占滿了還指定對齊方式干嘛?)
- 一籌莫展時先去看看官方文檔。學(xué)習(xí)新技術(shù)時,優(yōu)秀的博客或教程有時比官方文檔更易上手,所以我們往往忽略了官方文檔。即使去閱讀了,作為一個經(jīng)驗不足的初學(xué)者,文檔的一些內(nèi)容不是很理解,或者在閱讀過程中忽略了看似沒用但實則重要的說明。當(dāng)有了一定經(jīng)驗,碰到棘手的問題時,再去看官方文檔,可能有新的理解,問題便迎刃而解。
原博文發(fā)布在個人博客,歡迎訪問!!