傾囊相授 ! MUKI 的 RWD 入門與實戰課程分享

我在 2012 年寫過一篇 CSS Media Queries 介紹與基礎應用,後來也陸續開了一些 RWD 相關課程,也有在一些研討會分享過 RWD 技術,因為資源散落各地,所以決定利用部落格將我分享過的 RWD 資訊做個整合,讓大家可以快速上手。

另外我也會將自己的「RWD 入門與實戰」這個付費課程講義公開,讓大家可以在部落格內閱讀。為什麼要把付費內容免費化呢?其實我覺得, RWD 已經存在一段時間了,相信很多人都已經會了,就算不會,網路上也有許多分享文章可參考,「觀念」也沒什麼好藏私的,愈多人會 RWD,我們之後的進階課程才會輕鬆啊(笑)。

其實想要把內容公開化已經想很久了,突然如此積極還有另外一個原因,就是我在網路上看到有人盜用了我的講義內容,然後把他公開在網站上,好像還用這些內容去開課(這種行為真是令人不齒)。更扯的是,他盜用我的內容後還有附上一些課後補充,就是沒附上我的連結,是心虛嗎?哼~總之,我歡迎大家分享我公開的資料,但與其我的東西被盜用,還不如我自己公開分享啊啊~~

如果各位之後在其他地方看到這些內容,請不用懷疑,我以我的人格保證,他們絕對非原創絕對是盜用,因為這些東西都是我一個字一個字打出來的。也歡迎大家用力檢舉或是告訴我唷 ^___^

以上癈話到此結束,接下來開始進入正題吧。

RWD 相關簡報分享

我的 RWD 簡報都發在 slides.com 裡,大家可以直接點進去看,或是在部落格里閱讀。

RWD 入門與實戰課程簡報

這份簡報是「RWD 入門與實戰」的上課簡報,裡面有很基礎的 RWD 觀念,適合還沒碰過 RWD 卻有興趣想瞭解的朋友。跟練習有關的簡報我都已經拿掉了,我這堂課的兩大重點:(1)RWD 是由什麼組成的 (2)如何實作 RWD。

這份講義重點在「(1)RWD 是由什麼組成的」,另外上了幾次課之後,我改為使用 gitbook 做線上講義,所以這份簡報就沒再更新了。

2015 廣州前端分享會

這份是最早釋出的 RWD 簡報,是我去廣州的一場分享。這份簡報內容很多,到最後也沒講完,裡面列出了做 RWD 會碰到的一些問題,適合已經有 RWD 實作經驗的朋友閱讀。

簡報後面的「那些年我硬幹的事情」,是在分享已經上線的網站如何硬幹成 RWD 網站。

2015 高雄 MOPCON

2015 年底參加了高雄的 MOPCON,一樣是在講 RWD。

這份簡報可以看作是融合的「RWD 入門與實戰」以及「廣州前端分享」的精華,也是適合給有 RWD 實作經驗的朋友閱讀。


簡報比較偏「秀」,為了演好這場秀,裡面會帶上很多插圖,思緒也比較跳躍,所以後來我上課才改用講義,講義就比較像我的寫文風格,系統化 + 平鋪直敘 (自己說 XDDD)。

我會把講義整個搬到文章內,為了怕頁面拖太長,所以請點擊下一篇閱讀「RWD 入門與實戰」講義唷。

Avoid

以下內容是我在 RWD 入門與實戰課程的講義內容,免費放出來讓大家閱讀學習,歡迎分享與轉載 ( 請註明出處來源 )。
請勿盜用或用於商業用途,一但發現必定追究到天涯海角。

RWD 的基本組成:viewport

認識 viewport

viewport 用來告訴瀏覽器現在的裝置有多寬、多高。可以讓使用者在使用不同裝置看網站時,能有個基準比例。

  • 根據裝置的顯示區域來展示文檔 (html)
  • 可以透過放大與縮小 html,以符合裝置的可視區域
  • 通常會有初始值設定縮放的級別或其他規則

viewport 語法

HTML
  • width:使用 device-width (裝置寬度) 作為可視區域的寬度。
  • initial-scale:文檔初始的比例,用 1 表示 100% ,範圍從 0.1 ~ 10 可任填。
  • minimum-scale:最小可以縮放到 0.8 比例。
  • maximum-scale:最大可以縮放到 2.0 比例。
  • user-scalable:是否允許使用者進行縮放。no 不允許;yes 允許。

補充

iOS 10 版本提到:為了增強用戶的體驗,不管有沒有使用 user-scalable ,用戶都可以在 Safari 瀏覽器上縮放網頁。

承上,如果依然不希望使用者縮放,可以改用 JavaScript 禁用設定:

JS

總結

  • 將 viewport 應用在 RWD 網站上,可以很方便的建置一個適合手機、平板等不同裝置閱讀的環境。
  • viewport 也可以應用在非 RWD 的網站
HTML

RWD 的基本組成:流動式佈局

流動式佈局介紹

流動式佈局(Fluid Web Layout)是讓網站在排版時,把寬度從px改成%去排版,讓網站的版面可以參考父層,並用相對比例去分配寬度。

以下利用一個簡單的範例,教大家怎麼把網站版面改寫成流動式佈局。

這是一個用px排版的二欄式的版面

如果要將它改成流動式佈局版面,注意兩個要點:

  1. 把所有px單位改為%,並計算好與父層的相對比例。
  2. 最外層使用max-width設定寬度

改寫後的 CSS 如下(僅列出重點語法):

CSS

流動式網格佈局

如果 HTML 的層級愈多,在計算%時會非常不方便,所以我們可以改用流動式「網格」佈局替代。

網格系統並不是什麼新技術,從以前開始,就有許多設計師用網格在排平面或網頁稿件的版面。而現在有許多人把網格系統化,讓網頁設計師在排版時可以更快的上手,不用自己計算%

以下是一個 Grid System 的範例,範例中把網站總寬度切割成 12 等分,每一個區塊佔用的等份都是固定的。拖拉視窗可以發現寬度即使縮小,網格的數量也沒有減少。

☞ 補充

Bootstrap 也有網格系統(Grid System),所以我們可以使用 Bootstrap 幫我們快速建置基本的 RWD 網站。


RWD 的基本組成:客製化的 Layout 結構

一般來說,使用前面提到的網格式佈局,就可以做出一個 RWD 網站。但如果我們要在版面縮小時,修改元件樣式控制元件出現/消失… 等,這些是「網格式佈局」做不到的,因為網格式佈局只管寬度其他都不歸他管 XD。

因此,我們可以用 CSS 的 Media Query 語法幫我們實現這些功能或需求。

Media Query(ies) 介紹

Media query 的作用是,當偵測到不同尺寸的裝置時,給予對應的 CSS 設定。

在 RWD 的實作上,就是利用 media query 做出「共用一份 html,但是排版不同」的客製化 Layout。

可以讓裝置在任何寬度下,都可以有不同的 CSS 效果,例:

  • 縮小螢幕寬度時,選單跑到左側
  • 縮小螢幕寬度時,某些元素消失

補充

在做 RWD 網站時,Grid System(網格系統)跟 Media Query 通常是密不可分的,所以我們會同時用到這兩個技術。

Media Query 語法解析

以下是 Media Query 的規格:

CSS

寫成我們熟悉的 CSS 語法是:

CSS
  • mediatype : 裝置類型
    • all
    • screen
    • printer // 訪客列印網站資料
    • tv // 訪客用電視瀏覽網站
  • media feature : 裝置的規格
    • max-width / min-width / width
    • max-height / min-height /height
    • color
    • aspect-ratio
    • monochrome

參考資料: http://www.w3schools.com/cssref/css3_pr_mediaquery.asp

如何呼叫 Media Query

呼叫 media query 就跟呼叫 CSS 一樣,大致上有以下三種寫法:

1. 在 HTML 嵌入 CSS 檔案,這份 CSS 檔案會依據 media query 的設定顯示。

HTML

2. 在 CSS 檔案裡寫下 media query 的設定以及相關 CSS 語法

CSS

3. 在 CSS 裡使用 @import 嵌入另外一個 CSS 檔案

CSS

☞ 補充

雖然有這三種呼叫方式,但我們通常都只會使用第二種方法唷~。

Media Query 練習

這是一個已經用流動式佈局排好的頁面:

依照以往上課經驗,初學者在練習 Media Query 時,往往不知道該如何下手。我建議大家一開始先不要管「寬度」,只要先想著,如果我要做好這個功能,應該用哪些 CSS 語法?確定結果是你想要的後,再把這些耶你修改的語法單獨拉出來並加上寬度的條件。

☞ 練習一

網站寬度在 400px ~ 700px 之間,將 #sidebar#aside 的位置互換。

我們可以從頁面語法瞭解#sidebar以及#aside都已經用float排好版面了,如果要讓兩個區塊位置互換,其實只要在float上動點手腳即可:

CSS

☞ 練習二

網站寬度在 0px ~ 500px 之間,選單會從左右變成上下排列。

這個練習根據你的思維與慣用的語法不同,至少可以有四種寫法。在此根據思維的不同,分享兩個寫法給大家:

寫法一

假設我們已先設定好選單在桌機版的樣式:

CSS

那麼 media query 可以這樣寫:

CSS

☞ 補充

因為瀏覽器的寬度沒有負數,所以當寬度是 0 的時候,可以把 min-width 整段省略

寫法二

因為我們還沒有寫選單的樣式,而#menu沒有排版時,預設就是上下排列的狀態,因此可以把這個練習題目想成:寬度在 500px 以上,選單會變成左右排列

那麼我們只需要這樣寫就可以囉:

CSS

「RWD 入門與實戰」的講義暫時分享到此,因為後面的課程是直接用 Bootstrap 的 Grid System 做一個版面,比較難用文字描述,請見諒。

另外課程最後還有一些進階的 RWD 實作,例如設計 Grid 的思維、完全實現文字的縮放,純 CSS 實現表格的 RWD… 等等,這些在「廣州前端分享會」的簡報都可以看到唷。之後有時間會再整理成文章讓大家更瞭解其中的奧妙 😀

最後感謝各位的觀看,希望這篇文章可以幫助到各位唷。有任何問題,也歡迎在文章底下留言詢問~

☞ 延伸閱讀

如果對 Media Query 還不是很懂的話,建議可以看我在 2012 年寫的 CSS Media Queries 介紹與基礎應用

原生 CSS 的預處理器:Myth 介紹與使用

昨天閱讀 CSS Secret 時,作者提到了 Myth 這套預處理器,所以研究了一下如何搭配 gulp 作到自動化編譯(compile),以及如何結合 compass 作到 double 自動化 XDD。

Myth 介紹

免不俗的,先來介紹 Myth 吧!他跟 SASS, LESS 有點像又不太像,相同的地方在於他們都是 CSS 的預處理器,不同的是,SASS & LESS 有自己的規則跟語法(例如 mixin, extend)是原生 CSS 不支援的,而 Myth 的所有語法都是原生 CSS 的 spec,就算不用 Myth 編譯也可以在瀏覽器正常瀏覽。

但是,因為瀏覽器還沒有全面支援各種原生 CSS 的 spec,例如之前介紹過的 CSS 變數,所以我們可以利用 Myth 編譯 CSS,假使以後這些 spec 都開放支援了,直接把 Myth 摘除也不會有影響,非常方便!

有哪些原生的 CSS 需要編譯呢?其實功能不多,只有四個 XDD,我直接擷取 Myth 網站的圖片如下:

Variable 與 Math

再次強調,想瞭解 CSS Variable 可參考我之前寫的文章:CSS 原生變數介紹,不過 Myth 沒辦法支援 CSS Variable 所有功能,像是強大的「繼承」功能就無法支援。

我們都知道,所謂「編譯」就是將 CSS 語法寫死,不管是 SASS, LESS, 或是 Myth,即使在寫的時候靈活度很高,但是編譯出來的語法就是固定的。而 CSS variable 是原生的 CSS 語法,跳過編譯這個階段,可以讓語法更加靈活,尤其是前面提到的繼承功能 (這邊扯遠了,有興趣就看我那篇文章啦 XD)

Math 就是calc()語法的應用。

calc()是原生 CSS 裡很強大的一個「活用」語法,他本身是不需要再次被編譯的,但因為calc()可以加入變數作運算,因為牽扯到變數,所以我們需要編譯他們。

Color 與 Prefixes

未來color()也能像 SASS 一樣有lighten()這一類的數值調整,有興趣閱讀 spec 的朋友可以參考 W3C 的 draft:Modifying Colors: the color-mod() function

最後是針對瀏覽器添加的 prefix,以 Compass 為例,我們會寫:

CSS

以編譯成:

CSS

但 Myth 不需要加上@include這一類的函式,我們只要寫一行transition: color .2s;,就可以編譯成相容瀏覽器的語法。

以上就是 Myth 提供的四個核心語法。

如果你有興趣玩玩原生 CSS 的最新函式,也許可以考慮使用 Myth 幫你編譯唷!


安裝與使用 Myth,並搭配 gulp 自動化編譯

請先安裝 myth 這個套件,請使用 npm 套件管理:

Shell

他的使用方法很簡單~,假設我們在 input.css 寫好檔案,想把它編譯成 output.css,只要使用myth指令即可:

Shell

當然,每次要這樣輸入還蠻累的,所以可以搭配 gulp-myth 自動化工具。他除了支援 gulp 之外也有支援 grunt,不過我比較喜歡用 gulp,所以只提供 gulp 的設定方法 XD,如果你自己有在用 grunt,想必如何設定對你也不是難事啦😊 ~

專案目錄結構

先假設我們的專案目錄結構如下:

Plain Text

我們會在 dev/ 底下開發 CSS 檔案,最後希望透過 Myth 幫我們編譯到 build/ 目錄下。

⚒ 先安裝 gulp-myth

Shell

⚒ 新建 gulpfile.js 檔案

JS
gulpfile.js

最後到 terminal 執行gulp就大功告成啦!只要寫好 CSS,就可以透過 gulp 自動幫你編譯成另外一個 CSS,並存放至 build/ 目錄底下唷!


利用 gulp 結合 Compass 與 Myth

Myth 的存在並不是為了取代各種預處理器,透過前面的介紹,希望各位能理解它們存在的意義。Myth 的網站也清楚地提到:

You can still use variables and math functions, just like you do in preprocessors.

所以接下來讓我們試著把這兩個預處理器合在一起吧 ~

我自己使用的預處理器是 Compass,所以等等一樣只以 Compass 做例子,然後這次的目錄結構更改如下:

Plain Text

ps. 記得要先compass create啊 XDDD

⚒ 先安裝 gulp-compass

Shell

⚒ gulpfile.js 設定如下

JS
gulpfile.js

最後同樣到 terminal 執行gulp就完成了。利用 gulp 自動化工具,會先將 scss 檔案編譯完成,再交給 myth 編譯,最後再覆蓋到 stylesheets/ 目錄下。

以上兩種方法提供給各位參考,有興趣使用 Myth 的朋友也可以玩玩看唷~


昨天在看某篇技術文章時,看到最後心有慼慼焉,節錄如下:

大家大可不必過分在意一點點的 CSS 細節,CSS對於產品的商業價值有,但是到了一定階段以後,實際上就有限,或者說很難直觀的體現,或者說性價比就不高了。

以現在瀏覽器的渲染性能以及我們實際的開發需求,就算有差異,有價值嗎,肯定沒有!

大環境如此浮躁,你會發現,自己遇到的困境並不是技術成長遇到了瓶頸,而是根據不需要你這方面進一步的技術成長,來,幹點收益更明顯的事情!

我想,很多前輩技術博客斷掉了,怕也是人在職場,身不由己!

我能不能走出一條不一樣的路呢?

玩這些新的技術到底對現在的工作 / 生活有沒有幫助?其實想想還蠻哀傷的 XDD

不過我又想起了自己寫部落格的初衷,原本就不是要給誰誰誰看,也不是為了流量或是各種附加利益,畢竟我要賺錢我就轉行去寫 美妝 / 3C / 生活了 😂,我之所以想寫這些東西,純粹是為了記錄,畢竟大腦容量有限,我所能做的就是利用紙筆、利用打字幫我記錄下來。如果哪天我忘記了,至少還有這些記錄可以翻閱。

這就是我的初衷,直到現在依然不變,所以轉而想想,也不用怕別人需不需要,不違本心而已 XDD

扯遠了,哈,總之有任何問題都歡迎一起交流討論,針對 gulp 有更好的寫法也歡迎告訴我喔!

使用 CSS:not 與 data-index 即時搜尋頁面

去年看了一篇文章「Client-side full-text search in CSS」可以在單一頁面即時搜尋資料,覺得非常的好用,之前也有在粉絲團分享過這篇文章。原本不打算重新寫教學(因為原作者已寫的很詳細),但是最近發現有朋友不知道這功能,所以轉念想想,還是記錄下來順便推廣一下這好用的功能吧 🙂

我有將這個功能實作在前公司的網站(fanxin.tv),如果你有登入,可以進入我的動態點選「朋友列表」或「尋友工具」的分頁觀看效果,或者可以參考以下我用 codepen 做的範例

直接在搜尋框打上要搜尋的人名(可以用J,j搜尋),可以看到頁面即時篩選出正確的名字

這個範例有搭配 JavaScript,原作者使用的是原生的 JavaScript,而我為了稍作區別,將它改成了 jQuery,所以想瞭解怎麼用 jQuery 寫的朋友可以參考我的範例 🙂

這個即時頁面使用了 :not 以及 data-* 完成(不得不說, data-* 真的超好用的 XD),以下簡單介紹如何使用它們達成該功能。

在 html 加入 data-* 屬性

從頁面看,感覺是搜尋類別 name ,但其實我們要在 name 的父層 wrap 加上 data-index ,利用 data-index 做搜尋,而不是用 name

因此可以看到我在每個 wrap 裡加上了 data-index ,值跟 name 一樣都是填上名字。(第 1 & 3 行、第 6 & 8 行)

HTML

唯一不同的是,即使原本的 name 有大小寫,我在data-index一律改成小寫表示,如果要透過後端產生資料,可以從後端作處理,在樣板輸出的時候就先將大寫轉成小寫。

使用 :not 屬性做篩選

接著我們在 HTML 頁面加入以下語法(可以加在搜尋框的後面):

HTML

我們會利用 jQuery 動態在 style id="m-search" 裡加入 :not 語法,這樣就可以即時在頁面做篩選了。

:not是 CSS 的偽元素,跟 :nth-child 有異曲同工之妙,他可以幫我們做到元素篩選,假設今天我們搜尋「j」,希望出現所有名字有「j」的人,可以利用:not寫成:

CSS

這段意思是:「只要 data-index 的值沒有 J,就隱藏他」。

使用 data-index*= 是因為我們要做模糊比對,只要 data-index 有出現這個字都可以,畢竟我們不希望只搜尋字首或字尾,而是搜尋全部。

利用 jQuery 即時搜尋

最後,就可以利用 jQuery 即時搜尋,只要搜尋框有「改變、鍵盤輸入、貼上」等事件,我們就即時在 style id="m-search" 裡加入 :not 篩選,而他的篩選依據就是我們搜尋框的值:

JS

結語

以上就是整個過程,只要利用 CSS 以及 JavaScript(jQuery) 就可以做到即時搜尋,但是他只能搜尋這個頁面的東西,畢竟只是單純抓取 HTML DOM,如果要搜尋後端資料,還是要用 ajax 囉。

相關 jQuery 插件應用

3/12 更新:

有朋友將該功能做成 jQuery 插件釋出,有興趣想玩玩看的話,可以直接套用 jQuery 插件喔。

插件安裝與介紹:https://github.com/dca/jquery-msearch

用 data-* 屬性做出純 CSS 的 tooltip

最近因為案子需求,要做「tooltip」的功能,簡單來說,tooltip 是一種「當滑鼠移過文字時,會跳出一個簡短的提示說明」的特效。

tooltip 技術已存在很久,發展也有一段時間了,不論是用純 CSS 製作,或是透過 JavaScript 控制都有人寫過,不過最近我發現還可以利用 HTML5 的新標籤 data-* 達成。去年我有寫過一篇利用data-*在 HTML 以及 jQuery 存取資料的文章,但 data-* 厲害的地方不僅在此,我們還可以直接利用 CSS 的 attrdata-* 資料抓出來噢!!

那話不多說,就先上範例吧:

可以看到當滑鼠移過「Hover Me」的文字時,右方會淡出一個提示訊息;滑鼠移過「Push you mouse here」文字時,右方會出現多行的提示。

在此跟各位簡單介紹一下,如何使用 data-* 達成該功能。

在 html 加入 data-* 屬性

首先要做的第一件事情,就是設定 tooltip 的 html 程式碼。我的寫法為:

HTML

span裡面寫上data-tooltip的屬性,然後可以把它當作 HTML 屬性直接使用,在值(value)裡寫上提示文字。data-tooltip的「tooltip」名字可以自取,只要前面的格式以data-為開頭即可。

在 CSS 利用 attr 抓取 data-* 屬性

CSS 的偽元素是個很強大的東西,我們可以利用他做很多運用,通常為了做一些效果,content:" "多半會留空,但其實可以在裡面寫上attr抓資料歐!

我們可以這樣寫:

CSS

attr裡面塞入我們在 html 新增的data-tooltip屬性,這樣偽元素(:before) 就會得到該值。

利用 pre 解決 tooltip 自動換行

將 tooltip 的樣式做好後,也許你會發現文字的換行有點奇怪,可能會出現這樣的情況:

「Hello World」文字並沒有按照預期的情況換行,簡單來說是因為預設會使用空白換行,因此我們可以使用pre標籤保留空白字元,寫法為white-space: pre;

利用 Unicode 字元顯示多行 tooltip

最後,如果我們希望 tooltip 可以顯示多行文字該怎麼辦呢?
一開始我很直覺的在 data-tooltip 裡面加入 br 標籤,但他會直接將br秀出來:

後來我發現 bootstrap 有寫好 tooltip 的元件,他的做法是如果你要在 data-* 裡面使用 HTML 標籤,就必須加入一行 data-html="true" 的設定,當時看完覺得超神奇的,他把這串設定寫在 javascript 裡面做判斷,但我還是似懂非懂,不知道 bootstrap 的具體設定方法。

最後,我採用 Unicode \a 作處理。

在想要換行的地方改用&#xa ;取代br,這樣文字就會自動換行囉!!

HTML

☞ 補充

; 的前面其實不需要空格,但如果我不空格,字元會被編輯器吃掉。想看比較完整的語法可以參考 codepen 範例喔。

參考來源:http://stackoverflow.com/questions/16451553/css-data-attribute-new-line-character-pseudo-element-content-value

雖然我還是很想知道 bootstrap 到底是怎麼寫的,有在 FB 問過朋友,但其實還是看不懂,OTL

總之,data-* 真的是一個強大又好玩的東西,不僅可以自定義屬性(把自己當成 HTML 的規則制定者?),還可以透過 jQuery & CSS 存取~,大家一起來玩吧 😀