接下來近一分鐘裡,我希望你暫且將CSS、web開發、數字化使用者介面拋之腦後。
接著,我想讓你暢想時光回退,回到年少時,回到上學第一天。
那時的你更簡單,只擔心畫沒畫好圖形,有沒有尿褲子。
現在,看看上圖中的點,注意有些點是怎樣聚在一起的,有些點又是怎樣分開的?我想讓你把這些點分為五組,把你認為適合的分在一起。
開始吧,先檢查下有沒有人作弊,檢查完後,你就可以用你那孩子般的手指沿著每組的周圍畫一個圓。
你可能會畫成下面這樣吧?(無論你做什麼,只要別告訴你啥也沒做螢幕它就自己滾下去了,我不會相信的!)
確實,本來無論怎麼劃分右邊的兩個點都可以。我認為它們劃分在一起也沒錯。有人說沒有錯誤的答案,但我從來沒錯過,所以我也從不認可這個特別陳詞濫調的說法。
在我繼續往下說之前,讓我猜猜你剛才畫的是否像下面這樣呢?
可能也不像,對吧?
但如果你要將你的斷點設定在能匹配流行裝置的確切寬度(320px,768px,1024px)的位置,那如上圖這樣劃分是最基本的。
你曾經是否有在不經意間聽過或說過下面這些話?
中間斷點應該是一直到768畫素呢,還是包括768畫素呢?我明白了,那就是ipad橫屏的大小啊,它就是大(large)嗎?哦,大(large)是768畫素及其以上。我知道了,那小(small)就是320畫素嗎?那在0到319畫素範圍內的又是什麼呢?難道是螞蟻斷點?
我本可以不管上面那個問題繼續告訴你正確的做法,但我發現上述方法(”愚蠢的分組”)卻非常廣泛,對此我感到十分好奇。
為什麼會這樣呢?
我認為這個問題的答案,就像很多的問題一樣,歸結為術語不一致。畢竟,如果你都不瞭解關塔那摩灣那些事的話,你可能還認為那裡的水刑聽起來超級棒。(哦,我希望這是我的玩笑話)
因為我認為我們在討論和實現斷點時將”邊界”和”範圍”這兩個術語搞混淆了。
如果你在Sass中設定斷點,你會有一個叫$large
的變數嗎?也就是768畫素。
你是把範圍的下邊界當作是大(large)呢,還是上邊界當作是大(large)呢?如果是下邊界,那麼你一定不需要再有$small
變數了,它應該就是0了,是吧?
而如果這是上邊界那麼你又如何定義一個$large-and-up
斷點呢?那就必須是 min-width
為$medium
的媒體查詢,沒錯吧?
當你說大(large)的時候你是指一個邊界,那麼我們就陷入困惑了,因為媒體查詢總是一個範圍。
這種情況很混亂,弄清楚它實在很浪費時間。所以我給出三條建議:
- 正確設定斷點
- 合理命名範圍
- 宣告
Tip #1: 正確設定斷點
那什麼斷點才是正確的呢?
還記得剛才讓你在上學第一天畫的那些圓圈吧。我現在只是為你把它變成了矩形。
如果你打算給監控巨型顯示器的人顯示跟其他顯示器不一樣的東西,那麼將600畫素, 900畫素, 1200畫素 和 1800畫素設定為斷點就是正確的。另提醒喲,如果你要在網上購買一個巨型顯示器(giant monitor),一定要確保它確實是臺計算機。你應該不想要從快遞那兒收到一隻巨大的蜥蜴(giant lizard)吧。
其實剛讓你回到年少時玩的那些點實際上代表14種最常見的螢幕尺寸:
所以我們現在可以製作如下一張漂亮的小圖片方便讓商人,設計師,開發人員,測試人員之間進行暢通無阻的交流啦。
我突然有點後悔選擇了橘色和綠色搭配,但我不會重新再做這些圖片的。
Tip #2: 合理命名範圍
當然,只要你喜歡,你可以命名斷點為熊爸爸和熊寶寶。但如果我正要坐下和設計人員討論網站在不同裝置上應該如何顯示的時候,我希望這個命名能讓大家很快明白,儘快結束討論。如果為了方便命名為某個大小的平板電腦,那我就完蛋了。真見鬼,你甚至命名為”iPad平板電腦(iPad portrait)”都比那名字好。
“但是外觀在時刻變化!”你也許會反駁說,”手機越變越大,平板越變越小”。
但你網站的CSS能用三年(除非它是Gmail)。三年iPad已經換了兩代,CSS都還能用。大家肯定都知道,蘋果已不再製造新產品,只是在已有的東西(按鈕、孔啊等等)上刪減而已。
所以親們啊,1024 x 768的解析度會保留的。別用沙子埋了腦子(有趣的事實:鴕鳥沒在城市生活是因為沒沙子來躲避捕食者)。
結論:溝通很重要,命名時要合理,使用有用的詞彙。
Tip #3: 宣告
我知道,我知道,又在重複 “宣告”這個詞了。我換種方式說明:你的css應該定義它想要發生的事情,而不是它應該怎樣發生。因為怎樣發生應該隱藏於某種混合(mixin)裡。
早前,圍繞斷點的討論有部分略顯混亂,把適用於範圍的命名亂用於定義一個範圍邊界的變數。如果large
是一個範圍那麼簡單地使用$large: 600px
是沒有意義的。就像是說var coordinates = 4;
。
所以我們可以在一個混合(mixin)裡隱藏這些細節的實現而不是直接在程式碼裡暴露它們,或者我們可以想個更好的方法完全不使用變數。
首先我給出下面片段做為一個簡單的例子。但我真的認為它涵蓋了所有的基礎。看個實際應用,檢視在codeopen上的pen.我使用Sass是因為我不能想象沒有它怎麼建設網站,這樣的邏輯同樣適用於CSS或Less。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
@mixin for-phone-only { @media (max-width: 599px) { @content; } } @mixin for-tablet-portrait-up { @media (min-width: 600px) { @content; } } @mixin for-tablet-landscape-up { @media (min-width: 900px) { @content; } } @mixin for-desktop-up { @media (min-width: 1200px) { @content; } } @mixin for-big-desktop-up { @media (min-width: 1800px) { @content; } } // usage .my-box { padding: 10px; @include for-desktop-up { padding: 20px; } } |
我可能有點偏見,但這些CSS的宣告真的超級棒。
請注意,我強迫開發人員要指定-up
或者 -only
做為字尾。
歧義滋生混亂
上述程式碼一個明顯的詬病可能是沒有處理自定義媒體查詢。各位,這是好訊息啊。如果你想定義一個自定義媒體查詢,就寫一個自定義媒體查詢(在實踐中,如果我需要實現比上面更復雜的效果,那為了減少損失我會義無反顧地選擇使用Susy工具包)
另一個詬病可能是我上面用了8個混合(mixin)。當然使用單個混合(mixin)會更符合正常習慣,然後只需傳遞所需的大小,像這樣:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
@mixin for-size($size) { @if $size == phone-only { @media (max-width: 599px) { @content; } } <a href="http://www.jobbole.com/members/wx2715401697">@else</a> if $size == tablet-portrait-up { @media (min-width: 600px) { @content; } } <a href="http://www.jobbole.com/members/wx2715401697">@else</a> if $size == tablet-landscape-up { @media (min-width: 900px) { @content; } } <a href="http://www.jobbole.com/members/wx2715401697">@else</a> if $size == desktop-up { @media (min-width: 1200px) { @content; } } <a href="http://www.jobbole.com/members/wx2715401697">@else</a> if $size == big-desktop-up { @media (min-width: 1800px) { @content; } } } // usage .my-box { padding: 10px; @include for-size(desktop-up) { padding: 20px; } } |
當然,這能行得通。但如果你傳入不受支援的命名在編譯時並不會報錯。而且僅僅為了傳遞一個Sass變數到混合(mixin)開關中,卻會暴露8個變數。
更不用說@include for-desktop-up {...}
語法比@include for-size(desktop-up) {...}
漂亮多了。
兩段程式碼片段的詬病可能是我輸出了兩次900px,還有899px。當然也許我應該只使用變數然後在需要的時候讓變數減1。
但如果你想那樣做,簡直令人發狂。但我不這麼做,有兩個原因:
- 這些不會經常改變,這些數字也不是在程式碼庫任何其他地方都會使用。實際上它們不是變數也不會造成問題——除非你想在你的頁面中將你的Sass斷點暴露給一個指令碼,而該指令碼注入了帶有這些變數的JS物件。
- 用Sass把數字轉為字串的語法很令人討厭。如果你認為重複一個數字兩次是最差的選擇,那你會為此付出這些代價。
123456789101112131415161718192021222324@mixin for-size($range) {$phone-upper-boundary: 600px;$tablet-portrait-upper-boundary: 900px;$tablet-landscape-upper-boundary: 1200px;$desktop-upper-boundary: 1800px;@if $range == phone-only {@media (max-width: #{$phone-upper-boundary - 1}) { @content; }} <a href="http://www.jobbole.com/members/wx2715401697">@else</a> if $range == tablet-portrait-up {@media (min-width: $phone-upper-boundary) { @content; }} <a href="http://www.jobbole.com/members/wx2715401697">@else</a> if $range == tablet-landscape-up {@media (min-width: $tablet-landscape-upper-boundary) { @content; }} <a href="http://www.jobbole.com/members/wx2715401697">@else</a> if $range == desktop-up {@media (min-width: $tablet-landscape-upper-boundary) { @content; }} <a href="http://www.jobbole.com/members/wx2715401697">@else</a> if $range == big-desktop-up {@media (min-width: $desktop-upper-boundary) { @content; }}}// usage.my-box {padding: 10px;@include for-size(desktop-up) {padding: 20px;}}
理解起來會更容易了呢,還是更難呢?
哦,在前面幾個段落我言辭有些激昂…因為我為有些傻瓜感到可憐,因為他們做些讓人費解的事,比如將斷點儲存在一個Sass列表裡然後迴圈輸出媒體查詢,或做些荒謬的事讓接手的開發人員難以理解和維護。
越複雜越容易出現bug
最後,你也許會想“我難道不應該將斷點設在內容而不是裝置的基礎上嗎?”我很驚訝你能想到這點,答案是肯定的…但前提是對一個佈局單一的網站而言。如果你想要多種佈局,你就要為每種佈局設定一個斷點。哦,還有除非你的網站設計不經常變化,或者你很樂意在網站設計更新時也更新斷點,因為你想讓它們設定在內容的基礎上嘛,對吧?
對於複雜的網站,建議網站少設定一些斷點,你才會更輕鬆。
好了,我已經說完了!但這篇文章沒有我想要的那麼令人毛骨悚然,讓我看看能想到什麼藉口,包括一些。。。。
哦,我知道了!
斷點開發獎勵提示
是的,即使是flickr都設定了768到1400的斷點。
- 如果你需要體驗比你現在坐著的這臺顯示器更大的螢幕尺寸的CSS斷點,可以在Chrome 開發工具裡使用”responsive”模式,鍵入你喜歡的任何尺寸。
- 藍色欄顯示媒體查詢”max-width”,橘色欄顯示媒體查詢”min-width”,綠色欄顯示媒體查詢的MIN和MAX
- 點選媒體查詢把螢幕設定到該尺寸,如果你多次點選綠色的媒體查詢,它會在最大和最小間切換顯示。
- 在媒體查詢欄右鍵單擊某一個媒體查詢可以看到該媒體查詢在CSS規則中的定義。