標籤:

前端知識 | CSS小技巧-自適應橢圓

背景知識:

border-radius 屬性的基本用法。

難題:

你可能注意到過,給任何正方形元素設置一個足夠大的 border-radius,就可以把它變成一個圓形。所用到的 CSS 代碼如下所示:

圖1.1給元素設置固定寬高以及一半長度的 border-radius,可以得到一個圓形

你可能還注意到了,如果指定任何大於 100px 的半徑,仍然可以得到一個圓形。規範特別指出了這其中的原因:

「當任意兩個相鄰圓角的半徑之和超過 borderbox 的尺寸時,用戶代理必須按比例減小各個邊框半徑所使用的值,直到它們不會相互重疊為止。」——CSS 背景與邊框(第三版) http://w3.org/TR/css3-background/#corner-overlap)

不過,我們往往不願意對一個元素指定固定的寬度和高度,因為我們希望它能根據其內容自動調整並適應,而內容的長短不可能在事先就知道。即使是在設計一個靜態網站的時候(元素的內容可以預先確定),我們也可能需要在某個時刻改變其內容;或者我們為它準備了一款尺寸略有差異的回退字體,而不同字體對相同內容的渲染結果很可能是不同的。在這個案例中,我們通常期望達到這個效果:如果它的寬高相等,就顯示為一個圓;如果寬高不等,就顯示為一個橢圓。可是,我們前面的代碼並不能滿足這個期望。當寬度大於高度時,我們得到的形狀如圖1.2所示。那我們到底能不能用 border-radius 來產生一個橢圓,甚至是一個自適應的橢圓呢?

圖1.2在前面的圓形示例中,當高度小於寬度時發生的情況;border-radius 所產生的圓形用虛線標示。

解決方案:

說到 border-radius,有一個鮮為人知的真相:它可以單獨指定水平和垂直半徑,只要用一個斜杠(/)分隔這兩個值即可。這個特性允許我們在拐角處創建橢圓圓角(參見圖1.3)。因此,如果我們有一個尺寸為 200px×150px 的元素,就可以把它圓角的兩個半徑值分別指定為元素寬高的一半,從而得到一個精確的橢圓:

圖1.3一個容器設置了不相等的水平和垂直 border-radius;拐角處的弧線現在呈現出橢圓的形狀,這個橢圓的水平和垂直半徑就是我們為 border-radius 指定的值,在圖中用虛線標示。

圖1.4通過非對稱的 border-radius 曲線來創建一個橢圓。

我們可以在圖1.4中看到結果。但是,這段代碼存在一個很大的缺陷:只要元素的尺寸發生變化,border-radius 的值就得跟著改。我們在圖3-5中可以看到,當元素的尺寸變為 200px×300px 時,如果 border-radius 沒有跟著改變,會發生什麼後果。因此,如果我們的元素尺寸會隨著它的內容變化而變化,這就是一個問題了。難道我們真的走投無路了嗎?其實,border-radius 這個屬性還有另外一個鮮為人知的真相,它不僅可以接受長度值,還可以接受百分比值。這個百分比值會基於元素的尺寸進行解析,即寬度用於水平半徑的解析,而高度用於垂直半徑的解析。這意味著相同的百分比可能會計算出不同的水平和垂直半徑。因此,如果要創建一個自適應的橢圓,我們可以把這兩個半徑值都設置為50%:

由於斜杠前後的兩個值現在是一致的(即使它們最終可能會被計算為不同的值),我們可以把這行代碼進一步簡化為:

最終,只需要這一行代碼,我們就可以得到一個自適應的橢圓了。

擴展:border-radius 的簡寫方式

延伸一句代碼半橢圓:border-radius: 100% 0 0 100%/50%;即可形成如圖1.5所示的半橢圓

圖1.5

延伸一句代碼實現1/4橢圓:border-radius: 100% 0 0 0; 即可形成如圖1.6所示的1/4橢圓

圖1.6

小花絮:

為什麼叫 border-radius?可能有人會奇怪,border-radius 到底由何得名。這個屬性並不需要邊框來參與工作,似乎把它叫作 corner-radius 更貼切一些。這個名字乍聽起來確實讓人摸不著頭腦,其實原因在於 border-radius 是對元素 borderbox 進行切圓角處理的。當元素沒有邊框時,可能還看不出差異;當它有邊框時,則以邊框外側的拐角作為切圓角的基準。邊框內側的圓角會稍小一些(嚴格來說內角半徑將是 max(0,border-radius-border-width))。

海說軟體會持續推出前端教學課程、技術乾貨。

-END-


推薦閱讀:

理解mobx
前端日刊-2018.01.24
我理解的同步載入與非同步載入
web前端:如何(安全地)使用Vue.js的jQuery插件
前端與AI

TAG:前端開發 |