第一次嘗試 Responsive Design 和 Grid System
公司的活動頁,明明趕得要死,我還是忍不住把 Susy 用上了,為什麼?
因為前陣子在規劃新版面,我認為像樣的 grid system 能幫助我們,減少設計師、上稿人員和我,煩惱或溝通一些不必要的問題,例如某元素 margin 多少、某版位我做了多寬、……,不如先定個標準出來,要改再說,不改就我處理。
RWD 也是早就想做的事情,目前網站拆為桌面版和手機版(m.網址),結果因為 m 的功能不完整,造成 tablet 使用者處在不上不下的局面,想想 RWD 還是最輕鬆的解法。
找了不少解決方案,感覺都很難搞,最後只有 Susy 給我嘗試的勇氣。
Susy 可愛之處
- 不用自己算寬度。 比如 960px 分成 16 欄,每欄是多寬? 我不可能算對啊!
- 不用在 HTML 加入像
.row4 .span3 的噁心 class,那根本無法維護嘛。
Susy 實際做的事情
剛開始什麼 gutter、columns 的名詞都看不懂,但實際做一次,認識一下產生的 CSS,會發現 Susy 做的事其實不多。
※目前版本是 1.0.8,但以下會混用 2.0 alpha 未定的介面說明,我覺得更清楚。
-
建立 grid(set-grid(960px 12 1/4))
主要是維護 grid 設定的工作,也就是定義「容器寬、欄數、欄間隔、留邊」等等變數;
一般會寫下幾組設定,用在不同的 media query 條件下。
具體例子,v1.0.8 的語法
$container-width: 970px;
@include container;
產生的 CSS 會包含 max-width: 970px; 以及 :after :before 的 clearfix。
-
安排元素的佔有欄數與定位(span(last 3 of 5 isolate))
Susy 做掉兩個麻煩的算數問題,第一是元素本身的 width;
只要指定橫跨(span)寬度是 N 欄,Susy 就會根據當時的 grid 設定,把元素 width 設為應有的百分比。
第二是為了將元素放在正確的水平位置上,所需要設定的左右 margin
(理由:Susy 採用 float 加上負 margin 實作 grid,避免 % 除不盡時,瀏覽器處理最後一個 pixel 的問題,參考 Responsive Design’s Dirty Little Secret)。
v1.0.8 使用 @include span-columns(3 omega, 5); 指定元素佔 5 欄中的 3 欄;
omega 表示是該列的最後一個元素,預設會產生反方向的 float,倒過來算,否則那幾 % 有時還是會被擠到第二列。
另有 isolate(3) 用來將元素定位在第 3 欄;
針對列表也能以 isolate-grid(4) 讓各 item 寬 4 欄、自動對齊,且 nth-child(4n+1) 會自動 clear,產生 CSS 如:
#AllWorks ul.gallery li {
width: 23.07692%;
float: left;
margin-right: 2.5641%;
margin-right: -100%;
}
#AllWorks ul.gallery li:nth-child(4n + 1) {
margin-left: 0%;
clear: left;
}
#AllWorks ul.gallery li:nth-child(4n + 2) {
margin-left: 25.64103%;
} ... (後略)
-
Media query
提供方便設定 media query 的 Mixin。
v1.0.8 用法
$media-tablet: 640px 8 969px;
@include at-breakpoint($media-tablet) { // ... (block 後略)
會產生
@media (min-width: 640px) and (max-width: 969px) { ...
的 CSS,且其中寬度會以 8 欄為標準計算。
遇到的問題
-
容器已經有 max-width,但某個 header 想要背景佔滿畫面寬
要讓 content 置中,header、footer 又要橫向佔滿整個畫面,自然的作法就是將 header、content、footer 放在同一層,各自設定寬度(分別為 100%、container width、100%)。
如果想讓 header 的「內容」也遵守 grid 設定,讓它跟 content 對齊,就要在寬 100% 的 header 下,再加一層 wrapper 且設為 grid container 才行。
結論:這個問題跟 Susy 沒有關係。終究無法只用一個 container 就達成需求。
註:有個用 pseudo element 的做法,參考 css - How to handle full-width element outside of a 960 compass susy grid? - Stack Overflow。
-
預設的垂直對齊,只能靠頂(top)對齊
因為 CSS vertical-align 只對 layout 為 inline 或 table-cell 的元素有用,而 float 會把 layout 變成 block,正好 Susy 是使用 float 排版,結果就是「垂直對齊」變得不易做到。
可能的解法是改用 display: inline-block;,就能使用 vertical-align 了,也是我們平常實作 gallery 的方式。
(Susy 有一個相關 feature request inline-block version · Issue #69,不過被拒絕掉了)
這次我也沒用 vertical-align,設計師可能也比較中意 vertical rhythm……
但總之想換 inline-block 的話,要注意的應該只有:
-
Haml tag 要用
> 和 <
把多餘的空白去掉,因為空白會佔寬度:
%li><
%div.image
-
不使用 Susy
isolate,改為自己指定 width 和 margin:
li {
width: columns(4, 16);
margin-right: gutter(16);
&:nth-child(4n) {
margin-right: 0;
}
}