2015.09.17
易犯的 RWD 網站製作失誤

自從 Google 在 2015 年宣布將調整手機 Google 中行動版網站的搜尋結果排名,各大網頁公司的業務人員就開始以此當噱頭、勸業主改版,腳步比較遲緩的企業也陸續將自家的網站做行動版的優化。

讓資料可以優美的顯示在手機網頁瀏覽器的解決方案有很多,響應式網頁設計(RWD)是其中之一,RWD 的特點是用一些JS與CSS的技術,讓同一個頁面可以顯示在行動裝置跟電腦,不會有兩個網址,後端程式只要寫一次,其他都是美工與前端的事情。本文介紹一些網頁設計人員在製作 RWD 網站時常犯的失誤。

1.把自己的裝置解析度當成大家的裝置解析度
想看網頁實際上在小螢幕上看起來如何,於是就用自己的手機來預覽與修改,把網頁上的輸入框、容器或文字段落,在自己的手機上調整顯示得剛剛好,覺得很完美,但是用其他手機看卻跑版、跳行、內容突出螢幕外、字句斷得可怕,為什麼呢?

事實上手機螢幕的解析度一直在變,iOS 陣營的螢幕解析度是越來越大,Android 陣營的則是廠商客製自由度高,造成解析度破碎化,從 4.5 吋的手機到 7 吋的通話平板、11吋的雙系統平板,還有 4:3、16:10、16:9 等各種螢幕比例。

假設你在解析度 480*853 (Samsung) 的手機上製作頁面,把大部分的東西都設定最小寬度或是固定寬度 400px 以上,那在解析度 320*568 的 iPhone 5s 上看起來可是很慘烈的。

所以記住原則,多用百分比寬度,寬度不要設定太多固定數值。畫設計稿時也不要把網頁元件排得太寬,如下圖範例。
有時候可用圖示、placeholder、blur 自動驗證之類的功能,來取代按鈕,或是太多的提示文字有時候可用圖示、placeholder、blur 自動驗證之類的功能,來取代按鈕,或是太多的提示文字

要看網頁在行動裝置上長怎樣,可以利用一些模擬器,最容易安裝與使用的應該算是 Chrome Developer Tools 裡面的 Device Mode 。也可嘗試一些線上工具,如 ScreenflyMobile phone emulator (by COWEMO),要看 iOS 可以用 iOS simulator,不過模擬器畢竟是模擬器,字體顯示、不支援的元件、翻轉螢幕、輸入文字、觸控行為、跟實際用手機瀏覽的感覺還是很有差異。

2.orientation:landscape 不是螢幕方向打橫
製作 RWD 網站最常用的技巧之一就是 CSS 媒體查詢指令,讓符合條件的媒體裝置時執行對應的 CSS,常用的如寬度大於多少(min-width)、高度小於多少(max-height)...等等。

會遇到一個屬性叫 orientation:portrait 與 orientation:landscape,有些中文的網路教學會簡易的說它是「螢幕方向」是垂直或水平,但如果查閱 W3C 或 MDN 中的屬性定義,它並不是真的表示螢幕方向,而是「螢幕的高比寬還大」或「螢幕的高比寬還小」。

嗯? 那不就是螢幕打直跟水平嗎? 身為資訊人,永遠要考慮例外情況、故障情況會發生什麼事,例如某些情況,會造成手機是直的,卻是螢幕的高比寬還小,你想到了嗎?

點擊輸入框,彈出鍵盤時,會造成手機是直的,卻觸發 orientation:landscape 點擊輸入框,彈出鍵盤時,會造成手機是直的,卻觸發 orientation:landscape

3.使用者會修改瀏覽器設定
有時候會在文字段落區塊或容器區塊設定固定高度,讓區塊可以整齊顯示,不會忽高忽低。但會發生使用者反應「兩行字疊在一起啦」「字顯示到一半就被吃掉啦」,自己試了又沒有,到底為什麼呢? 有些把顧客當白癡的公司,或是深諳業務技巧的人員會說這是「手機壞了」「個案」,但真的是這樣嗎?

如果有平面出版相關經驗的人,可能都會聽過書本一頁幾行字,雜誌一頁幾行字的說法。但是在資訊時代,卻比較少聽過這種潛規則,頂多只有文字或按鈕不要小於多少尺寸,哪有人在講電子書、網頁、手機一行要有幾個字? 因為資訊產品的螢幕尺寸太多,而且通常都可以自訂顯示文字大小、自訂顯示背景色與文字顏色,或設定系統配色為高對比。

問題就出在「自訂顯示文字大小」這回事上面。

華碩瀏覽器華碩瀏覽器
Chrome for Android Chrome for Android

例如一些瀏覽器都有「字型縮放」跟「最小字型大小」的設定,前者是將整個網頁不論大小的文字強制放大,後者是將小於多少點數的字強制放大,若使用者設定這些選項之後,就會造成所謂的「兩行字疊在一起啦」「字顯示到一半被吃掉啦」之類的現象。

那如何排除因為調整瀏覽器設定,而造成字疊在一起的情況呢?

  • 行距不要設固定px
  • 區塊不要設固定高度
  • 不要用太多 overflow:hidden

那要如何避免文字因為瀏覽器的設定而被強制放大呢? 無解。

以前可能聽過用 pt 單位設定 font-size,或是設定 text-size-adjust:100% 的秘方,但後來除了 iOS,其他的也已漸漸不支援了。或是還有用 transform : scale 來把放大的字再縮回去的祕法,但是你得先知道使用者把字放到多大。

還有一招最不是方法的方法,就是把字通通做成圖片,就沒有什麼因為調整「最小字型大小」而導致跑版的情況。

但畢竟能隨意放大才是體貼使用者的行為,美觀只是一回事,能讓使用者看清楚網頁上要傳達的文字訊息才是真的。但是工程師替使用者著想,誰來替工程師著想? 下次又遇到此問題時,除了請使用者把「最小字型大小」調回預設值,或是一些奇巧的業務嘴說法,還有別招嗎?

4.電腦網頁用的輔助輸入元件
現代的網頁常常都有一些輔助輸入的網頁元件,例如小日曆、自動完成功能、離開輸入框焦點時自動驗證;彈出訊息...之類的功能。如果未對這些輔助輸入元件在行動裝置版面做處理,將會導致表單難以輸入,差一點的頂多是畫面顯示多餘的功能,或是伺服器請求的浪費,但要是發生阻擋主要畫面,或是警示訊息顯示在畫面外,造成無法繼續操作,這些都是災難性的。

自動完成功能的在手機瀏覽環境下較難點選自動完成功能的在手機瀏覽環境下較難點選

一些日曆元件在手機瀏覽環境下較難點擊,可以換成 html5 input type一些日曆元件在手機瀏覽環境下較難點擊,可以換成 html5 input type

例如 JQuery UI 的小日曆在手機上較難點擊,我們可以用 modernizr.js 或是簡易的 js UserAgent 查詢指令,在行動裝置上不執行小日曆,然後將 input type 改成 date,讓使用者用系統內建的日曆元件來完成日期的輸入(如上圖右)。

if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
$("#date").datepicker("destroy");
$("#date").prop("type", "date");
//(請注意日期格式要調整成跟 JQ UI 的 datepicker 日期格式一樣)
}

使用系統 UI 元件的缺點,就是每個系統的顯示方式都不一樣,造成使用者體驗不一致(如下圖範例),甚至有些合約驗收標準是畫面要顯示得跟合約一樣,這都容易造成麻煩。
由上至下: Safari/ android browser/ chrome on android由上至下: Safari/ android browser/ chrome on android

說到輸入,html5 增加了一些 input type ,使用正確的 type,可以讓輸入電話、email 之類的欄位跳出對應的鍵盤,而不是跳出完整的字母鍵盤。如使用 type="tel",會跳出數字鍵盤,使用 type="email",會跳出帶有.com 跟 @ 的字母鍵盤。

另外有一些手機輸入法太過聰明,常常會自動校正、自動首字轉大寫、自動加空格,在某些輸入情境下相當痛苦(如輸入帳號或驗證碼時),可以在 input 加入 autocapitalize="off" 與 autocorrect="off",關閉自動大寫與自動校正。

雖然資訊系統的終極目標是指紋掃一下、條碼掃一下,甚至語音輸入,就完成所有步驟。但是在那一天到來之前,還有很大一段路要走。在現階段,只能想辦法盡量減少痛苦的輸入流程。

5.行動裝置也有瀏覽器相容性問題
經驗豐富的網頁設計師,通常都熟知所謂 CSS hack,conditional comment 之類的用法,因為在電腦的瀏覽環境,明明是同一段符合W3C的標準語法,卻可能在 IE6、IE7、IE8、IE8 相容性模式、Vista 與 Win7 的 IE8、IE9、IE9 相容性模式、IE10、IE10 相容性模式、Win7 的IE10,IE11、IE11相容性模式、Modern IE、Win7 的 IE11,Win8 的 IE11,Win8.1 的 IE11,Firefox,Chrome,Safari in Mac OS,Opera,360 瀏覽器......上面產生異常的瀏覽情況。

後來手機與平板的出現讓網頁環境又再次推進,不能再以「IE8不支援」「IE 的使用者怎麼辦」當藉口,因為行動裝置的瀏覽器基本上都支援 CSS3 等新的網頁語法,而且行動裝置的的淘汰週期比電腦更快。近一兩年進入網頁設計職場的新人,反而有些知道如何用 css 畫台灣國旗,卻不知道\0\9*_ 之類的 IE css hack。

但是行動裝置一樣有瀏覽器相容性問題,如 android 4.x 不支援 calc,android 4.3 以下不支援 Viewport units,iOS 則是使用 Viewport units 與 html body overflow:hidden 時會有怪情況,也不支援 background-attachment: fixed 與 window.open()。

行動裝置上除了以上的主流環境,還有一些比較冷門但也挺常見的網頁環境,例如 htc, sony, samsung, 小米手機內建的瀏覽器,或是一些使用者為了讀取 Flash 內容,會用海豚瀏覽器,還有被人遺忘的智慧型手機 Windows Phone。

這些只能靠經驗,或是使用任何先進的語法前,先去查查此語法在哪些瀏覽器不支援、或有問題。

除了瀏覽器相容性,還有瀏覽器預設樣式問題。比如說同樣有一個 select 下拉選單,設定寬 80px,在自己的 Android 手機上看起來好好的,就收工了,不過實際上 iOS Safari 的 select 箭頭按鈕非常大,如果下拉選單字太多,是會被切掉看不到的。所以寬度要再加大一點。或是同一個網頁, iOS 的按鈕圓角看起來比 Android 來得圓,必須再額外設定 border-radius。此兩例也可以設定 -webkit-appearance:none 相關屬性,讓這些表單元件的預設樣式通通消失。

6.使用太多「滑鼠移入」事件
以前的網頁很常見所謂的「滑鼠移入後會彈出子選單、移到某項目又跳出第三層選單」的多層選單功能,但是在行動裝置上的操作方式只有點一下(click)、長按(hold click/taphold)、滑動(swipe)、縮放(zoom)、捲動(scroll),跟電腦完全不一樣。要是sitemap 或是內頁次分類選單規劃得不好,有些頁面在手機上根本一輩子都點不進去。所以應該盡量避免規劃這種「滑鼠移入」才能跑出重要功能/訊息的功能。

事實上在手指點一下的時候,還能觸發 js mouseenter 事件,只是沒有 mouseleave 事件,所以東西會卡在畫面上藏不起來。hover 事件則完全不行。應急的話可把 hover 事件改成 mouseenter 事件。

另外現在很多購物或型錄網站網頁會在產品圖片製作所謂「放大鏡(zoomin)」功能,這種東西在行動裝置上用起來也是很痛苦,不如直接設定 user-scalable=yes,讓整個頁面可以放大。

另外有些網頁 costdown 非常嚴重,超連結只會寫連結顏色跟滑鼠移入(hover)的顏色,少了訪問過(visited)的連結色與連結觸發(active)的顏色,常常讓使用者不知道有沒有點到連結。

7.只會自幹,不善用 Framework
有些開發人員喜歡享受自幹的成就感,自己寫 media query,定一堆 breakpoint,自己寫元件樣式,自己控制每種裝置上的容器寬度,什麼東西都能掌握在自己控制下的感覺是很好,但有時候可以用一些現成 framework。

如 JQuery Mobile, Bootstrap,裡面都有 grid system,或是一些刻好的現成元件,還幫你顧到一些基本的瀏覽器相容性問題,也蠻方便的。compass 或 sass 也可以引入一些別人做好的東西,不用通通自幹(前提是你知道引入的東西是幹嘛用的)。如有機會,可以用看看。

8.只會用 Bootstrap
有些開發人員半路出家,只會用 Bootstrap 之類的 Framework 來做出好像符合合約需求,但實際上維護性與續用性非常差的網頁,不知其原理,出問題也不知道如何排除,要嘛就硬幹埋下地雷。用 Framework 沒關係,但要知道原理,比如為什麼 hidden-xs 會在螢幕寬 < 768 的時候藏起來,768 的數字是哪來的?

這年頭網頁架構越來越龐大,網頁公司其實很少需要碰到從無到有做一個網站的情況,每個公司通常都有幾個充滿技術債的系統,例如「學校班級內容管理系統」「XX 行業網站內容建置系統」「OO 預約系統』「購物車含線上 ERP 電子商務系統」,有些很賺錢,有些是很賺錢的垃圾,有些是垃圾。通常內容都是一些民國初年就已經切好版的頁面內容,framework 也套不上去,如要維護,還是要懂得相關的網頁技術。

9.DRY原則
軟體領域有一個 Don't repeat yourself(不要重複你自己,簡稱DRY)的開發原則,這個在網頁部分也稍許適用。

例如有些開發人員對於 CSS 的繼承、覆蓋觀念較弱,於是會發生控制平板區間螢幕寬度的 CSS,在手機上又寫一段一模一樣的,如有修改,就要一次修改好幾處,造成人力與時間的浪費。

善用繼承與覆蓋,可減少一些重複編寫的內容。如有幸遇到架構完整的系統,還可以將區塊配置(layout)、配色主題(theme)的 css 或功能模組完全分開,達成事半功倍的效果。

10.效能問題
有些網頁為了趕流行,會製作一頁式網頁,或是使用 parallex scrolling 之類的效果,圖片非常多、載入流量非常大的網頁,或是中國流行的 H5 活動頁面,但成品製作出來後,會發現滑起來有頓感,或是頁面載入時間非常久,有時候可以唬爛說「Android 手機不夠頂級」、「Android 就是頓」「大陸手機才這樣,很快壞」「這邊遠傳的訊號不好」「伺服器該升級了」,但是當出錢的人拿的是最新款的 iPhone,出現頓感是不被允許的,這些責怪手機、責怪系統、把客戶當白痴的說法就不攻自破。

RWD 的概念之一就是同一份網頁程式,透過不同的樣式檔與媒體查詢指令,在不同裝置顯示不同樣貌的網頁。那必定在有些情況會有多餘的圖片、多餘的 JS 、多餘的 CSS、多餘的 HTML,多餘的 DOM,這些都要仰賴使用者端的瀏覽器與硬體去計算並顯示,重繪(repaint)、重排(reflow)的次數一多,很容易造成網頁瀏覽卡頓。

例如古代常見的連結圖片取代法 text-indent:-9999px,會在網頁上產生一個寬 9999px 的容器,拖累效能。有些東西雖然是 display:none,但還是有被下載、執行,只是看不到。

11.position:fixed 的捲動抖動與頁面縮放問題
通常在上導覽列、下導覽列,或是一些側邊廣告,或是彈出區塊的背景圖層,會使用 position:fixed 的 CSS 語法,讓頁面不論滾動到何處,區塊都會固定在同一地方。

但是發現頁面快速滑動時,或是用手指壓著螢幕,上下移動頁面時,position:fixed 的區塊會亂跑,但是一鬆手,又會回到原處,可以在元素上加入 -webkit-transform: translateZ(0); 改善此抖動問題。

zoom in Bootstrap navbar-fix-top examplezoom in Bootstrap navbar-fix-top example
另外有一些網頁的內容會存在非常大張的圖片,所以會把網頁的 meta viewport 屬性設定為 user-scalable=yes,但是把網頁用手指一放大,會發生 position:fixed 的元素也跟著被放大,並蓋住網頁內容的情況(如上圖)。現今一般解法是用 JS 去偵測網頁 zoomin 事件,然後把 position:fixed 的元素縮回正常大小。

結語
網頁設計基本上是一個得同時兼顧舊裝置,又得不斷學習新技術的行業,開發人員的失誤可能造成團隊與公司的損失,也可能造成使用者的流失,不可不慎。

除了技術面的問題,還有使用者體驗面,也就是 Mobile Friendly 的問題,一個網頁是否真的好用? 不妨親自操作一遍看看用起來有多痛苦。但是有些人會問,一個網頁好用不是基本的嗎? 為什麼使用者體驗還要另外要求? 給多少錢,做多少事啊!

資料來源:http://jimmysu.logdown.com/