搜尋

Flexbox 的彈性伸縮

彈性盒子 Flexbox 除了基本的設定和對齊,也可以藉由作用於「彈性項目」的 flex、flex-grow、flex-shrink、flex-basis 樣式屬性,製造出可以根據不同的父元素寬度,進行「自由伸縮、彈性伸縮」的彈性項目,除此之外,也會透過彈性項目專用的 order 樣式屬性,改變彈性項目位置,這篇教學會介紹這些樣式屬性的用法。

延伸閱讀:認識彈性盒子 FlexboxFlexbox 的對齊方式

快速導覽:

CSS 教學 - Flexbox 的彈性伸縮

flex-grow 彈性項目擴展比例

flex-grow 樣式屬性會設定「彈性項目的擴展比例」,屬性值只支援「沒有單位、非負值的數值」,預設值為 0,可以使用浮點數,沒有繼承特性,使用後彈性項目會根據所設定的數值,自動分配彈性容器扣除未設定擴展比例的彈型項目內容空間的「剩餘空間」,計算公式如下 ( 寬度表示元素容器盒子的外邊界範圍 ):

CSS 教學 - Flexbox 的彈性伸縮 - flex-grow 計算公式

下方範會使用兩組 div,按照下列規則撰寫 CSS,可以看出第二組和第三組的第四個 div,不論 flex-grow 數值為何,都會撐滿容器,而第一組只會保留自己的空間:

  • 假設彈性容器寬度 400px。
  • 內容有三個未設定擴展比例的彈性項目、一個設定 flex-grow:1 的彈性項目。
  • 假設三個未設定彈性項目的「內容與邊界」加起來共有 100px。
  • 彈性容器寬度減去上述的 100px 還有 300px。
  • 有設定 flex-grow:1 的彈性項目分配到 (300x1)/1,也就是「300px + 自己的容器空間」。
  • 有設定 flex-grow:4 的彈性項目分配到 (300x4)/4,也就是「300px + 自己的容器空間」。

線上展示:https://codepen.io/oxxo/pen/RwXwYEK

<!-- HTML 程式碼-->
<div class="f g1"><div>o</div><div>o</div><div>o</div><div>o</div></div>
<div class="f g2"><div>o</div><div>o</div><div>o</div><div>o</div></div>
<div class="f g3"><div>o</div><div>o</div><div>o</div><div>o</div></div>

<!-- CSS 程式碼 -->
<style>
  .f {
    width: 400px;
    height: 50px;
    border: 1px solid #000;
    display: flex;
    font-size: 24px;
    margin: 20px;
  }

  div div {padding: 5px 0px;}
  div div:nth-child(1) {background: #f33;}
  div div:nth-child(2) {background: #fb0;}
  div div:nth-child(3) {background: #4cf;}
  div div:nth-child(4) {background: #0b0;}

  .g2 div:nth-child(4) {flex-grow: 1;}   /* 第二組的第四個 div 設定彈性擴展 */
  .g3 div:nth-child(4) {flex-grow: 4;}   /* 第三組的第四個 div 設定彈性擴展 */
</style>

CSS 教學 - Flexbox 的彈性伸縮 - flex-grow 一個彈性項目擴展比例

如果兩個以上的彈性項目設定了 flex-grow,則同樣會按照計算公式計算彈性項目寬度,下方範例的第三個和第四個 div,會按照下方公式分配寬度 ( 假設剩餘空間為 300px ):

  • 第三個 div ( flex-grow:1 ):300 x 1 / ( 2 + 1 ) = 100
  • 第四個 div ( flex-grow:2 ):300 x 2 / ( 2 + 1 ) = 200

線上展示:https://codepen.io/oxxo/pen/eYqYLbX

<!-- HTML 程式碼-->
<div class="f g1"><div>o</div><div>o</div><div>o</div><div>o</div></div>

<!-- CSS 程式碼 -->
<style>
  .f {
    width: 400px;
    height: 50px;
    border: 1px solid #000;
    display: flex;
    font-size: 24px;
    margin: 20px;
  }

  div div {padding: 5px 0px;}
  div div:nth-child(1) {background: #f33;}
  div div:nth-child(2) {background: #fb0;}
  div div:nth-child(3) {background: #4cf;}
  div div:nth-child(4) {background: #0b0;}

  .g1 div:nth-child(3) {flex-grow: 1;}   /* 第三個 div 設定彈性擴展 */
  .g1 div:nth-child(4) {flex-grow: 2;}   /* 第四個 div 設定彈性擴展 */
</style>

CSS 教學 - Flexbox 的彈性伸縮 - flex-grow 兩個以上彈性項目擴展比例

如果有「設定寬度」或「內容寬度較大」的彈性項目,則同樣會按照計算公式,先減去原本的寬度,再按照比例分配剩下的空間,下方的範例有三組 div,第一組原本的內容寬度都相,第二組的第四個 div 因為字元較多所以內容較寬,第三組的第三個 div 有設定寬度。

線上展示:https://codepen.io/oxxo/pen/Jjgjaxo

<!-- HTML 程式碼-->
<div class="f g1"><div>o</div><div>o</div><div>o</div><div>o</div></div>
<div class="f g2"><div>o</div><div>o</div><div>o</div><div>oxxo</div></div>
<div class="f g3"><div>o</div><div>o</div><div>o</div><div>o</div></div>

<!-- CSS 程式碼 -->
<style>
  .f {
    width: 400px;
    height: 50px;
    border: 1px solid #000;
    display: flex;
    font-size: 24px;
    margin: 20px;
  }

  div div {padding: 5px 0px;}
  div div:nth-child(1) {background: #f33;}
  div div:nth-child(2) {background: #fb0;}
  div div:nth-child(3) {background: #4cf;}
  div div:nth-child(4) {background: #0b0;}

  .g1 div:nth-child(3) {flex-grow: 1;}
  .g1 div:nth-child(4) {flex-grow: 2;}
  .g2 div:nth-child(3) {flex-grow: 1;}
  .g2 div:nth-child(4) {flex-grow: 2;}
  .g3 div:nth-child(3) {
    flex-grow: 1;
    width: 100px;
  }
  .g3 div:nth-child(4) {flex-grow: 2;}
</style>

CSS 教學 - Flexbox 的彈性伸縮 - flex-grow 對於有設定寬度彈性項目的影響

flex-shrink 彈性項目縮小比例

flex-grow 樣式屬性會設定「彈性項目的縮小比例」,屬性值只支援「沒有單位、非負值的數值」,預設值為 1,可以使用浮點數,沒有繼承特性,如果 flex-grow 樣式屬性是分配「剩餘的空間」flex-shrink 樣式屬性就是分配「溢出彈型容器的空間」,計算公式如下 ( 寬度表示元素容器盒子的外邊界範圍 ):

CSS 教學 - Flexbox 的彈性伸縮 - flex-shrink 計算公式

線上展示:https://codepen.io/oxxo/pen/VwowGgj

<!-- HTML 程式碼-->
<div class="f g1"><div></div><div></div><div></div><div></div><div></div></div>
<div class="f g2"><div></div><div></div><div></div><div></div><div></div></div>

<!-- CSS 程式碼 -->
<style>
  .f {
    width: 400px;
    height: 50px;
    border: 1px solid #000;
    display: flex;
    font-size: 24px;
    margin: 20px ;
  }
  div div {
    padding: 5px 0px;
    width: 100px;
  }
  div div:nth-child(1) {background: #f55;}
  div div:nth-child(2) {background: #fb0;}
  div div:nth-child(3) {background: #4cf;}
  div div:nth-child(4) {background: #0b0;}
  div div:nth-child(5) {background: #a6f;}

  .g1 div {flex-shrink: 0;}
  .g2 div {flex-shrink: 1;}
</style>

CSS 教學 - Flexbox 的彈性伸縮 - flex-shrink 所有彈性項目設定 0 或 1

線上展示:https://codepen.io/oxxo/pen/mdNdGvW

<!-- HTML 程式碼-->
<div class="f g1"><div></div><div></div><div></div><div></div><div></div></div>
<div class="f g2"><div></div><div></div><div></div><div></div><div></div></div>

<!-- CSS 程式碼 -->
<style>
  .f {
    width: 400px;
    height: 50px;
    border: 1px solid #000;
    display: flex;
    font-size: 24px;
    margin: 20px ;
  }
  div div {
    padding: 5px 0px;
    width: 100px;
  }
  div div:nth-child(1) {background: #f55;}
  div div:nth-child(2) {background: #fb0;}
  div div:nth-child(3) {background: #4cf;}
  div div:nth-child(4) {background: #0b0;}
  div div:nth-child(5) {background: #a6f;}

  .g1 div {flex-shrink: 0;}
  .g2 div:nth-child(4) {flex-shrink: 6;}
</style>

CSS 教學 - Flexbox 的彈性伸縮 - flex-shrink 彈性項目設定不同數值

線上展示:https://codepen.io/oxxo/pen/BaXaOMm

<!-- HTML 程式碼-->
<div class="f g1"><div>oxxo.studio</div><div>oxxo.studio</div><div>oxxo.studio</div><div>oxxo.studio</div><div>oxxo.studio</div></div>
<div class="f g2"><div>oxxo.studio</div><div>oxxo.studio</div><div>oxxo.studio</div><div>oxxo.studio</div><div>oxxo.studio</div></div>
<div class="f g3"><div>oxxo.studio</div><div>oxxo.studio</div><div>oxxo.studio</div><div>oxxo.studio</div><div>oxxo.studio</div></div>

<!-- CSS 程式碼 -->
<style>
  .f {
    width: 400px;
    height: 50px;
    border: 1px solid #000;
    display: flex;
    font-size: 24px;
    margin: 20px ;
  }
  div div {padding: 5px 0px;}  /* 彈性項目未設定寬度,讓內容自動撐開容器 */
  div div:nth-child(1) {background: #f55;}
  div div:nth-child(2) {background: #fb0;}
  div div:nth-child(3) {background: #4cf;}
  div div:nth-child(4) {background: #0b0;}
  div div:nth-child(5) {background: #a6f;}

  .g1 div {flex-shrink: 0;}
  .g2 div {flex-shrink: 1;}
  .g3 div:nth-child(4) {flex-shrink: 6;}
</style>

CSS 教學 - Flexbox 的彈性伸縮 - flex-shrink 不影響未設定寬度的彈性元素

flex-basis 彈性項目基礎比例

flex-basis 樣式屬性會設定「彈性項目的基礎比例」,屬性值只支援「具有單位且非負值的數值或關鍵字」,沒有繼承特性,下方列出可用的單位與關鍵字:

單位或關鍵字 說明
px 絕對長度單位。
% 相對長度單位,數值為彈性容器寬度的百分比。
auto 自動調整比例 ( 預設值 )。
0 所有彈性元素都設定為 0 時等於 auto。
content 由內容決定寬度。

使用 flex-basis 時會有下列兩種情況,分別會產生不同的效果 ( 下方「寬度」表示預設的水平排列,如果改成垂直排列則是「高度」 ):

  • 彈性容器空間 > 彈性項目總寬度flex-basis 屬性值為彈性項目寬度。
  • 彈性容器空間 < 彈性項目總寬度:根據 flex-basis 屬性值、本身長度、容器寬度換算實際寬度。

下方範例有四個轉換成彈性盒子的 div 群組,所有群組中第一個紅色 div 設定為 flex-basis: 50%;,第二個橘黃色 div 設定為 flex-basis: 100px;,第三第四的藍色綠色 div 設定為 flex-basis: 10px;,最後一個紫色 div 設定為 width: 10px;,執行後可以看到下列結果:

  • 前兩組 div 是「彈性容器空間 > 彈性項目總寬度」flex-basis 的屬性值等於彈性項目的寬度
  • 後兩個 div 是「彈性容器空間 < 彈性項目總寬度」,就會按照圖片說明的公式計算最後的結果
  • flex-basis 對於彈性項目而言,設定數值後的效果與 width 相同

線上展示:https://codepen.io/oxxo/pen/Exqxerq

<!-- HTML 程式碼-->
<h3>彈性容器空間 > 彈性項目總寬度</h3>
  <div class="f g1"><div></div><div></div><div></div><div></div><div></div></div>
  <div class="f g2"><div></div><div></div><div></div><div></div><div></div></div>

<h3>彈性容器空間 < 彈性項目總寬度</h3>
  <div class="f g3"><div></div><div></div><div></div><div></div><div></div></div>
  <div class="f g4"><div></div><div></div><div></div><div></div><div></div></div>

<!-- CSS 程式碼 -->
<style>
  .f {
    width: 400px;
    height: 50px;
    border: 1px solid #000;
    display: flex;
    font-size: 24px;
    margin: 20px ;
  }
  div div {padding: 5px 0px;}
  div div:nth-child(1) {background: #f55;}
  div div:nth-child(2) {background: #fb0;}
  div div:nth-child(3) {background: #4cf;}
  div div:nth-child(4) {background: #0b0;}
  div div:nth-child(5) {background: #a6f;}

  div div:nth-child(1) {flex-basis: 50%;}
  div div:nth-child(2) {flex-basis: 100px;}
  div div:nth-child(3) {width: 10px;}
  div div:nth-child(4) {width: 10px;}
  div div:nth-child(5) {flex-basis: 10px;}

  .g2 {width:300px;}
  .g3 {width:200px;}
  .g4 {width:100px;}
</style>

CSS 教學 - Flexbox 的彈性伸縮 - flex-basis 彈性容器空間大於彈性項目總寬度

CSS 教學 - Flexbox 的彈性伸縮 - flex-basis 彈性容器空間小於彈性項目總寬度

flex 彈性伸縮樣式縮寫

flex flex-growflex-shrinkflex-basis 三個樣式屬性的縮寫樣式,三個樣式之間使用「空白分隔」,這個樣式屬性作用於「彈性項目」,沒有繼承特性,寫法如下:

div {
  flex: flex-grow flex-shrink flex-basis;
        /* 擴展        縮小        基礎  */
}

使用 flex 時除了撰寫三個屬性值,也可以透過四種「關鍵字」對應預設的縮寫屬性值,預設值為 initial,下方列出四種關鍵字對應的屬性值:

關鍵字 對應屬性值 彈性項目總長未超過容器時 彈性項目總長溢出容器時
initial 0 1 auto 維持原寬度 ( 無彈性 ) 縮小填滿容器
auto 1 1 auto 擴展填滿容器 縮小填滿容器
none 0 0 auto 維持原寬度 ( 無彈性 ) 維持原寬度 ( 無彈性 )
非負值數字 非負值數字 0 0 擴展填滿容器 消失

下方範例展示使用 0 作為關鍵字所產生的彈性伸縮效果,由於藍綠紫三個 div 加起來寬度為 100px,所以剩餘的 100px 就由紅黃兩個 div 按照比例分配,因為設定 flex: 0 之後第三個數值為 0,等於 flex-basis: 0,在其他彈性項目不為 0 的狀態下,若還有剩餘空間就會按照比例分配,若沒有剩餘空間,該彈性項目就會消失

線上展示:https://codepen.io/oxxo/pen/LYwYJap

<!-- HTML 程式碼-->
<h3>彈性容器空間 > 彈性項目總寬度</h3>
<div class="f g1"><div></div><div></div><div></div><div></div><div></div></div>
<div class="f g2"><div></div><div></div><div></div><div></div><div></div></div>

<h3>彈性容器空間 < 彈性項目總寬度</h3>
<div class="f g3"><div></div><div></div><div></div><div></div><div></div></div>

<!-- CSS 程式碼 -->
<style>
  .f {
    width: 400px;
    height: 50px;
    border: 1px solid #000;
    display: flex;
    font-size: 24px;
    margin: 20px ;
  }
  div div {padding: 5px 0px;}
  div div:nth-child(1) {background: #f55;}
  div div:nth-child(2) {background: #fb0;}
  div div:nth-child(3) {background: #4cf;}
  div div:nth-child(4) {background: #0b0;}
  div div:nth-child(5) {background: #a6f;}

  .g1 div {width: 100px;}              /* g1 的彈性項目預設寬度 100px,容器還剩餘 100px */
  .g1 div:nth-child(1) {flex: 1;}      /* 等於 flex: 1 0 0; */
  .g1 div:nth-child(2) {flex: 2;}      /* 等於 flex: 2 0 0; */

  .g2 div {width: 100px;}              /* g2 的彈性項目預設寬度 100px,容器還剩餘 100px */
  .g2 div:nth-child(1) {flex: 1 0 0;}  /* 等於 flex: 1; */
  .g2 div:nth-child(2) {flex: 2 0 0;}  /* 等於 flex: 2; */

  .g3 div {width: 200px;}              /* g3 的彈性項目預設寬度 200px,溢出容器 100px */
  .g3 div:nth-child(1) {flex: 1;}      /* 等於 flex: 1 0 0; */
  .g3 div:nth-child(2) {flex: 2;}      /* 等於 flex: 2 0 0; */
</style>

CSS 教學 - Flexbox 的彈性伸縮 - flex 設定單一數值

下方範例展示了一個「非常彈性」的彈性排版,搭配「文字換行」和「內容溢出裁切」的樣式,就能在不同寬度的父元素顯示狀態下,展現不同的彈性項目寬度,實現的效果如下:

元素 樣式 彈性容器有空間時 溢出彈性容器空間時
紅色 div flex: 1 0 0; 按照紅 1 黃 5 增加空間 消失
黃色 div flex: 5 0 0; 按照紅 1 黃 5 增加空間 消失
藍色 div flex: 0 1 80px; 維持 50px 按照藍 1 綠 5 扣掉空間
綠色 div flex: 0 5 80px; 維持 100px 按照藍 1 綠 5 扣掉空間
紫色 div flex: 0 0 50%; 隨時保持 50% 容器寬度 隨時保持 50% 容器寬度

線上展示:https://codepen.io/oxxo/pen/NWQWLJY

<!-- HTML 程式碼-->
<div class="f"><div>oxxo</div><div>oxxo</div><div>oxxo</div><div>oxxo</div><div>oxxo</div></div>

<!-- CSS 程式碼 -->
<style>
  .f {
    width: 300px;
    height: 100px;
    border: 1px solid #000;
    display: flex;
    font-size: 24px;
    margin: 20px ;
    resize: both;     /* 可用滑鼠拖拉縮放 div */
    overflow: auto;   /* 搭配 resize 一起用 */
  }
  div div {
    padding: 5px 0px; 
    width: 60px;
    overflow-wrap:break-word;
    overflow: hidden;
  }
  div div:nth-child(1) {background: #f55;}
  div div:nth-child(2) {background: #fb0;}
  div div:nth-child(3) {background: #4cf;}
  div div:nth-child(4) {background: #0b0;}
  div div:nth-child(5) {background: #a6f;}

  div div:nth-child(1) {flex: 1 0 0;}
  div div:nth-child(2) {flex: 5 0 0;}
  div div:nth-child(3) {flex: 0 1 50px;}
  div div:nth-child(4) {flex: 0 5 100px;}
  div div:nth-child(5) {flex: 0 0 50%;}
</style>

CSS 教學 - Flexbox 的彈性伸縮 - flex 彈性排版示範

order 彈性項目順序位置

order 樣式屬性是作用於彈性項目的樣式屬性,可以「改變彈性項目的位置」,屬性值使用「無單位的整數」,預設值為 0,數字越小越靠近主軸起始點 ( Main Start ),下方的範例會改變原本 1~9 的順序。

線上展示:https://codepen.io/oxxo/pen/xxvxaeb

<!-- HTML 程式碼-->
<div class="f">
  <div class="o3">1</div><div class="o4">2</div><div class="o1">3</div><div class="o5">4</div><div class="o2">5</div><div class="o9">6</div><div class="o8">7</div><div class="o7">8</div><div class="o6">9</div>
</div>


<!-- CSS 程式碼 -->
<style>
  .f {
    width: 300px;
    height: 50px;
    border: 1px solid #000;
    display: flex;
    font-size: 24px;
    margin: 20px ;
  }
  div div {
    padding: 5px 0px; 
    flex-grow: 1;
    text-align: center;
  }
  div div:nth-child(1) {background: #f33;}
  div div:nth-child(2) {background: #fb0;}
  div div:nth-child(3) {background: #4cf;}
  div div:nth-child(4) {background: #0b0;}
  div div:nth-child(5) {background: #f9f;}
  div div:nth-child(6) {background: #f80;}
  div div:nth-child(7) {background: #6f6;}
  div div:nth-child(8) {background: #ccc;}
  div div:nth-child(9) {background: #ff0;}

  .o1 {order: 1;}
  .o2 {order: 2;}
  .o3 {order: 3;}
  .o4 {order: 4;}
  .o5 {order: 5;}
  .o6 {order: 6;}
  .o7 {order: 7;}
  .o8 {order: 8;}
  .o9 {order: 9;}
</style>

CSS 教學 - Flexbox 的彈性伸縮 - order 彈性項目順序位置

使用 order 時需要注意,透過 CSS 選擇器選取到的元素會被歸類為「同一個順序」,因此若選擇了多個元素,這些元素會一起移動,下方範例會透過 CSS 選擇器,將偶數元素的 order 設定為 2,將奇數元素的 order 設定為 3,就能讓偶數放在前面,奇數放在後面。

<!-- HTML 程式碼-->
<div class="f">
  <div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div><div>7</div><div>8</div><div>9</div>
</div>


<!-- CSS 程式碼 -->
<style>
  .f {
    width: 300px;
    height: 50px;
    border: 1px solid #000;
    display: flex;
    font-size: 24px;
    margin: 20px ;
  }
  div div {
    padding: 5px 0px; 
    flex-grow: 1;
    text-align: center;
  }

  div div:nth-child(1) {background: #f33;}
  div div:nth-child(2) {background: #fb0;}
  div div:nth-child(3) {background: #4cf;}
  div div:nth-child(4) {background: #0b0;}
  div div:nth-child(5) {background: #f9f;}
  div div:nth-child(6) {background: #f80;}
  div div:nth-child(7) {background: #6f6;}
  div div:nth-child(8) {background: #ccc;}
  div div:nth-child(9) {background: #ff0;}


  div div:nth-child(2n) {order: 2;}    
  div div:nth-child(2n-1) {order: 3;}
</style>

CSS 教學 - Flexbox 的彈性伸縮 - order 改變多個選取物件順序

小結

這篇教學介紹的 flexflex-growflex-shrinkflex-basis 是可以充分發揮 Flexbox 最大效益的樣式屬性,透過這些樣式屬性,就能產生自動適應不同父元素寬度的彈性項目,是相當方便好用的樣式屬性!

延伸閱讀:認識彈性盒子 FlexboxFlexbox 的對齊方式

意見回饋

如果有任何建議或問題,可傳送「意見表單」給我,謝謝~

CSS 教學

基本介紹

認識 CSS 開始使用 CSS CSS 語法規則 CSS 命名原則

CSS 選擇器

認識 CSS 選擇器 優先順序 ( 權重 ) 樣式繼承與聯集 元素選擇器 ID 和 Class 選擇器 屬性選擇器 文件結構選擇器 虛擬類別選擇器 ( 結構 ) 虛擬類別選擇器 ( 類型 ) 虛擬類別選擇器 ( 輸入 ) 虛擬類別選擇器 ( 行為 ) 虛擬類別選擇器 ( 超連結 ) 虛擬類別選擇器 ( 邏輯 ) 虛擬類別選擇器 ( 其他 ) 虛擬元素選擇器 群組與組合選擇器

數值與單位

關鍵字與文字數值 長度與角度單位 顏色單位 位置名稱與時間單位

變數與函式

變數 數學計算 文字與清單計數 生成內容與引號 色彩模型 漸層色 影像濾鏡

文字樣式

使用通用字型 使用外部字型 @font-face 定義字型 文字尺寸 常用文字樣式 文字換行 文字空白與 Tab 大小 文字行高與縮排 文字水平與垂直對齊 文字書寫方向 特殊文字樣式

元素容器

容器顯示類型 ( display ) 元素 display 對照表 盒子模型 ( Box Model ) 寬度與高度 內邊距 ( padding ) 外邊界 ( margin ) 邊框 ( border ) 邊框圓角 影像邊框 輪廓 ( outline ) 可見性與透明度 內容溢出與裁切

背景與陰影

背景顏色 背景圖 ( 定位、尺寸 ) 背景圖 ( 固定、重複 ) 背景圖 ( 多重背景、混合 ) 背景縮寫 ( background ) 容器陰影 ( box-shadow )

清單與表格

清單樣式 清單計數器 定義計數規則 表格基本樣式 表格邊框樣式 表格內容寬度與對齊

基本排版與定位

元素排版方式 浮動 ( float ) 浮動形狀 定位 ( position )

Flexbox 彈性排版

Flexbox 彈性盒子 Flexbox 對齊方式 Flexbox 彈性伸縮

Grid 網格排版

Grid 網格容器與格線 Grid 網格空間與命名 Grid 網格流向與間距 Grid 排列網格項目