天天看點

border-radius 原理分析

border-radius 想必大家都有所了解,比較常見的用法就像下面一樣:

注意左邊的盒子 border-radius: 100px;  右邊的為0哦,是以右邊的實際上沒有設定圓角邊框屬性;咱們比較下:

border-radius 原理分析

看大家大概都能看懂,不過我就想弄清楚個原理,不然覺得記不住,而且很不爽,而且這個樣式細究起來有8個參數可以選,天呐,,,

是以我來說說我了解的圓角原理,就以上圖中的 border-radius: 100px; 為例分析;

上圖在我看來,浏覽器就是這樣渲染的,以左上角為例,如圖:

border-radius 原理分析

第一步:因為設定了 border-radius: 100px; ,是以浏覽器首先在原來盒子的四個尖角(其中左上角為 L1 ),以左上角 L1 為例,就是分别向下 100px ,向右 100px 至 A1、B1, 然後畫完這個正方形 L1A1OB1, 這樣就确定了圓心 O ,是以從圓心 0 開始到 A1 到 B1 就構成了一個 1/4 圓弧,然後浏覽器把正方形 L1A1OB1 中 L1A1B1 這一部分的背景色給抹去了(自然背景色就會變成父元素的背景色,但是 L1A1B1 這一塊邊框還是存在的,隻是看起來像是沒有了,你可以按 F12 檢查元素驗證我說的對不對?),效果見圖2;

第二步,大家可以發現,圓心 O 已經在邊框内容裡了,是以這個時候,做圓角的時候裡面内容也會受到影響,也就是說,裡面的綠色正方形也會受到圓角邊框的影響,那麼按照前面的規則,這個時候, OC1D1形成了一個 1/4 圓弧,然後把正方形 OC1M1D1 中 C1M1D1 這一部分的背景色給抹去了,隻不過這個時候抹去了原有的背景色,覆寫上了邊框的背景色,而不是父元素,不然豈不是太難看~~~效果見圖3:

其實,前兩步也可以這麼了解,通過 border-radius: 100px; 确定了 A1、B1、O 三個點,如果 O 在内容裡,就确定了 C1、D1 兩個點,然後就把 A1B1D1C1 這一塊區域塗成邊框的顔色就行了;最外層的 A1L1B1 背景色塗成父元素的

剩下的三個邊角也是一樣的處理規則,不過有一點可能要提下,如果圓心 O 不在内容裡面,那當然影響不了綠色的正方形盒子,就僅僅是邊框的圓角;不信看圖:

border-radius 原理分析

代碼:

<div class="verticalMid" style="background-color:#90EE90;border: 50px solid #FA8072;width: 250px;height: 250px;border-radius: 40px;float: left;">
        <div class="verticalMidSon">border-radius: 40px;</div>
    </div>
    <div class="verticalMid" style="background-color:#90EE90;border: 50px solid #FA8072;width: 250px;height: 250px;border-radius: 60px;float: left;">
        <div class="verticalMidSon">border-radius: 60px;</div>
    </div>    
    <div class="verticalMid" style="background-color:#90EE90;border: 50px solid #FA8072;width: 250px;height: 250px;border-radius: 80px;float: left">
        <div class="verticalMidSon">border-radius: 80px;</div>
    </div>      

可以看到, border-radius: 為 40px 的時候,裡面綠色正方形邊框沒有影響, 60px 的時候已經有細微圓角了, 80px 的時候,就很明顯了;其實這裡的臨界線是 50px ,當 border-radius: 50px 的時候,圓心 O 正好在綠色正方形尖角上,是以 小于 50px ,内容就不會發生圓角,大于 50px 就會産生圓角,其實這個 50px 就是邊框的寬度呐,簡單來說可以這麼記憶,不過複雜情況就不止了,還要具體情況具體分析!

好了,這下原理我們是明白了,然後咱們來細究下 border-radius:

根據 w3c 的文檔,其實我們上面設定 border-radius:100px 等同于設定了四個屬性值(其實是八個屬性值):

border-top-left-radius: 100px; 
border-top-right-radius: 100px;
border-bottom-right-radius: 100px; 
border-bottom-left-radius: 100px;      

如果我們改成隻設定左上角的圓角邊框,那就是 border-top-left-radius: 100px; 乘機再和之前的畫圖放一起比較下,嘿嘿,看代碼,看圖:

border-radius 原理分析

代碼:

<div class="verticalMid" style="background-color:#90EE90;border: 50px solid #FA8072;width: 250px;height: 250px;border-top-left-radius: 100px;float: left;display: table;">
        <div class="verticalMidSon">圖1:border-top-left-radius: 100px;</div>
    </div>
    <img src="https://jimmystephen.github.io/cssSummary/border-radius/border-radius-origin3.bmp" alt="" />
    <div class="verticalMid"  style="background-color:#90EE90;border: 50px solid #FA8072;width: 250px;height: 250px;border-top-left-radius: 100px;float: left;">
        <div class="verticalMidSon">圖2:border-top-left-radius: 100px;</div>
        </div>
    <img src="https://jimmystephen.github.io/cssSummary/border-radius/border-radius-origin3.bmp" alt="" style="position: absolute;left:350px;opacity: 0.5"     />      

圖1是浏覽器實作效果,圖3是原理分析的畫圖結果,圖2就是把圖1圖3重疊了喲,,,你看一模一樣吧~~

border-top-left-radius: 100px; 這個既然大家了解了,那麼其他三個也是一樣的,當然,如大家所想,這裡屬性值除了可以用 px ,也可以用 em、% ,% 相對的是元素的實際寬高,也就是相當于 js 裡的 offsetWidth 和 offsetHeight ,包括了内容、内邊距 padding 、邊框等,當然不包括外邊距 margin ,這裡就不展示了;另外,至于四個值的縮寫嘛,不說大家也知道啦,不過像 border-radius: 30px 50px 60px; 這種 3 個值的,分别指向哪個角,自己測試吧,不做示例了

到這裡呢, border-radius 的正常用法我覺得已經說完了,但是細節還沒講完,用不到的看到上面就可以了,有興趣的可以繼續往下看,下面的用法可能也是有點奇葩,姑且稱之為奇技淫巧吧~~

可能有的人呢,就是不喜歡這種規整的圓角邊框,就喜歡一些不對稱的邊框,比如下圖三張圖:

border-radius 原理分析

代碼:

<div class="verticalMid" style="background-color:#90EE90;border: 50px solid #FA8072;width: 250pheight: 250px;border-top-left-radius: 50px 100px;;float: left;position: relative;">
        <div class="verticalMidSon">圖1:border-top-left-radius: 50px 100px;</div>
        <div style="width:50px;border:1px solid black;position: absolute;left:-50px;top:50px;"></div>
        <div style="height:100px;border:1px solid black;position: absolute;left:0px;top:-50px;"></div>
    </div>
    <div class="verticalMid" style="background-color:#90EE90;border: 50px solid #FA8072;width: 250pheight: 250px;border-top-left-radius: 100px 100px;;float: left;position: relative;">
        <div class="verticalMidSon">圖2:border-top-left-radius: 100px 100px;</div>
        <div style="width:100px;border:1px solid black;position: absolute;left:-50px;top:50px;"></div>
        <div style="height:100px;border:1px solid black;position: absolute;left:50px;top:-50px;"></div>
    </div>    
    <div class="verticalMid" style="background-color:#90EE90;border: 50px solid #FA8072;width: 250pheight: 250px;border-top-left-radius: 200px 100px;;float: left;position: relative;">
        <div class="verticalMidSon">圖3:border-top-left-radius: 200px 100px;</div>
        <div style="width:200px;border:1px solid black;position: absolute;left:-50px;top:50px;"></div>
        <div style="height:100px;border:1px solid black;position: absolute;left:150px;top:-50px;"></div>
    </div>      

結合上面的解釋,大家好好開動腦筋想想原理~~畫圓角邊框的圓心我都用實體黑線交叉标出來了,所有的圓角邊框原理,都是依據圓心和兩個半徑繪制的;

以圖1為例:border-top-left-radius: 50px 100px; 實際上就是:水準半徑 50px 的圓角邊框,垂直半徑 100px 的邊框;然後你再回去看看圖1的兩條黑線,橫着的就是确定 50px 的水準半徑,豎着的就是确定 100px 的垂直半徑;兩條半徑的交點,就是圓心;圓心和兩個半徑都有了(這裡畫的貌似是橢圓圓弧?恩,應該是!),那麼就開始畫圓角邊框了;原理就是這樣

上面一個圓角邊框就是 2 個屬性值,那麼如果四個角都設定,就是 8個 屬性值,,,我們平常用 border-radius: 50px 就表示 8 個值都一樣, border-radius: 50px 40px 30px 20px; 表示的是四個角,不過水準垂直半徑是相等的,是以平常我們也沒有看到上圖圖1這種奇怪的形狀,如果要水準垂直半徑不等的話,那就可能要 8 個參數了,那麼這個時候就要按照這種格式寫:

border-radius: 水準1 水準2 水準3 水準4/垂直1 垂直2 垂直3 垂直4;
border-radius: 水準簡寫/垂直簡寫;      

如果要把上面圖1 border-top-left-radius: 50px 100px; 拓展到四個角,那就有這麼兩種寫法:

border-radius: 50px 50px 50px 50px/100px 100px 100px 100px;
border-radius: 50px/100px;      

咱們來上個圖試試:

border-radius 原理分析

代碼:

<div class="verticalMid" style="background-color:#90EE90;border: 50px solid #FA8072;width: 250pheight: 250px;border-radius: 50px 50px 50px 50px/100px 100px 100px 100px;float: left;position: relative;">
        <div class="verticalMidSon">圖1:border-radius: 50px 50px 50px 50px/100px 100px 100px 100px;</div>
        <div style="width:50px;border:1px solid black;position: absolute;left:-50px;top:50px;"></div>
        <div style="height:100px;border:1px solid black;position: absolute;left:0px;top:-50px;"></div>
    </div>
    <div class="verticalMid" style="background-color:#90EE90;border: 50px solid #FA8072;width: 250pheight: 250px;border-radius: 50px/100px;float: right;position: relative;">
        <div class="verticalMidSon">圖2:border-radius: 50px/100px;</div>
        <div style="width:50px;border:1px solid black;position: absolute;left:-50px;top:50px;"></div>
        <div style="height:100px;border:1px solid black;position: absolute;left:0px;top:-50px;"></div>
    </div>      

如果沒有其他需求,到這裡, border-radius 好像也沒啥了,似乎也挺簡單的,然而最近發現一點稀奇的用法,有興趣的額可以繼續看看哦~~~

先說個簡單的,比如說, border-radius 還可以用來畫一些幾何圖形,嘿嘿,看圖!

border-radius 原理分析

代碼:

<div style="background-color:#90EE90;float:left;border: 10px solid #FA8072;width: 80px;height: 80pborder-radius: 0;">
    </div>
    <div style="background-color:#90EE90;float:left;border: 10px solid #FA8072;width: 80px;height: 80pborder-top-left-radius: 50px 50px;border-top-right-radius: 50px 50px;">    
    </div>
    <div style="background-color:#90EE90;float:left;border: 10px solid #FA8072;width: 80px;height: 80pborder-radius: 50px;">        
    </div>
    <div style="background-color:#90EE90;float:left;border: 10px solid #FA8072;width: 80px;height: 80pborder-top-left-radius: 100px 100px;">        
    </div>    
    <div style="background-color:#90EE90;float:left;border: 10px solid #FA8072;width: 80px;height: 80pborder-top-left-radius: 100px 100px;border-bottom-right-radius: 100px 100px;">        
    </div>    
    <div style="background-color:#90EE90;float:left;border: 10px solid #FA8072;width: 80px;height: 40pborder-top-left-radius: 50px 50px;border-top-right-radius: 50px 50px;">    
    </div>      

除了最後一張圖對原正方形高度做了修改,其他的都沒有修改原正方形尺寸,代碼都在上面哦;另,有其他細節不懂的,可以再看 W3Cplus:CSS3的圓角 border-radius

我覺得W3Cplus講的還是比較細的,就是沒說原理~~~

行文倉促,如有錯誤,歡迎批評指正~~~