前言:記不久前面試的時候,面試官問我平時用什么布局方式,我非常耿直的說 div+css,利用position,float等布局,這就是非常傳統的布局方式,通常都要寫比較多的css代碼;前幾天在知乎上看到篇文章 前端未來頁面布局發展方向是 Flexbox 還是 Grid? flex布局的話,我知道,是css3中引入的,即彈性盒子布局,它的瀏覽器兼容性如下圖。對於grid布局,我才聽聞,所以趕緊學習了一下。
查看屬性的兼容性可以在這個網站:can I use
一 ,flexbox:
任何一個容器都可以指定為Flex布局,設置 display:flex;設置這個屬性之后,子元素的float,clear和vertical-align屬性將會失效。
flex容器默認有兩根軸:水平的主軸(main axis)垂直的交叉軸(cross axis)
用表格的方式來一目了然的顯示它的屬性值:
屬性名稱 |
屬性含義 |
屬性可能的值 |
|
定義在容器的屬性 |
flex-direction |
決定主軸的方向 |
row(默認) 水平,起點在左端 row-reverse 水平,起點在右端 column:垂直,起點在上沿 column-reverse:垂直,起點在下沿 |
flex-wrap |
決定一條軸線放不下,如何換行 |
Nowrap(默認) 不換行 Wrap:換行,第一行在上面 Wrap-reverse:換行,第一行在下面 |
|
flex-flow |
是上面兩個屬性的簡寫 |
默認值是 row nowrap |
|
justify-content |
定義項目在主軸上的對齊方式 |
Flex-start(默認值)左對齊 Flex-end 右對齊 Center 居中 Space-between:兩端對齊,項目之間的間隔都相等 Space-around:每個項目之間的間隔相等,所以項目之間的間隔比項目與邊框之間的間隔大一倍 |
|
align-items |
定義項目在交叉軸上如何對齊 |
Flex-start 交叉軸的起點對齊 Flex-end 交叉軸的終點對齊 Center:交叉軸的中點對齊 Baseline:項目的第一行文字的基線對齊 Stretch (默認值)如果項目未設置高度或者設為auto,將占滿整個容器的高度 |
|
align-content |
定義多跟軸線對齊方式,一條軸線該屬性不起作用 |
Flex-start: 與交叉軸的起點對齊 Flex-end 與交叉軸的終點對齊 Center:與交叉軸的中點對齊 Space-between:與交叉軸的兩端對齊,軸線之間的間隔平均分布 Space-around:每根軸線之間的間隔都相等,所以軸線之間的間隔比軸線與邊框之間的間隔大一倍 |
|
定義在項目上的屬性 |
order |
定義項目的排列順序,數值越小,排列越靠前 |
默認0 |
flex-grow |
定義項目的放大比例,如果存在剩余空間,不放大 |
默認0(如果所有項目的flex-grow屬性為1,則等分剩余空間) |
|
flex-shrink |
定義項目的縮小比例 |
默認1 負值對該屬性無效 |
|
flex-basis |
定義在分配多余空間之前,項目占據的主軸空間,瀏覽器根據這個屬性來計算主軸是否有多余空間 |
默認auto,即項目本來大小 |
|
flex |
是上面三個的簡寫 |
默認值 0 1 auto 后兩個值可選 |
|
align-self |
允許單個項目與其他項目不一樣的對齊方式,可覆蓋align-items屬性 |
默認值auto 表示繼承父元素的align-items屬性,如果沒有父元素,則等同於 stretch |
解釋一下 align-content屬性,
當我們把容器的flex-warp
的值設置為warp
或者warp-reverse
時,若項目不能在一根主軸上顯示,容器便會出現多根主軸。
此時便需要一個值來定義多根平行軸線的對齊方式,這個值便是align-content
。
使用實例:
1,使用flex可以用很少的代碼實現水平/垂直居中
1 <div class="container"> 2 <div class="box"></div> 3 </div> 4 5 <style> 6 .container{ 7 display:flex; 8 align-items:center; 9 justify-content:center; 10 } 11 .box{ 12 width:200px; 13 height:200px; 14 background:#ff0; 15 } 16 </style>
2,之前校招的時候經常被問到的聖杯布局
<div class="container"> <header>Header</header> <div class="content"> <main>Main</main> <nav>Nav</nav> <aside>Aside</aside> </div> <footer>Footer</footer> </div> <style> .container{ display:flex; /* 垂直*/ flex-direction: column; width:100%; /*視口被均分為100單位的vh 占據整個窗口*/ min-height:100vh; } header,footer{ /*放大縮小比例為0 占據垂直方向80px*/ flex:0 0 80px; } .content{ display: flex; /*1 1 auto 后兩個值省略*/ flex:1; } nav{ /*默認 0 數值越小 排列越靠前*/ order:-1; flex:0 0 80px; } aside{ flex:0 0 80px; } main{ flex:1; } </style>
還有類似於QQ,微信的兩個人對話的模式用flex也很好處理。
二,grid:
grid布局在2010年由Microsoft提出,目前已經成為W3C候選標准,目前還不能用於生產環境,但可以通過設置瀏覽器來看到效果,在Chrome中地址欄中輸入chrome://flags打開瀏覽器實驗網絡平台功能,將experimental web platform features設置為enable,這樣我們就可以正常使用grid,如果要在項目中使用grid布局,可以安裝 css-grid-polyfill
依然用一個表格直觀的顯示grid的屬性:
屬性名稱 |
屬性含義 |
屬性可能的值 |
|
容器的屬性 |
display |
定義一個網格容器 |
Grid 以塊級元素的形式顯示 Inline-grid 以內聯元素的形式顯示 Subgrid 父級網絡容器的一個子項,行和列的大小都從父級獲取 |
Grid-template-columns
|
網格的行數 |
定義網格的寬高,單位可以是(px,em,rem,vw,vh,百分比),也可以是網格中自由空間的份數(單位fr) 定義網格線的名稱,不是必須值,未設定以數字表示 |
|
Grid-template-rows |
網格的列數 |
||
Grid-template-areas |
定義網格區域,配合grid-area調用聲明好的網格區域名稱來放置對應的網格項目 |
名字 |
|
Grid-column-gap |
定義網格之間的間距(不包括網格項目到容器邊緣的間距) |
|
|
Grid-row-gap |
|||
Justify-items |
水平方向的對齊方式
|
Start 內容與網格區域的左邊對齊 End 右邊對齊 Center 中間對齊 Stretch(默認值)代表填充整個網絡區域的寬/高度 |
|
Align-items |
垂直方向的對齊方式 |
||
Justify-content |
定義網格和網格容器列軸對齊方式,和align-content相反 |
Start 網格在網絡容器左邊對齊 End 右邊對齊 Center 中間對齊 Stretch 改變網絡子項的容量讓其填充整個網格容器寬度 Space-around 在每個網格子項中間放置均等的空間,在始末兩端只有一半大小 Space-between 在始末兩端沒有空間 Space-evenly 始末兩端也放置均等空間 |
|
Align-content |
定義網格和網格容器行軸對齊方式 |
||
Grid-auto-columns |
指定隱式網格 |
|
|
Grid-auto-rows |
|
||
Grid-auto-flow |
控制自動布局算法如何工作 |
Row 自動布局算法在每一行中一次填充,只有必要時才會添加新行 Column 自動布局算法在每一列中依次填充,必要時添加新行 Dense 如果更小的子項出現時嘗試在網格中填補漏洞 |
|
grid |
grid-template-rows,grid-template-columns,grid-template-areas,grid-auto-rows,grid-auto-columns,grid-auto-flow的合並 |
|
|
項目的屬性 |
Grid-column-start |
定義了網格項目垂直方向的開始位置網格線。 |
|
Grid-column-end |
定義了網格項目垂直方向的結束位置網格線。 |
|
|
Grid-row-start |
定義了網格項目水平方向的開始位置網格線。 |
|
|
Grid-row-end |
定義了網格項目水平方向的結束位置網格線。 |
|
|
Grid-column |
grid-column-start與 grid-column-end的簡寫 |
|
|
Grid-row |
grid-row-start + grid-row-end的簡寫形式。 |
|
|
Grid-area |
調用grid-template-areas屬性創建的模板。同時,這個屬性也可以是grid-row-start grid-column-start grid-row-end grid-column-end的縮寫。 |
|
|
Justify-self |
水平方向的對齊方式 |
start代表該網格單元和網格區域的左邊對齊。 end代表該網格單元和網格區域的右邊對齊。 center代表該網格單元和網格區域的中間對齊。 stretch為默認值,代表填充整個網格區域的寬度。
|
|
Align-self |
垂直方向對齊方式 |
這么多屬性看完,簡直N臉懵逼,What?!
還是從實例入手吧
聖杯布局:
<section class="grid"> <div class="title">title</div> <div class="nav">nav</div> <div class="main">main</div> <div class="aside">aside</div> <div class="footer">footer</div> </section> .grid { display: grid; width: 100vw; height: 100vh; grid-template-columns: 80px 1fr 1fr 1fr 80px; grid-template-rows: 80px 1fr 1fr 80px; grid-template-areas: 'title title title title title' 'nav main main main aside' 'nav main main main aside' 'footer footer footer footer footer'; font-size: 30px; text-align: center; } .title { grid-area: title; } .nav { grid-area: nav; } .main { grid-area: main; } .aside { grid-area: aside; } .footer { grid-area: footer; }