最近看到幾篇博文講解margin:auto在flex容器中的使用,惋惜的是大多講解都浮於頁面表現,沒深究其中的做用機理,本文在此淺薄對其表現機理作簡單探討.css
平常業務迭代過程當中,flex已是前端工程師解決常見佈局的神兵利器.可是隨着使用的深刻,偶然會發覺flex對於簡單的佈局足夠直接迅速,可是對於稍稍複雜一些的佈局,就須要層層的包裹分組來解決.舉個栗子,下圖是咱們常見的佈局圖:html
若是flex容器之中僅僅只有三個元素,彼此分離,咱們藉助於justify-content就足夠應付.可是若是其中兩個元素須要當成一組來處理,好比圖一中的BC,使用flex佈局,就不能保證佈局結構足夠簡單,就須要把AB用一個div之類的標籤包括起來當成一個元素,而且BC須要在新的包裹容器中居中,才能夠實現上圖佈局.代碼以下:前端
<div class="flex-container"> <div class="A">A</div> <div class="BC"> <div class="B">B</div> <div class="C">C</div> </div> <div class="D">D</div> </div>
.flex-container { display: flex; justify-content: space-between; } .A { background: #FFE6CC; width: 100px; } .BC { flex: 1; display: flex; justify-content: center; align-items: center; } .B { background: #FFF2CC; width: 100px; } .C { background: #F8CECC; width: 100px; } .D { background: #E1D5E7; width: 100px; }
那麼有沒有比上面更簡單的佈局方式麼?有,那就是使用margin:auto.編程
若是使用margin:auto的話,那麼怎麼更加簡單實現上圖的佈局.
下面是佈局代碼.微信
<div class="flex-container">
<div class="A">A</div>
<div class="B">B</div>
<div class="C">C</div>
<div class="D">D</div>
</div>
.flex-container { display: flex; justify-content: space-between; } .A { background: #FFE6CC; width: 100px; } .B { background: #FFF2CC; width: 100px; margin-left: auto; } .C { background: #F8CECC; width: 100px; margin-right: auto; } .D { background: #E1D5E7; width: 100px; }
相對與引子中的代碼來講,圖中標紅的是改動的地方.
主要是下面三個改動:前端工程師
去掉外層flex中的justify-content屬性.[margin:auto優先級比justify-content高,會使此屬性失效,因此刪除]dom
簡化html結構.原來須要三層結構,簡化後只須要兩層.佈局
B的margin-left和C的margin-right設置爲auto.flex
最好的原理說明在css的規範中.咱們首先查閱規範中對於flex容器margin:auto的說明[資源來源可參閱文末的參考資料].flexbox
規範中明確說明了兩個重要的點,:
margin:auto優先級比 justify-content,align-self優先級高
若是正常分配空間以後,仍然有未分配的空間,剩下的空間將分配給margin:auto的元素.
可是此規範沒有說明,若是有多個margin:auto的元素,空間將如何分配?對此,mdn文檔有說明[資源來源可參閱文末的參考資料]:
mdn明確告知,空間將會平均分配給margin:auto的元素.
總結來看,就是能夠使用margin:auto在flex容器主軸方向給子元素的左右兩側分配空間.
到此有看官可能有疑問了,若是flex容器,一個子元素margin-left,margin-right都設置爲auto,另一個子元素僅僅只設置了margin-left,那麼空間該如何分配.實測證實,在主軸方向上,有幾個外邊距(指margin-left,margin-right)設置爲auto,那麼就分幾份.
.flex-container { display: flex; } .A { background: #FFE6CC; width: 100px; } .B { background: #FFF2CC; width: 100px; margin-left: auto; margin-right: auto; } .C { background: #F8CECC; width: 100px; margin-left: auto; } .D { background: #E1D5E7; width: 100px; }
上述代碼顯示效果以下:
B由於左右兩個外邊距都是auto,因此會各佔一份,C由於只有左邊距是auto,所以只佔用一份.
上面的舉例主軸都是水平方向.那麼主軸是豎直方向的是否也適用呢?這裏能夠確定回答: 列容器margin:auto仍然有效.不過須要把margin-left,margin-right改爲設置 margin-top,margin-bottom爲auto.
.flex-container { display: flex; flex-direction: column; height: 500px; } .A { background: #FFE6CC; width: 100px; } .B { background: #FFF2CC; width: 100px; margin-top: auto; } .C { background: #F8CECC; width: 100px; margin-bottom: auto; } .D { background: #E1D5E7; width: 100px; }
上述代碼顯示效果以下:
從示例中能夠看出,margin:auto有空間佔有效應. 使用margin:auto在某些狀況下能夠替代 flex:1, justify-content: space-between等的使用.這裏再也不展開闡釋.
margin:auto適合用來給flex容器的子元素間(在主軸方向)增長空間,適當的使用margin:auto能夠簡化dom的佈局結構以及樣式代碼,提升編程效率.
[1] w3c css-flexbox規範: https://www.w3.org/TR/css-flexbox-1/#auto-margins
[2] mdn關於margin:auto對flex容器的影響說明: https://developer.mozilla.org/zh-CN/docs/Web/CSS/margin-left
微信搜索 ''十八將君'',關注個人公衆號和我一塊兒成長~