前言
我在第二屆 CSS Conf(2015 中國 CSS 開發者大會)上的演講廣受好評,很多網友向我索取現場視訊。條件所限,這個演講並沒有留下視訊存檔。因此,本文嘗試在靜態幻燈片的基礎上,以文字的方式還原現場講解,儘可能為不能去現場的朋友呈現最完整的體驗。
我在每幅圖片之間補充了講解文字。你不用分辨每段文字是配合上圖還是下圖的,只管順序閱讀即可。
大家看到封面的畫風,應該可以看出我今天走的不是技術路線,而是娛樂路線。如果說前面幾位講師的分享是燒腦的懸疑推理大片,我這個環節就是輕鬆愉快的爆米花電影了,大家可以放鬆一下。
接下來,接照慣例,需要介紹一下 “這個人”。有兩個標籤可以描述這個人。
首先,他來自百姓網(此處省略百姓網的誘人之處一百字)。歡迎各位小夥伴到百姓網來看一看,我們一起來玩些好玩的。
第二個標籤是這個:
大家可能會說,“把 CSS 寫進自己的名字”,聽起來這麼拽,那你上一屆 CSS Conf 怎麼沒來?
上一屆 CSS Conf 我確實沒有來。我給自己找的理由是北京太遠了,我就不去了。但實際上我自己很清楚,真正的原因是,我並不知道自己應該在這樣的大會上分享什麼。
第二屆 CSS Conf 就在上海,我沒有任何理由不來,但我仍然需要面對這個問題——我要為現場的觀眾分享些什麼呢?
其實,最近這幾年,在 CSS 領域出現了很多好東西:
當我聽說它們、瞭解它們、使用它們的時候,我的心情是這樣的——
右邊的這個小男孩就是我。我的心情是激動、新奇、興奮。
那麼,我會在 CSS Conf 上分享它們嗎?一番思索之後,我的答案是——“不”。
有幾個原因:首先,我相信肯定會有其它同學會分享它們;此外,它們不是 CSS,它們並不能解決我們在 CSS 上遇到的問題。
更重要的是,它們其實跟我沒什麼關係,它們是別人寫的優秀的工具,而我只是在享受別人的發明所帶來的便利。就好像我在遊樂場 high 了一天之後,我還是我,還是要回到自己平凡的生活。
那我應該分享些什麼?我嘗試在記憶的長河中逆流而上,找尋 CSS 最初帶給我的欣喜和感動。
我發現,有一件事情,即使在今天,仍然可以實實在在地帶給我樂趣——那就是用 CSS 的各種神奇的特性,實現各種神奇的效果。有些效果甚至令人驚歎——“這怎麼可能是用 CSS 實現的?!”
在 我的個人主頁 上,收錄了一些 CSS 謎題。所謂 “謎題”,就是需要費一番腦筋才能實現的效果。每一道題都有我自己的解答和評述。
在這些謎題中,收穫最多讚歎的,應該是這個案例——弧形排列的可摺疊二級導航。
這是 2009 年的時候,一位網友在論壇裡求助,說他們公司的設計師想要實現這樣一個效果。大家看到背景是一個弧形的造型,所有導航選單需要順著這個背景圖案以弧形排列。
而且,有些選單是可以展開的(上圖中加紅框的部分)。當我點選第一個可展開選單時,效果是這樣的:
點選第二和第三個,展開效果是這樣的:
……和這樣的:
所有選單項都需要順滑地貼合這個弧形背景自然展開。
論壇裡的網友紛紛表示,這樣的效果應該用 Flash 來實現才對,用 CSS 怎麼可能做到?!
我動了一番腦筋,最終把這個效果做了出來。當然,在這個例子裡,我用到了一些 JS,用來監聽點選事件、切換元素 class;除此以外所有的元素佈局和定位都是由 CSS 來完成的,也就是說,你可以任意地改變選單項的數量和內容。
大家可以試試,在 2009 年,要相容 IE6,應該怎麼做?
今天由於時間關係,我們不會講解這個案例。我會跟大家聊一些跟 CSS 有關的趣事。我今天的分享分為兩個部分:
第一部分會介紹一件 CSS 能做的有趣的事情;第二部分是我最近遇到的一件值得高興的事情。
首先,這件趣事就是用 CSS 畫圖示。
請問現場有哪些同學嘗試過?(僅前三排就有多人舉手。)好的,試過的同學接下來一定會找到很多共鳴。
有同學可能會問:
我這裡不想找一些技術上的原因,單從感性的角度來回答這個問題。
它太好玩了!只有你試過,你才知道它有多好玩。
有一句話,大家可能聽過,是說 JS 的:
我這裡借用這個句型,說一個 CSS 的版本:
不信?我們來看一些例子:
在 CSS3 剛開始火起來的時候,大家肯定見過這張圖——用 CSS3 畫的機器貓。
用純 CSS 畫的 iPhone。
用 CSS 畫的小黃人。
很多公司的 logo 也是很有特點的,也被網友用 CSS 畫了出來,比如 Opera 的 logo:
最神奇的是下面這個:
(笑聲。)
居然還有網友用 CSS3 畫了一個 IE8 的圖示。不過,諷刺的是,IE8 自己完全沒有能力正常渲染這個圖示。(笑聲。)
這件事情這麼好玩,我自己當然也是做過的。
我寫過一個移動端的 Web UI 框架叫 CMUI,在最初的版本中,圖示的解決方案 就是用純 CSS 來實現的。
我們來看一下用 CSS 畫圖示會用到哪些基本原理。
怎樣用 CSS 來畫一個矩形?這沒有任何難度,因為任何一個塊元素本身就是矩形。
改變它的寬高,把它拉長,就可以得到一條線:
那怎樣得到一個三角形?
在早期的 CSS 中,沒有任何特性是跟斜線直接相關的。但你要相信勞動人民的智慧是無窮的。很快 CSS 開發者們就發現了關於邊框的一個祕密。
這是一個加了邊框的塊元素。當我們把四個方向上的邊框設定為不同的顏色時,效果會變成這樣:
我們會發現,在不同邊框顏色的交界處,出現了一道斜邊。接下來,我們逐漸減小這個元素的寬高至零,同時增加各條邊框的厚度,最終會變成這個樣子:
我們會得到四個頭對頭的三角形!
接下來,我們用透明色把不需要的三條邊框隱去,就可以得到一個三角形:
通過改變這個元素各條邊框的厚度,就可以改變這個三角形各條邊的角度。我們可以得到銳角三角形:
……或者直角三角形等等。
以上是在 CSS2 時代用 CSS 畫圖示時我們可以做的。CSS3 為 CSS 增加了更加強大的能力,我們看來一個例子:
CSS3 增加了圓角屬性,給一個矩形設定圓角,可以得到一個圓角矩形;逐漸增加圓角半徑到一定的程度,我們就可以得到一個圓形。
圓角除了對邊框有效,還可以對實色矩形生效。比如這條短線,我們可以把它設定為圓頭的樣式;CSS3 還增加了旋轉這樣的變形屬性,我們可以把它扭轉一定的角度。
把這兩個圖形組合起來,我們就可以得到……
一個放大鏡的圖示。
根據這個思路,常見的圖形都可以拆解開來,化整為零,用 CSS 畫出來。比如下面這個:
……這個:
……和這個:
下面這個圖示稍稍有些複雜:
你可能會想,它居然也可以用 CSS 畫出來?
我們先從簡單的開始。三角形我們已經介紹過了,所以先把它隱去:
再來看外層的那個有斜向缺口的矩形框。斜角缺口也需要利用邊框交界處的斜邊來實現,不過這個框無法用一個元素來實現,我們需要分兩步走。完成一邊:
……再完成一邊:
最後我們剩下的難題似乎就是這個奇怪的形狀了,好像是個鷹嘴的樣子。
這個形狀如何實現?給大家五秒鐘的時間考慮一下。
在揭開謎底之前,我們需要了解一下:
這裡有一個塊元素,設定了邊框和圓角,它的兩條邊框會通過一段圓弧連線起來:
首先,第一個真相,邊框圓角可以指定兩個半徑值(下圖中的 r1
和 r2
):
如果這兩個半徑值相等,則連線兩條邊框的圓弧就是一條相標準的 1/4 圓弧。如果不相等(比如我們把 r2
減小),會得到這樣的效果:
我們發現連線兩條邊框的圓弧會變成一道 1/4 橢圓弧。這個真相解決了我們在尺度上的問題。接下來,我們需要解決形狀上的問題。
第二個真相,不同方向上的邊框的厚度(下圖中的 w1
和 w4
)也是可以不一樣的:
如果我們逐漸減小 w4
的值至零,我們會得到這個形狀:
大家應該可以看出,我們需要的形狀已經出現了。最後,我們調整一下這個元素的寬高,只保留我們需要的部分,就可以得到這個鷹嘴的形狀。
最終,我們就實現了這個乍看起來不可能用 CSS 實現的圖示。
看到這裡,可能有同學會說:
“你這是奇技淫巧啊!”
事實上,我們剛剛介紹的技巧都是標準的 CSS 特性。只有那些對 CSS 的各種特性觀察入微的人,才有可能在非常規的場景之下把這些特性發揮出來,從而完成不可能完成的任務。——這是我對所謂 CSS “奇技淫巧” 的理解。
說到 CSS 圖示這件事,有一個網站不能不提。
這個網站叫 one-div.com,收錄了這位站長製作的純 CSS 圖示。這個網站最大的特點在於,所有的圖示只用到了一個 <div>
標籤。(驚歎聲。)很有創意,推薦大家觀摩。
用 CSS 畫圖示這麼好玩的事情,肯定不止我和這位站長會想到。我們搜尋 “純 CSS 圖示” 這個關鍵字,可以發現有很多的案例和開源專案。
當然,我們也會聽到反對的聲音。比如這一條:
“用 CSS 畫圖示,這種瘋狂的事情趕快停止吧!”
大家玩得這麼開心,你一本正經地來教育大家,很無趣,對吧?當然,這篇文章的觀點肯定有它的道理,但任何一門技術都是有優點和缺點的,要看使用場景。比如,下面就是一個正面的例子:
這是一個開源專案,叫 fileicon.css,作者是中國人。
為什麼說它是一個正面的例子呢?因為,作為一個樣式庫,它的介面非常清晰。
你只需要使用一個空元素,再加上一些有意義的屬性就可以了。
然後,你就可以得到一個設計精緻的檔案圖示了——它有著優雅的圓角,還有一個可愛的折角效果。
我很喜歡這個專案。
不過在現有的版本中,它有一個小缺憾——只能把它放在純白的背景上。如果你把它放在其它背景上,會發現它的折角的空缺位置是不透明的:
實際上能做到這一步已經很不容易了。大家可以自己試一下,用一個空標籤把這樣的圖示做出來。
我很喜歡這個專案,於是我花了一點時間,給作者寫了一個 demo。我用了一些 CSS 奇技淫巧,把折角處做成了真正的透明:
同時,我還順手支援了 IE8。
因為 IE8 支援偽元素,我們沒有理由放棄它。只不過 IE8 無法渲染圓角,我們在 IE8 下只有方角效果了。
好的,以上就是我的分享的第一部分——CSS 圖示。
(掌聲。)
鳴謝
- 插畫作者:小妖(百姓網設計師)