CSS 切版之 clip-path:Bootstrap Vue Logo ?

Clement
5 min readApr 1, 2021

--

X: Bootsrap Vue 使用教學

O: 三角形切版、clip-path

先向因為看到 Boostrap Vue 或 Boostrap 而點進來的朋友說聲抱歉,這篇其實跟這兩個主題都沒有太大的關係,趕時間的話可以先行離開沒關係。

不過如果是看到 CSS 或直覺會和切板有關係而點進來的朋友,希望你會找到一些有趣的東西,這篇是一個學習筆記,不太算技術文章,可以配茶慢慢看。

最近因為在學 Vue.js ,在亂逛 Vue UI 框架的時候,點進去 Boostrap Vue 的網頁看看,突然發現他們家的 Logo 做得蠻有趣的:

  1. 三個三角形堆疊在一起
  2. 最靠近螢幕的三角形有一個向內凹的部分(或其實就是一個六邊形)
  3. 字母 B 在第二層的三角形上
  4. 每一個邊都有陰影
  5. 當 hover 到 container 的時候,三個三角形會有各自的動畫效果。

看一下開發者工具得知 Logo 元素是 <path>,推測可能是用 svg 來做的,說不定是設計師做的?但也沒關係啊,對於一個想要主宰視覺和畫面的人(誤)來說,這 Logo 看了就手癢,覺得自己用純 CSS 應該也做得出來。在 Codepen 來做一個看看,測試自己的能力到底如何。

結果就是徹底失敗。

失敗過程:

通常來說,同一個畫面、效果或是功能不會只有一種做法,必須依照當下的環境限制和需求來選擇透過不同的程式碼來達成。而要在畫面上畫出三角形,我其實也只會使用最基礎的(?)方式: pseudo element + border + position

.triangle {
width: 300px;
height: 300px;
position: relative;
}
.triangle::after {
content:'';
position: absolute;
border-top: 300px solid red;
border-right: 150px solid transparent;
border-left: 150px solid transparent;
}

這樣很簡單的就畫出一個倒三角形了。在畫面上看到的其實不是 .triangle本身,而是其偽元素::after的各border。至於怎麼調整border來達到你要的形狀,可以自己提整看看border長度或選擇不同border,應該就知道了(吧)。

不過反正問題來了:

無法繪製內凹六邊形的內凹部分

沒辦法,Boostrap Vue Logo 上的這個假三角形真六邊形,有點棘手。
原本嘗試再多用一個偽元素::before來把凹進去的地方用蓋的蓋掉,創造內凹六邊形的效果,然後再把background-color 換成和第二層三角形一樣。但總覺得有點麻煩,因為這樣之後要處理box-shadow 可能會有點問題。

虛心求教:

頭殼抱著燒了一陣子後,決定放下身段回到 Google 的懷抱,最後決定落腳在純 CSS 的作法:clip-path。可以先看一下純 CSS 的 clip-path 能做到什麼境界:

看過一次怎麼用 clip-path 畫圖之後就會覺得這根本在犯規了,以下整理 clip-path 用法,以便之後查詢。

.target {
width: 300px;
height: 300px;
background:#333;
/* 圓形:半徑 at 圓心座標X 圓心座標Y */
clip-path: circle(50% at 0% 0%);

/* 橢圓形:長(短)軸半徑 短(長)軸半徑 at 圓心座標 */
clip-path: ellipse(50% 20% at 150px 150px);

/* 三邊形: 右下座標, 頂點座標, 坐下座標 */
clip-path: polygon(0% 100%, 50% 0%, 100% 60%);

/* 四邊形:上座標, 右座標, 下座標, 左座標 */
clip-path: polygon(0% 0%, 50% 0%, 50% 50%, 0% 50%);

/* 五邊形:各頂點位置 */
clip-path: polygon(0% 0%, 50% 0, 70% 30%, 60% 60%, 20% 80%);

/* 六邊形:bootstrap-vue logo */
clip-path: polygon(0% 0%, 20% 0%, 50% 50%, 80% 0%, 100% 0%, 50% calc(8.66*30px))
}

這麼一來最棘手的 bootstrap-vue logo 部分就做好了,接下來剩下一些動畫要處理,我們透過改變toptransform: scale(),搭配transition來解決。然後再加上一些陰影,結果box-shadow 一寫下去就發現問題不單純了。因為clip-path幫你把元素外面的地方都剪掉了,所以自然看不到 box-shadow。心路歷程應該會和這篇很像。總之,我們使用filter: drop-shadow來做。至於box-shadowdrop-shadow 的比較再麻煩爬文,因為畢竟這篇主要聚焦在 clip-path

Bootstrap Vue on my Codepen

PS. 若是對clip-path不滿意也可以試試看transform: rotate() + overflow: hidden的做法。

參考文章:
Quick Tip: CSS Triangles
運用 clip-path 的純 CSS 形狀變換
單一 div 的正多邊形變換 ( 純 CSS )

--

--

Clement
Clement

Written by Clement

A web frontend developer’s clueless notes that might contain something about Angular, typescript or other frontend related subjects.

No responses yet