border-radius與圓角

圓角因使人感覺舒適的友好風格而變得無處不在。這個無處不在也讓很多前端工程師累個半死,YAHOO Performance Research Engneer Team的Nicole在講演《Designing Fast Websites》中用的副標題是don』t blame the rounded corners!,從側面也說明了圓角給實現者帶來的困擾:實現麻煩、兼容困難、性能不佳。而W3C早在2002年的CSS3草案中就加入了一個叫 border-radius 的屬性,通過它可以直接來定義HTML元素的圓角。

CSS3的border-radius規範

最新草案中其主要信息如下:
1、屬性:border-top-right-radius
   border-bottom-right-radius
   border-bottom-right-radius
   border-bottom-right-radius
值:<length> <length>?。它們分別是定義角形狀的四分之一橢圓的兩個半徑。如圖:
image

a. 第一個值是水平半徑。
b. 如果第二個值省略,則它等於第一個值,這時這個角就是一個四分之一圓角。
c. 如果任意一個值為0,則這個角是矩形,不會是圓的。
d. 值不允許是負值。

2、屬性:border-radius。它是上面四個屬性值的簡寫。
值:<length>{1,4} [ / <length>{1,4} ]?

a. 如果斜線前後的值都存在,那麼斜線前的值設置水平半徑,且斜線後的值設置垂直半徑。如果沒有斜線,則水平半徑和垂直半徑相等。
b. 四個值是按照top-left、top-right、 bottom-right、bottom-left的順序來設置的。如果bottom-left省略,那麼它等於top-right。如果bottom-right省略,那麼它等於 top-left。如果top-right省略,那麼它等於top-left。

3、應用範圍:所有的元素,除了table的樣式屬性border-collapse是collapse時

4、內邊半徑等於外邊半徑減去對應邊的厚度。當這個結果是負值時,內邊半徑是0。所以內外邊曲線的圓心並不一定是一致的。

5、border-radius也會導致該元素的背景也是圓的,即使border是none。如果background-clip是padding-box,則背景(background)會被曲線的內邊裁剪。如果是border-box則被外邊裁剪。border和padding定義的區域也一樣會被曲線裁
剪。

6、所有的邊框樣式(solid、dotted、inset等)都遵照角的曲線。如果設置了border-image,則曲線以外的部分會被裁剪掉。

7、如果角的兩個相鄰邊有不同的寬度,那麼這個角將會從寬的邊平滑過度到窄的邊。其中一條邊甚至可以是0。

8、兩條相鄰邊顏色和樣式轉變的中心點是在一個和兩邊寬度成正比的角上。比如,兩條邊寬度相同,這個點就是一個45°的角上,如果一條邊是另外一條邊的兩倍,那麼這個點就在一個30°的角上。界定這個轉變的線就是連接在內外曲線上的兩個點的直線。

9、角不允許相互重疊,所以當相鄰兩個角半徑的和大於所在矩形區域的大小時,用戶代理(瀏覽器)比如縮小一個或多個角半徑。運算法則如下:f = min(Li/Si),i ∈ {top, right, bottom, left},Ltop = Lbottom = 所在矩形區域的寬,Lleft = Lright = 所在矩形區域的高。如果f < 1,那麼所有角半徑都乘以f。

瀏覽器支持

實際中,目前沒有任何一款瀏覽器支持這個屬性,只有部分瀏覽器利用其私有屬性支持部分實現:

1、Firefox對border-radius的支持:

程序代碼 程序代碼
-moz-border-radius: <length>{1,4} | inherit
-moz-border-radius-bottomleft : <length>{1} | inherit
-moz-border-radius-bottomright  : <length>{1} | inherit
-moz-border-radius-topleft  : <length>{1} | inherit
-moz-border-radius-topright : <length>{1} | inherit

a. 只對每個角設置一個半徑,只支持實現四分之一圓角,並不支持橢圓形圓角。
b. 具體每個角的命名規則也和W3C不一致,這個比較討厭。
c. Firefox3圓角已經相當圓滑了,Firefox2比較糟糕,好在它即將終結了。

2、Safari和Chrome對border-radius的支持:

程序代碼 程序代碼
-webkit-border-radius: <length>{1,2} | inherit
-webkit-border-bottom-left-radius : <length>{1,2} | inherit
-webkit-border-bottom-right-radius : <length>{1,2} | inherit
-webkit-border-top-left-radius  : <length>{1,2} | inherit
-webkit-border-top-right-radius : <length>{1,2} | inherit

a. 每個屬性有1個或2個值,當有兩個值時1個表示水平半徑,一個表示垂直半徑(當writing-mode改變也隨之而變)。所以,Safari和Chrome中的圓角可以是橢圓角。
b. webkit的實現方法和W3C的CSS3草案2005年版本非常一致,和當前的草案最大不同就是簡寫屬性-webkit-border-radius的屬性值也只有1個或2個值,意義和前面相同。
c. Chrome中圓角鋸齒比較嚴重,基本上和Firefox2是同一水平,或許是它的webkit版本較低造成的。
d. 由於webkit出生於khtml,所以把 上面屬性中的webkit換成khtml即會得到以khtml為核心的瀏覽器支持的屬性了。

3、Opera尚不支持border-radius,雖然Opera10 alpha擁有眾多的CSS3改進,但是依舊看不到對其支持的希望。

4、IE就不用說了,標準的不支持了。從MSDN的CSS Compatibility and Internet Explorer中可以看出IE8已經鐵定不支持了。

實際應用

最簡單的應用就是支持的用圓角,不支持的用方角。比如Wordpress2.7的後台、雅虎口碑UED的blog和今天你帶傘了嗎?。基礎代碼如下:

程序代碼 程序代碼
border-width: 1px;
border-style: solid;
-moz-border-radius: 11px;
-khtml-border-radius: 11px;
-webkit-border-radius: 11px;
border-radius: 11px;

實現請看演示實例

利用VML可以實現從IE5-7的圓角,但是貌似IE8不支持VML了。組件DD_roundies就是綜合以上解決方案的一個具體應用。說實話這樣實現出來的圓角也比較粗糙了,我感覺還不如不要。

像VML一樣,Canvas也能實現圓角,切除了IE外,所有的主流瀏覽器都支持。所以就有了兩者結合實現的組件Cornerz。

如果上面的現實太痛苦,而又非要用圓角的話,要麼一個像素一個像素去拼裝,比如Chunky Borders;要麼就老老實實用圖片來實現吧,比如CSS Mojo的方式。

出處: http://www.wowbox.com.tw/blog/article.asp?id=3148

重要度:
閱讀權限:
文章分類:
電腦標籤:

發表新回應