你所不知道的「補白」

首先,你必須要知道這幾個常用屬性的可用值,

屬性 預設值 可用值
justify-content normal flex-start,flex-end,center,space-between,space-around
align-content normal flex-start,flex-end,center,space-between,space-around
align-items stretch flex-start,flex-end,center,baseline,stretch
align-self auto auto,flex-start,flex-end,center,baseline,stretch

好了,請留意兩個屬性的預設值,align-contentalign-items 預設都是使用 stretch。換句話說,當你什麼事情都沒有做的時候,他會幫你自動 填滿 。這個 填滿 的動作並不會因為 flex-grow 設定為 0 而阻止他做填滿動作,相對的,如果你的子容器或是元件,在有設定高度(height)的情況下(以 row 為例子),這個 stretch 會被忽略,自動變成 flex-start 為預設值。

也就是說,下列的設定方式,對於 align-items 來說 無效

.flexbox {
    display: flex;
    align-items: stretch;
}

.flexbox .item {
    width: 200px;
    /* 因為你設定了高度,所以上面的 stretch 會自動轉換為 flex-start */
    height: 200px;
}

接著,如果你使用了 baseline 來當作對齊標準,那麼,他會對齊的目標會變成內容的文字基準線,大概會像是這個樣子,

然後你就發現留白的位置會變得比較感性。


通常我們在相對尺寸的設計下,使用這些對齊方式,或是使用 margin-*: auto; 這樣的設定方法,都會在畫面上填充出一段留白。但是對於 margin 屬性來說,兩個被計算(computed)出來的結果是不同的,

這個是 margin-left: auto; 的補白,

這個是 justify-content: space-between; 的補白,

正常人應該會覺得是廢話。

這兩個基本的 目的 不同,

  • margin 用於 推齊 元件。
  • justify-content 用於 對齊 元件。

但是!

兩者使用 getBoundingClientRect() 取得的結果會一樣!

bottom: 333
height: 240
left: 667
right: 907
top: 93
width: 240
x: 667
y: 93

唯一的差別在於,

document.defaultView.getComputedStyle(document.querySelector('.item'), '').getPropertyValue('margin-left')

這個數值會隨著裝置的大小而任意變動,因為你叫做 margin-left: auto;。以上的例子,換成 column 也是相同的狀況,我這邊就不再贅述了。


容器

在上一個章節提到的 align-content 這項屬性,他的設定範圍是在 Flex 容器,這邊容我再雞婆講一次設定範圍,

屬性 設定範圍 目標對象
justify-content Flex 容器 區塊元件,Flex 元件
align-content Flex 容器 區塊元件,Flex 元件
align-items Flex 容器 區塊元件,Flex 元件
align-self Flex 元件 相對於父元件(自身)

這邊所提到的容器,就是我每次截圖最外面的 Container 的部分,然後,我在昨天有提到關於巢狀的事情,在這邊就會出現這種範例。

<div class="flex-container">
    <div class="flex-item child-flex-container">
        <div class="flex-item"></div>
        <div class="flex-item"></div>
        <div class="flex-item"></div>
    </div>
    <!-- 後面假設有 100 組一樣的東西 -->
    <!-- 重複貼 100 次這種事情我做不出來 -->
</div>

此時,若我們一點比較風騷的操作,可能會像是這樣,

.flex-container {
    display: flex;
    flex-flow: row wrap;
    justify-content: flex-start;
    align-content: space-between;
}

.flex-item {
    display: block;
    align-self: center;
}

.child-flex-container {
    display: flex;
    align-self: center;
}

好了,現在開始解釋上面的樣式表 怎麼改會壞掉,以及 什麼設定會衝突 這兩件事。

  • align-content 會覆蓋 .child-flex-containeralign-self 設定。
  • align-content 會覆蓋自身的 align-items 設定。
  • align-itemsalign-self 會有 加乘 的效果。

所以,請在設計你的 Flex 容器跟元件的時候,注意這些衝突的地方。如果你想要抵銷這些事情,就必須在多包一層巢狀的 DOM 來避開,這也是為什麼,不建議在較複雜的結構當中,頻繁的使用 Flex 設定的原因。

這邊展示一下什麼叫做 加乘 的效果。


關於 inline-flex 這件事

除非你有很充足的理由,不然不建議使用 display: inline-flex; 來定義你的 Flex 容器。你可以把他想像成 display: inline-block; 這樣的設定。


所以說那個手機版

所以在行動裝置的尺寸裡面,需要設計格線系統當中,我們可以將最小關注的點放在單一元件的尺寸上。畢竟,我們由小的尺寸慢慢往上長大的時候,一定會到某個界線之後,不能再使用 width: 100% 來製作畫面。

所以你最大的分界點就是那個 不能用 width: 100% 的那個情況。

那麼,在 可以用 width: 100% 的情況下,你需要關注單一元件的狀況是,你有固定寬度,但是畫面放不下,但是,如果讓他斷行,元件自己長大又太大,這種狀況就得重新設計這個畫面。

對,設計師需要重新考慮介面。