從手機版到桌機版

講完一些基礎的 Media Query 之後,我們來看看全部都放在一起的一些情況。單就我們 前幾天 提到的狀況,在那個 .sidebar 屬於手機版或桌機版,所呈現的欄位問題來看。

.gird {
    grid-template-columns: repeat(auto-fit, [body] minmax(36rem, 1fr) [end]);
}

一般來說從這裡開始沒有什麼太大的問題,唯一的狀況就在於,當你的 .sidebar 因為 @media 的設定而變成 columns 排列時,你的 .context-wrapper 會變大,而在他變大的同時,你的 .card 就可能會從單欄變成雙欄。為了避免這種狀況,所以我們就得在一些特定的尺寸下,去設計你的 grid-template-columns 的數值。

也就是說,當我們的行動裝置分水嶺在 768px 的時候,

@media (min-width: 768px) {
    /* 在這種情況下,原本的側邊欄位會被往上提,變成整體單欄的狀態 */
    .sidebar-wrapper {
        grid-column: 1;
    }
    .context-wrapper {
        grid-column: 2;
    }
}

所以,這時候就會出現,在 942px769px 之間都是單欄 .card,而當裝置尺寸縮小到 768px 以下時,突然變成雙欄配置,那麼,我們不想要這樣單欄、雙欄、單欄的情況下,勢必要讓 769px 以上都會是雙欄配置。而且,在 742px 以上到 768px 又會是雙欄,我們得避開這種單雙不斷切換的情況。

所以,

@media (max-width: 768px) {
    .grid {
        grid-template-columns: repeat(auto-fit, [body] minmax(38.4rem, 1fr) [end]);
    }
}

這個 38.4rem 是基於我們的 :root 是設定 font-size: 10px,然後接著做一點數學,

768 / 2 / 10 = 38.4

這樣一來,只要低於 768px 這個斷點的 .context-wrapper 都會是單欄設定,為何除以 2 就夠了?

因為兩欄配置下需要一個 gap,在沒有扣除 gap 的情況下,一定會跑回 1fr 的設定。

所以,我們這邊可以得到一個結論,

當你需要在特定尺寸,擁有特定格線元件數量,那麼你可以使用這個簡單的公式來計算:

(<特定尺寸> - (<幾張 .card> - 1) * <gap 寬度>) / <幾張 .card>

例如,我要在 1440px.context-wrapper 寬度下,擁有 4 個 .card 的話,那麼就是,

(1440 - (4 - 1) * 10) / 4 / 10 = 35.25rem

所以我就這樣設定,

@media (max-width: 1950px) {
    .grid {
        grid-template-columns: repeat(auto-fit, [body] minmax(35.25rem, 1fr) [end]);
    }
}

至於為何是 1950px,不要忘記,這邊是行動裝置寬度,所以你必須把 .sidebar 跟原本的 gap 加上去。而如果,你一定要在這些尺寸以上,都只能擁有 4 個 .card 的話,那麼就可以用更簡單的方式製作,

@media (max-width: 1950px) {
    .grid {
        grid-template-columns: repeat(4, 1fr);
    }
}

但請注意,這樣你的卡片尺寸所擁有的伸縮比就會很大,當裝置尺寸越大時,你的卡片就會跟著越來越大。


彈性尺寸的困難處

在搭配 auto-fitauto-fill 的時候,比較困難的地方在於,你使用了 1fr 設定為 minmax 基準,他的自動彈性這件事情其實很難抓出一個基準點。也就是說,如同上面的例子,當我的裝置尺寸在 1950px 的時候,我們的 .context-wrapper 確實如同我們所設定的,他有 4 個 .card 的呈現效果。

但是,如果裝置尺寸在 3160px 的時候呢?

你會獲得 8 個 .card

然後這個尺寸中間還會有 5, 6, 7 個 .card 的呈現方式。縱使這些呈現效果可能勉強符合我們的需求,但,倘若你有針對這些 .card 做出額外的操作,例如使用 :nth-of-type 這類的選擇器,那麼,他可能就不會是你想要的結果。

因為,在不同的行動裝置尺寸底下,所謂的 :nth-of-type 並不一定會在你要的位置上,舉例來說,第 5 張 .card1950px 的情況下,是屬於第二行第一欄(1st column, 2th row),而在超過 2050px 後,會變成第一行最末欄(last column, 1st row)。

如果你在 :nth-of-type(5) 設定了一個放大的效果,或許在 1950px 直到 2049px 以前都會相安無事。直到裝置尺寸大於 2050px 的時候,這個擁有放大效果的 .card 就會跑到最後面去。

這些事情是使用彈性尺寸上的麻煩處。

如果不知道 auto-fill, auto-fit 的差異,可以參考我的 舊文


所以說那個手機版

祝大家國慶日快樂。


Blog 同步刊登:[12th 鐵人賽] RWD 的難題 Part 3, Day 26