Effective前端(3)用CSS畫一個三角形

會編程的銀豬

借用Effective之名,開始寫Effective系列,總結一些前端的心得。

三角形的場景很常見,打開一個頁面可以看到各種各樣的三角形:

由於div一般是四邊形,要畫個三角形並不是那麼直觀。你可以貼一張png,但是這種辦法有點low,或者是用svg的形式,但是太麻煩。三角形其實可以用CSS畫出來。如上圖提到,可以分為兩種三角形,一種是純色的三角形,第二種是有邊框色的三角形,先介紹最簡單的純色三角形。

1. 三角形的畫法

三角形可以用border畫出來,首先一個有四個border的div應該是這樣的:

然後把它的高度和寬度去掉,剩下四個border,就變成了:

再把border-top去掉,沒有了border-top就把上面的區域給裁掉了:

接下來,再讓左右兩邊的border透明,就是一個三角形了:

這裡是用了底部的border作為三角形,如果要取左邊border,同理只需讓上下兩個border顏色為transparent,同時不要右邊的border:

border-top: 50px solid transparent;nborder-bottom: 50px solid transparent;nborder-left: 50px solid #000;n

效果如下:

2.控制三角形的角度

上面畫的三角形是一個直角三角形,用得比較多的應該是等邊三角形,那麼怎樣畫一個等邊三角形呢?

首先,保持border-left和border-right的大小不變,讓border-bottom不斷變大,觀察下形狀是怎麼變的:

可以看到頂部的角度在不斷變小,換句話說三角形底邊長不變,而底邊的高在不斷地變大,因為border-bottom-width其實就是底邊的高:

然後再做第二個實驗,讓border-left不斷地變大,其它兩個border保持不變:

通過上下對比,看出border-left變大增加了左邊那條邊的長度。由此可以想到,如果右邊的border-width是0的話,那麼它將是一個直角三角形,並且直角在右下角:

即代碼為:

border-left: 60px solid transparent; nborder-right: 0 solid transparent; nborder-bottom: 40px solid #000;n

border-right為0,也就是border-right可以和width、height一樣不用設置,兩行代碼即可。其中border-left決定了底部直角邊的長度,而border-bottom決定了右邊直角邊的長度,剛好跟直觀的想法相反。明白這一點很重要。

同時,通過切換四個border的設置就可以控制直角邊在不同的位置,例如如果想要直角邊在右上角的話,那應該是設置border-left和border-top,讀者可以自行想像一下。

回到上面的問題,怎樣畫一個等邊三角形,等邊三角形的底邊的高是底邊的1/sqrt(2)倍。經過上面的分析可以知道,底邊是由border-left加上border-right的長度合起來的,而底邊的高是border-bottom,所以如果border-bottom-width是40px,那麼border-left和border-right的寬度都是40px * sqrt(2) / 2 ~= 28px,約等於28px。驗證一下:

確實畫出了一個等邊三角形。到這裡你可能會有一個疑問:上面取了約等,因為像素大小是不能為小數,但是上面是28個px,舍掉的小數相對很小,如果我畫的三角形本來就比較小,像那種下拉的右邊的三角形,捨去個小數影響比較大,這時候怎麼辦?其實這個問題本身是無解的,因為你要畫的區域就那麼小,要想畫個絕對等邊的三角形本身就有難度,就算用其它的辦法也會有一樣的困境。

3.畫一個有邊緣色的三角形

這種三角形很常見,特別是tip的提示框、聊天消息的框等:

上面實現是用了一個圖標字體,跟svg差不多,但是同於高度沒有那麼剛剛好,導致它看起來有點錯位了。如果用CSS畫,就不會有這種問題。

這種畫法其實很簡單,只是不容易想到——就是先畫一個深色的三角形,然後再畫一個同樣大小白色的三角形蓋在它上面,兩個三角形錯位2個像素,這樣深色三角形的邊緣就剛好露出一個像素。

首先畫一個深色的三角形:

<style>n.chat-msg {n width: 300px; n height: 80px; n border: 1px solid #ccc; n position: relative;n}n.chat-msg:before{n position: absolute; n left: -10px; n top: 34px; n border-top: 6px solid transparent; n border-bottom: 6px solid transparent; n border-right: 10px solid #ccc;n}n</style>n n<div class="chat-msg">hi,親</div>n

效果如下:

然後再畫一個白色的三角形蓋上去,錯位兩個像素

.chat-msg:before{n position: absolute; n left: -8px; n top: 34px; n border-top: 6px solid transparent; n border-bottom: 6px solid transparent; n border-right: 10px solid #fff;n}n

效果如下:

到這裡就說明完了,上面用的屬性都是CSS 2最基本的一些屬性,所以沒有兼容性問題。這個方法的缺點是沒辦法設置三角形的box-shadow的輪廓為一個三角形,所以用不了box-shadow。

除了畫一個三角形之外,還可以畫其它很多形狀,像五角形、愛心等等,詳見css-tricks,但是這種由於藉助了transform等屬性,所以兼容性沒有畫一個三角形的好,並且大小不好擴展,你要改它的大小,要麼你知道它畫的原理,然後一個個去改各個構成的屬性位置和大小,要麼用scale,用scale會有文檔流佔用空間不一致的問題。所以這種比較複雜的css畫法,實用性並不是很大,還不如用個圖標字體。

作者:會編程的銀豬

版權歸作者所有,轉載請註明出處


推薦閱讀:

【前端入門系列】HTML5動畫與動效(之五)
什麼是M站?
[一勺燴]最流行前端開發圖表顯示組件總結
如何免費製作一個H5微場景?

TAG:CSS3 | HTML5 | 前端开发 |