# 談 CSS 管理 — 排版時要注意的事

# 前言

就算只是簡單的排版,設定 padding, margin 字型大小等等,也可以牽扯到很多需要注意的細節,CSS 裡頭沒有正確的答案,很多時候甚至需要一點想像力與創造力,這也是前端相當迷人的地方。今天來介紹一些在排版上需要注意的事情以及值得關注的議題。

# 認識基本 box model 與各式排版屬性

篇幅的關係我們並不會一一介紹,不過想要特別提幾個重要的概念:

  1. Box model: 認識 padding margin border 的差別,可以幫助你更好排版
  2. Position: 認識 absolute, relative, fixed, static,以及 z-index 是怎麼運作的,才不會亂設定屬性導致後續維護困難。
  3. display:除了一般的 block, inline-block, float, flex 之外,grid 也是相當值得學習的排版利器,隨著瀏覽器的迭代,grid 的使用也越來越普及了。

# Typography

管理字型,主要有幾個重點,一個搞清楚 px 與 em, rem 的差別,另外一個則是理解 letter-spacing, line-height 等排版的不同。

另外,雖然管理 typography 聽起來不難,但實際上做起來還是要考慮挺多細節的,像是:

  • 怎麼設定字體大小的級別與用途?在網站中有幾個階層的標題?是否需要實作印刷排版?
  • 不只字體大小需要考慮,同時也要考慮顏色、字重(font-weight)、font-style(斜體、粗體等)、行距、字距等
  • 在不同的載具(平板、筆記型電腦、大螢幕、手機、電視等)的顯示
  • 是否需要考量多國語系?排版上是否需要調整(例如 RTL 等)

你可能會覺得這些難道不是設計師的事嗎?但如果知道這些事,你可以更容易與設計師溝通,也更容易察覺到在設計上有哪些問題。

另外要怎麼讓這些事情變得更容易管理與設定?才不會每次改設計或是調整字體大小與顏色時就會到處爆版?

雖然這些事情總是沒有正確的答案或解決方法,不過提供幾個經驗:

###決定最小的字型大小

這樣可以讓你在做排版時仍然可以感覺得出來最小的字體整體仍然是舒服的;你也可以從最大的字開始,但最好先決定最大與最小的字,這樣在這之間的字型大小比較好設計。

# 參考 modular scale

這個 scale 是依據和諧比例來決定各個字級的字型大小,不過是否有幫助就見仁見智了,自己是覺得看起來挺舒服的,當然也可以根據場景需求做調整。可以參考 Modular Scale (opens new window) 這個網站。ratio 的話或許可以參考黃金比例 1.618 或是根據需要做調整。

# 不同的裝置設定不同的級距

例如在手機與筆記型電腦上,可能就會設定不同的字級大小,利用 media query 可以很容易做到這一點:

$font-sizes: (
  desktop: (
    'x-large': 2rem,
    large: 1.67rem,
    medium: 1.35rem,
    normal: 1rem,
    small: .87rem,
    'x-small': .8rem,
  ),
  mobile: (
    'x-large': 1.56rem,
    large: 1.4rem,
    medium: 1.05rem,
    normal: 1rem,
    small: 0.97rem,
    'x-small': 0.85rem,
  ),
  tablet: (
    // your font scale
  )
);

@mixin font-size($key) {
  
  
  @media screen and (max-width: 1200px) and (min-width: 960px) {
    $fonts: map-get($font-sizes, 'desktop');
    font-size: map-get($fonts, $key);
  }
  
  @media screen and breakpoint-for-mobile {
    $fonts: map-get($font-sizes, 'mobile');
    font-size: map-get($fonts, $key);
  }

    @media screen and breakpoint-for-tablet {
    $fonts: map-get($font-sizes, 'tablet');
    font-size: map-get($fonts, $key);
  }
}

.card {
  @include font-size(medium);
  background-color: #fff;
}

你可以透過函數與 mixin 的包裝或其他方式達到類似的事情。

如果想要做的更 responsive 一點,也可以考慮用 calc 達到類似的效果,calc 可以幫你動態計算值,例如 calc(1vh + 0.25em) 是個合法的表達式,讓瀏覽器幫你計算而不用把邏輯搬到 JavaScript 寫(不過有時候在 JS 寫也挺方便就是了)。

# 數字排版可考慮靠右與 tabular-numeric

在實作倒數計時、table 顯示數字時,常常會發生一件事,就是因為數字造成的不等寬讓頁面有跑動的感覺。你當然可以為了數字再選擇一套等寬字體,不過這樣又會再載入其他不必要的字元。

比較好的做法是可以透過 CSS 來達到類似的效果,在 CSS 有個屬性叫做 font-variant-numeric,可以達到類似的效果,詳細可以參考 MDN 的文件 (opens new window)

# 實作 RWD 要注意的事

在實作 RWD 時有幾件事可以考慮:

# 真的有需要 RWD 嗎?

在實作 RWD 之前,先評估是否有必要性是相當重要的事,例如在 facebook 或是 IThome 當中,會根據裝置的型別來決定入口網站,例如如果用手機瀏覽 facebook 時就會被導到 m.facebook.com

為什麼要這樣做呢?對於 facebook 來說,電腦網頁版有比較豐富的功能,例如左側的導覽列、messenger 功能、可以觀看直播等,這些在手機版上都做不到。

不僅如此,兩者的 layout 也有相當大的差別,如果要實作 RWD 不僅會讓 CSS 不好維護,也有可能在手機版載入更多不必要的程式碼(messenger 等等),所以拆成兩個入口或許更好維護也說不定。

當然這樣的話也要額外維護另外一個版本的樣式,要怎麼取捨就看專案怎麼決定了。

# 不只判斷寬,也要判斷高

例如在手機版有個大大的 header,他的預設顯示是 fixed 的。但是對於一些高度並不高的手機(例如 iPhone SE 等),這個高度是相當礙事的,這時就可以將 header 隱藏,當使用者上滑時再顯示。

# 判斷橫向與直向

有時使用者可能會橫著拿手機來瀏覽畫面,不過很容易就忽略掉這部分的處理。在 CSS 當中可以:

@media (orientation: landscape) {}

來做到類似的效果。

# CSS Custom property

在近幾年,CSS 推出了 custom property,讓你能夠自定義一些變數,而且可以用 JS 操作,也具有 CSS 屬性的特色,對於互動性要求越來越高的網頁開發而言是個福音。支援度也算不錯(如果不理 IE 的話)

這個特性有幾個好處:

  • 用這些屬性不需要預處理器
  • 可以用 initial inherit 的方式建立階層
  • 覽器會在需要的時候重新 render(改變變數值時)
  • 可以訪問並且用 JavaScript 操縱它們(等等會講到)

因為是 property,所以他具有以下幾個特性:

  • initial inherit 的值可以使用
  • 呼叫的方式是 var(--variable-name)
  • 能夠放在 inline-style 裡面
  • 可以用 js 取值、設值

當然也可以套用事件註冊器,讓有興趣的數值注入到我們的變數之中。

document.addEventListener("mousedown", e => {
  // some HTMLElement;
  element.style.setProperty("--pageX", e.pageX)
  element.style.setProperty("--pageY", e.pageY)
})

# 小結

今天介紹了一些在排版上需要注意的事情,看起來還蠻雜的,不過經驗談嘛,CSS 裡頭有太多事情值得探討了,真的想要研究的話又是另外一個大坑了。比較詳細的案例介紹,或許會等到進階篇開始時再一一探討(可能是最後 8 ~ 9 天開始吧)