2022年12月11日 星期日

CSS display grid 和 flex 對於子元素 width 的差別

 CSS 的 display grid 和 flex 對於子元素的 width 行為不太一樣,
主要差別是:

Grid:
先以父元素的寬度計算子元素均分後的寬度,子元素各自再用 width 屬性計算出自己最後的寬度,width 是百分比時,最後寬度是以子元素分到的寬度再乘以百分比得到。

Flex:
先以父元素的寬度計算各子元素的寬度,width 是百分比時,寬度是父元素的寬度乘以百分比來得到,之後再用 Flex 排版的方式決定是否寬度要進行延展、縮小或不變 ( 例如 flex-grow、flex-shrink、flex-basis 等設定)。

以下用實際例子來展示:

HTML:

<div class="grid stripes-background">
  <div>grid item1</div>
  <div>grid item2</div>
</div>

<div class="flex stripes-background">
  <div>flex item1</div>
  <div>flex item2</div>
</div>

CSS:

.stripes-background {
  background-image: linear-gradient(45deg, #000 25%, transparent 25%, transparent 50%, #000 50%, #000 75%, transparent 75%, #fff);
  background-size: 50px 50px;
}

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
}

.flex {
  background-color: yellow;
  display: flex;
}

.grid div, .flex div {
  border: 1px solid black;
  width: 50%;
  background-color: rgba(0, 256, 0, 0.7);
}

JsFiddle 的線上範例

範例中有兩個區塊,分別使用了 display grid 和 flex,並在父元素和子元素上畫上背景來較好的分辨子元素寬度的分配。

可以看到子元素被設定了 width: 50%;,

在 grid 佈局中,子元素先以父元素的寬度用 flex 佈局計算好了應得的寬度,也就是
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
,然後才用應得的寬度乘上 50% 得到最後的寬度。

而 flex 佈局中,子元素先以父元素的寬度乘上 50% 得到應得的寬度,之後才進行 flex 佈局,而此例剛好沒有要對子元素寬度進行增縮。

簡單地來說,

Grid 是先在父元素把分配的空間格線畫好,再把子元素放進各空間中,此時子元素的 100% 寬度就是所處空間的寬度,最後各子元素再根據自己的 width 屬性設定計算寬度。

而 Flex 是子元素先根據自己的 width 屬性計算寬度,100% 寬度就是父元素的寬度,接著再用 Flex 進行排版決定各子元素在空間上的排列位置,最後再看有沒有要用 flex-grow、flex-shrink、flex-basis 等設定增縮子元素的寬度。