打造超完美CSS圓角框(不是一般的完美)

打造超完美CSS圓角框
CSS圓角框的出現已經不是一天兩天了,它出現的直接目的就是爲了替換原有的以四個角上安放圖片爲主的圓角框,它的優勢在於不需要用圖片,對於統一主題中出現不同顏色樣式的需求,不需要用作圖工具重複製作多套圓角圖片,而可以直接從css抽取顏色信息,方便做成獨立的配色方案,其次,它對於圓角框長寬等位置信息的設置具有比圖片圓角更爲高明的自適應能力,真正可以把程序員的注意力集中到內容的排布而不是陷入對頁面佈局應對的泥藻中(這也可以作爲一個簡單的分離關注點的有效例子)。
CSS圓角框有如此優秀,那麼爲什麼不用呢,最近,在我和一位好兄弟合作的項目中出現了上述需求(這位兄纔在web開發領域擁有多年的經驗,曾經自己寫過ajax框架,他做的東西精巧別緻,思維獨特,始終是我心目中強悍的高手),於是決定在其中使用CSS圓角框替換傳統的圖片圓角,我把設想告訴他,但是他的第一反應是讓我不要用CSS圓角,原因如下:
  1. CSS圓角從所周知會出現鋸齒,難以處理
  2. CSS圓角內部一般都無法放置複雜的頁面元素,放置其中的元素要麼會出現大小難以調節,要麼會使得整個圓角框發生嚴重的元素構圖混亂(也就是整個頁面不聽我們的話,發生破裂)
  3. CSS圓角很難跨瀏覽器,兼容性差
(人們常說提出一個問題往往比解決一個問題更爲難能可貴,更何況我的這位兄弟能在第一反應給CSS圓角框的缺陷做出如此精闢的概括,更顯示出他在web開發領域紮實的基本功和對事物鍼砭時弊的觀察力,這一點始終讓我望塵莫及。)
上述CSS圓角框的缺陷都如我這位兄弟所說,的確都存在,而且沒有一個問題能夠輕易解決,但是有句話怎麼說來着,“車到山前未必有路,與其繞過這座山,還不如踏踏實實一步一個腳印的踏出一條路來”,一來方便自己行走,二來蔭庇後人。
那麼讓我們一個一個的仔細分析上述問題,慢慢解決他們
問題一 首先看鋸齒,我們知道鋸齒的實質是肉眼無法接受眼前所看到的現實的狀況,計算機在處理曲線圖形時,若是沒有專門的解決方案,鋸齒可以說無處不在,那麼這個解決方案究竟在那裏呢?聰明的你一定會在第一時間聯想到,我們的圖形處理利器photoshop(以下簡稱ps),ps在圖形處理領域可謂一直是領軍羊,它不僅處理速度極快,而且在技術上擁有大量的積累。我們這裏只看它是如何處理鋸齒的
下圖爲鋸齒和抗鋸齒後圖形的對比
我們看到在使用了抗鋸齒的圓角邊緣呈現出一種漸進的半透明狀態,沒錯,它其實就是一個半透明,這也就是ps中抗鋸齒算法的本質
假設前景圖層上某A點,背景圖層上某B點,目標半透明C點,那麼我們可以用如下公式來獲取目標點C的RGB值:
XML/HTML代碼
  1. R(C)=(R(A)*alpha+R(B)*(256-alpha))/256      
  2. G(C)=(G(A)*alpha+R(B)*(256-alpha))/256      
  3. B(C)=(B(A)*alpha+R(B)*(256-alpha))/256      
  4. alpha取值範圍    [0,256]      
  5. (R Red, G Green, B Blue)  
這就是一個半透明的算法(其實是一個着差運算),這個算法是方形(box)抗鋸齒算法的基礎(當然,抗鋸齒本身就是一個高級話題,算法也有很多種,比如方形(box),三角(triangle),高斯(gauss),米西爾(mitchell),其中大多是動態圖形抗鋸齒,有興趣的朋友可以自己研究一下,這裏只討論最簡單的靜態圖形抗鋸齒),方形抗鋸齒算法是在過濾區域內使用均等的權重把採樣疊加在一起實現的,也就是說離邊緣越近,alpha值越高,離邊緣越遠,alpha值越低,你可以在邊緣的各像素平均分佈alpha值來達到抗鋸齒的目的
對於鋸齒和抗鋸齒有了基本的概念,那麼解決方法也有了
1) 最簡單的解決方法是在ps中做一個圓角矩形,放大後把邊緣的各像素點依葫蘆畫瓢照搬到頁面上去(用css控制border-color和background-color兩個屬相實現)
2) 更爲穩妥的解決方法應該是做一個專門的程序來解決抗鋸齒,這樣一通百通,原本想自己寫,可是得益於別人已經做了這樣的工作
這是一個php的實現版本,用的就是方形抗鋸齒算法,有了這麼方便的工具,相信你可以最快速的做出沒有任何鋸齒的CSS圓角框來
問題二,三 在web2.0如火如荼的今天,圓角成爲一種首推的web2.0標誌性設計元素和風格,webstandard由於其強大的控制能力和便於修改的特性得到大面積推廣,這直接促使div(span)+css的設計模式越來越得到大家的認可,於是CSS圓角框就有了它存在的最大理由,可惜的是,大多數圓角框的設計意圖僅僅是爲了要在其中放置一些簡單的頁面元素,諸如文本和圖片,由於需求的侷限,設計者無法考慮到日後圓角框還有更大的活動空間(不要去責怪設計者,CSS圓角框作爲一種設計手段上的革新,本身就是一種偉大的顛覆和創造,我們又怎麼忍心對設計者要求的如此十全十美,如此苛刻呢)
下圖爲在Firefox(以下簡稱ff)中頁面出現混亂的情況
正確的顯示效果

由於圓角框內放置了複雜的頁面元素(包括了float屬性,margin屬性等),ff下混亂的頁面元素大家也看到了,可以用慘不忍睹來形容,而同樣的錯誤在ie6, ie7中也會發生,那麼究竟是什麼導致了元素混亂不堪呢?
下面以spiffycorners生成的代碼爲例
CSS代碼
  1. .spiffy{display:block}   
  2. .spiffy *{   
  3.   display:block;   
  4.   height:1px;   
  5.   overflow:hidden;   
  6.   font-size:.01em;   
  7.   background:#CC0000}   
  8. .spiffy1{   
  9.   margin-left:3px;   
  10.   margin-right:3px;   
  11.   padding-left:1px;   
  12.   padding-right:1px;   
  13.   border-left:1px solid #e99191;   
  14.   border-right:1px solid #e99191;   
  15.   background:#d83f3f}   
  16. .spiffy2{   
  17.   margin-left:1px;   
  18.   margin-right:1px;   
  19.   padding-right:1px;   
  20.   padding-left:1px;   
  21.   border-left:1px solid #f9e5e5;   
  22.   border-right:1px solid #f9e5e5;   
  23.   background:#d53030}   
  24. .spiffy3{   
  25.   margin-left:1px;   
  26.   margin-right:1px;   
  27.   border-left:1px solid #d53030;   
  28.   border-right:1px solid #d53030;}   
  29. .spiffy4{   
  30.   border-left:1px solid #e99191;   
  31.   border-right:1px solid #e99191}   
  32. .spiffy5{   
  33.   border-left:1px solid #d83f3f;   
  34.   border-right:1px solid #d83f3f}   
  35. .spiffyfg{   
  36.   background:#CC0000}  
XML/HTML代碼
  1. <div>  
  2.   <b class="spiffy">  
  3.   <b class="spiffy1"><b></b></b>  
  4.   <b class="spiffy2"><b></b></b>  
  5.   <b class="spiffy3"></b>  
  6.   <b class="spiffy4"></b>  
  7.   <b class="spiffy5"></b></b>  
  8.   
  9.   <div class="spiffyfg">  
  10.     <!– content goes here –>  
  11.   </div>  
  12.   
  13.   <b class="spiffy">  
  14.   <b class="spiffy5"></b>  
  15.   <b class="spiffy4"></b>  
  16.   <b class="spiffy3"></b>  
  17.   <b class="spiffy2"><b></b></b>  
  18.   <b class="spiffy1"><b></b></b></b>  
  19. </div>  
在仔細觀察了代碼之後我們發覺一個問題,在其中的容器元素spiffyfg的css中沒有出現float屬性,float是用於控制頁面元素浮動的工具,它是負責頁面佈局的強有力的手段,我們在頁面設計中會用到大量的float控制代碼,但是,對於float而言,微軟的IE和Firefox有着不同的理解,在W3C對於webstandard的標準中,嚴格的規定了屬性的繼承法則,子元素必須以明文聲明某個屬性是從它的父元素繼承而來,若是該屬性缺失,則認爲繼承終止,Firefox就嚴格的貫徹了這一標準, 而微軟的產品一向以實用主義和尊重用戶體驗聞名,這勢必導致他更遵從於產品的價值標準,在IE中,瀏覽器對屬性的解釋會採取就近原則,如果子元素屬性缺失,就會從它的父元素獲取屬性。這種做法粗看上去方便了設計者,但已不適應走向標準化的今天。
沒錯,我們已經找到了問題的癥結,於是我們在這裏可以把第二個和第三個問題歸結爲由於ie和ff在float屬性上的不同解釋所引發的衝突和不兼容。
我們找到了問題的本質原因,但又帶來了新的問題,如何編寫代碼適應兩個不同的瀏覽器,出於同一屬性的不同解釋,也就意味着這是一個原子性問題,擅自改動代碼,造成的結果只能是拆東牆補西牆,這時候,我們想,是否有一個工具,IE認可,FF不認可,那不就解決問題了,那麼這樣的工具存在嗎,這個時候我的這位兄弟提醒了我,應該說,上帝在關閉一扇門的時候總會爲其打開另一扇門(不要把上帝認爲是比爾蓋茨^_^),微軟擅做決定改變了標準,讓我們無法設計統一的代碼,但在其css的設計中也提供了一個他獨有的工具:表達式(expression),表達式的最初設計意圖是爲了在css中插入可執行的javascript代碼,方便對羣組元素方便的賦值,而在實踐中我們發現,這一工具不爲ff認可,於是問題就出現了轉機。
針對屬性繼承的問題,我們可以在容器元素spiffyfg的屬性中插入如下代碼
CSS代碼
  1. .spiffyfg{   
  2.   background:#CC0000  
  3.   float:left;       /*for Firefox*/  
  4.   float:expression("none"); /*for IE      */  
  5. }  
還有一個小問題,兩款瀏覽器正對圓角邊框的顯示方法也會有不同,同樣的解決方法,在.spiffy *元素中插入
CSS代碼
  1. .spiffy *{   
  2.   display:expression("block");   
  3.   display:-moz-box;   
  4.   height:1px;   
  5.   overflow:hidden;   
  6.   font-size:.01em;   
  7.   background:#CC0000  
  8. }  
OK,到現在爲止,藉助與各種工具,我們成功的打造了一款沒有任何鋸齒,可以容納任意複雜元素而又沒有任何兼容性問題的圓角框
本文在思考實踐和寫作過程中均受到了我的這位好兄弟的積極的啓發和引導,可以說沒有他的經驗和智慧,我們無法解決這些問題,文章的大量篇幅也不僅侷限於解釋原理和解決問題,而是希望能通過這樣一個在常人看來不起眼的圓角框的改良過程,給大家以問題解決思路和攻克難關的精神上的啓發
問題雖小,我們或許也能找到迂迴的道路,可人生中總會碰到絕境,如何逢生不在於工具,而在於你有沒有絕境逢生的信念。
(完)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章