裁切路徑 clip-path
clip-path 是個特別的 CSS 樣式屬性,可以在網頁元素裡定義一出個「裁切形狀」,讓元素只顯示裁切形狀的內容,裁切形狀外圍都會變成透明背景,這篇教學會介紹如何使用 clip-path 裁切路徑。
這篇教學只會介紹非 SVG 元素的用法,但
clip-path
也有針對 SVG 元素的屬性值,可先從這篇文章了解更多:SVG 研究之路 (9) - Clipping and Masking
快速導覽:
clip-path 裁切形狀
通常使用 clip-path
會先透過下列的 CSS 定義形狀函式,裁切出特定的形狀,定義形狀之後,套用 clip-path
的元素只有裁切形狀的部分會顯示,裁切形狀外圍都會變成透明背景。
定義形狀函式 | 說明 |
---|---|
circle(半徑 at 圓心座標) |
圓形 |
ellipse(長、短軸半徑 at 圓心座標) |
橢圓形 |
inset(上右下左的邊距 round 上右下左圓角半徑) |
內置矩形 |
polygon(座標, 座標, 座標...) |
多邊形 ( 最少三個座標 ) |
定義形狀時,需要注意下列幾點:
- 單位通常使用
px
或%
。- 若單位使用
%
,x 座標和左右長度為元素寬度的百分比,y 座標和上下長度為高度的百分比。
下方範例會呈現四種不同的裁切形狀,並分別呈現 px 和 % 單位的差異 ( 使用另外的 div 呈現元素的實際大小 ),從中可以看出不只背景顏色被裁切,連同元素內容顯示的文字都會一起被裁切。
<!-- HTML 程式碼-->
clip-path: circle(50px at 50px 50px);
<div><div>oxxo</div></div>
clip-path: circle(50% at 50% 50%);
<div><div>oxxo</div></div>
clip-path: ellipse(50px 10px at 50px 40px);
<div><div>oxxo</div></div>
clip-path: ellipse(50% 10% at 50% 40%);
<div><div>oxxo</div></div>
clip-path: inset(10px 20px 30px 40px round 10px 20px 30px 40px);
<div><div>oxxo</div></div>
clip-path: inset(10% 20% 30% 40% round 10% 20% 30% 40%);
<div><div>oxxo</div></div>
clip-path: polygon(0 0, 200px 20px, 100px 150px);
<div><div>oxxo</div></div>
clip-path: polygon(0 0, 200% 20%, 100% 150%);
<div><div>oxxo</div></div>
<!-- CSS 程式碼 -->
<style>
body > div {
width: 200px;
height:150px;
border: 2px solid #000;
margin: 10px;
}
div div {
width: 100%;
height: 100%;
border: none;
font-size: 40px;
}
div:nth-of-type(1) div {
clip-path: circle(50px at 50px 50px);
background: #f55;
}
div:nth-of-type(2) div {
clip-path: circle(50% at 50% 50%);
background: #f55;
}
div:nth-of-type(3) div {
clip-path: ellipse(50px 10px at 50px 40px);
background: #090;
}
div:nth-of-type(4) div {
clip-path: ellipse(50% 10% at 50% 40%);
background: #090;
}
div:nth-of-type(5) div {
clip-path: inset(10px 20px 30px 40px round 10px 20px 30px 40px);
background: #f90;
}
div:nth-of-type(6) div {
clip-path: inset(10% 20% 30% 40% round 10% 20% 30% 40%);
background: #f90;
}
div:nth-of-type(7) div {
clip-path: polygon(0 0, 200px 20px, 100px 150px);
background: #f09f;
}
div:nth-of-type(8) div {
clip-path: polygon(0 0, 200% 20%, 100% 150%);
background: #f09f;
}
</style>
撰寫座標或寬度時,如果是「inset 內置矩形」,可以在「數值相同」的情況使用「縮寫」寫法:
- 「邊距」遵守「
上 右 下左
」順時鐘寫法,縮寫為「上 左右 下
」、「上下 左右
」或「上右下左
」。- 「圓角半徑」遵守「
左上 右上 右下 左下
」順時鐘寫法,縮寫為「左上 右上左下 右下
」、「左上右下 右上左下
」或「四角
」。
下方範例會使用縮寫的方式呈現同樣的結果。
<!-- HTML 程式碼-->
inset(10xp 20px 50px 20px round 10px 20px 50px 20px)
<div><div>oxxo</div></div>
inset(10px 20px 50px round 10px 20px 50px)
<div><div>oxxo</div></div>
inset(10px 50px 10px 50px round 10px 50px 10px 50px)
<div><div>oxxo</div></div>
inset(10px 50px round 10px 50px)
<div><div>oxxo</div></div>
inset(10px 10px 10px 10px round 10px 10px 10px 10px)
<div><div>oxxo</div></div>
inset(10px round 10px)
<div><div>oxxo</div></div>
<!-- CSS 程式碼 -->
<style>
body>div {
width: 200px;
height:150px;
border: 2px solid #000;
margin: 10px;
}
div div {
width: 100%;
height: 100%;
border: none;
font-size: 40px;
}
div:nth-of-type(1) div {
clip-path: inset(10px 20px 50px 20px round 10px 20px 50px 20px);
background: #f55;
}
div:nth-of-type(2) div {
clip-path: inset(10px 20px 50px round 10px 20px 50px);
background: #f55;
}
div:nth-of-type(3) div {
clip-path: inset(10px 50px 10px 50px round 10px 50px 10px 50px);
background: #090;
}
div:nth-of-type(4) div {
clip-path: inset(10px 50px round 10px 50px);
background: #090;
}
div:nth-of-type(5) div {
clip-path: inset(10px 10px 10px 10px round 10px 10px 10px 10px);
background: #f90;
}
div:nth-of-type(6) div {
clip-path: inset(10px round 10px);
background: #f90;
}
</style>
clip-path 繪製正多邊形
下方範例會運用 clip-path
裡的 polygon
函式,搭配一些數學計算公式,就能繪製各種正多邊形,但使用 polygon
繪製正多邊形需要注意「採用順時針方向繪製」,避免線段重疊時,發生面積區域相減的狀況。
<!-- HTML 程式碼-->
正三角形<div></div>
正方形<div></div>
正五邊形<div></div>
正六邊形<div></div>
正七邊形<div></div>
正八邊形<div></div>
<!-- CSS 程式碼 -->
<style>
div {margin: 10px;}
div:nth-of-type(1) {
width: 100px;
height: 87px;
background: #c00;
clip-path: polygon(0% 100%, 50% 0%,100% 100%);
}
div:nth-of-type(2) {
width: 100px;
height: 100px;
background: #069;
clip-path: polygon(0% 0%,100% 0%,100% 100%, 0% 100%);
}
div:nth-of-type(3) {
width: 162px;
height: 154px;
background: #095;
clip-path: polygon(0% 38.31%, 50% 0%,100% 38.31%,80.86% 100%,19.14% 100%);
}
div:nth-of-type(4) {
width: 200px;
height: 174px;
background: #f80;
clip-path:polygon(25% 0%, 75% 0%,100% 50%,75% 100%,25% 100%,0% 50%);
}
div:nth-of-type(5) {
width: 224px;
height: 218px;
background: #09c;
clip-path: polygon(50% 0%, 90.18% 19.72%,100% 64.22%,72.32% 100%,27.68% 100%,0% 64.22%,10.09% 19.72%);
}
div:nth-of-type(6) {
width: 242px;
height: 242px;
background: #f69;
clip-path: polygon(29.34% 0%, 70.66% 0%,100% 29.34%,100% 70.66%,70.66% 100%,29.34% 100%,0% 70.66%,0% 29.34%);
}
</style>
clip-path 正多邊形變換動畫
如果已經可以使用 clip-path
製作正多邊形,就能參考下方程式碼,搭配 animation
做出正多邊形變化的動畫效果,範例中使用的技巧是先繪製出正八邊形的「八個座標點」,依序將這些座標點改變座標並互相「重疊」,就能做出正多邊形變換動畫。
延伸閱讀:動畫 animation
<!-- HTML 程式碼-->
<div>oxxo</div>
<!-- CSS 程式碼 -->
<style>
div{
width: 115px;
height: 100px;
font-size: 45px;
text-align: center;
clip-path: polygon(0% 100%, 50% 0%,100% 100%,100% 100%,100% 100%,100% 100%,100% 100%,100% 100%);
animation-name: size, oxxo;
animation-duration: 5s;
animation-direction: alternate;
animation-timing-function: linear;
animation-iteration-count: infinite ;
}
@keyframes size{
5% {width: 115px;}
24% {width: 100px;}
43% {width: 105px;}
62% {width: 114px;}
81% {width: 103px;}
95%, 100% {width: 100px;}
}
@keyframes oxxo {
0%, 5% {
background: #c00;
clip-path: polygon(0% 100%,50% 0%,100% 100%,100% 100%,100% 100%,100% 100%,100% 100%,100% 100%);
}
24% {
background: #069;
clip-path: polygon(0% 100%,0% 0%,100% 0%,100% 100%,100% 100%,100% 100%,100% 100%,100% 100%);
}
43% {
background: #095;
clip-path: polygon(19.14% 100%,0% 38.31%,50% 0%,100% 38.31%,80.86% 100%,80.86% 100%,80.86% 100%,80.86% 100%);
}
62% {
background: #f80;
clip-path: polygon(25% 100%,0% 50%,25% 0%,75% 0%,100% 50%,75% 100%,75% 100%,75% 100%);
}
81% {
background: #09c;
clip-path: polygon(27.68% 100%,0% 64.22%,10.09% 19.72%,50% 0%,90.18% 19.72%,100% 64.22%,72.32% 100%,72.32% 100%);
}
95%, 100%{
background: #f69;
clip-path: polygon(29.34% 100%,0% 70.66%,0% 29.34%,29.34% 0%,70.66% 0%,100% 29.34%,100% 70.66%,70.66% 100%);
}
}
</style>
clip-path 三角形組合動畫
下方範例會運用 clip-path
做出四個等腰三角形組成正方形,接著透過 animation
讓四個等腰三角形分別變成四個正三角形。
<!-- HTML 程式碼-->
<div>O</div>
<div>X</div>
<div>O</div>
<div>X</div>
<!-- CSS 程式碼 -->
<style>
div{
position: absolute;
top: 50px;
left: 250px;
font-size: 30px;
box-sizing: border-box;
background: #c00;
}
div:nth-of-type(1){
padding: 27px 0 0 7px;
width: 50px;
height: 100px;
clip-path: polygon(0% 0%, 0% 100%, 100% 50%);
animation:a 2s infinite alternate;
}
div:nth-of-type(2){
padding: 0 0 0 40px;
width: 100px;
height: 50px;
clip-path: polygon(0% 0%, 100% 0%, 50% 100%);
animation:b 2s infinite alternate;
}
div:nth-of-type(3){
padding: 27px 0 0 22px;
left: 300px;
width: 50px;
height: 100px;
clip-path: polygon(0% 50%, 100% 0%, 100% 100%);
animation:c 2s infinite alternate;
}
div:nth-of-type(4){
padding: 10px 0 0 40px;
top: 100px;
width: 100px;
height: 50px;
clip-path: polygon(50% 0%, 100% 100%, 0% 100%);
animation:d 2s infinite alternate;
}
@keyframes a {
90%, 100% {
padding: 27px 0 0 40px;
left: 100px;
width: 100px;
height: 87px;
background:#09f;
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
}
@keyframes b {
90%, 100% {
padding: 27px 0 0 40px;
left: 200px;
width: 100px;
height: 87px;
background: #0a0;
clip-path: polygon(50% 0%, 100% 100%, 0% 100%);
}
}
@keyframes c {
90%, 100% {
left: 400px;
padding: 27px 0 0 40px;
width: 100px;
height: 87px;
background: #f09;
clip-path: polygon(50% 0%, 100% 100%, 0% 100%);
}
}
@keyframes d {
90%, 100% {
left: 300px;
top: 50px;
padding: 27px 0 0 40px;
width: 100px;
height: 87px;
background: #f90;
clip-path: polygon(50% 0%, 100% 100%, 0% 100%);
}
}
</style>
clip-path 工具推薦
如果要使用 clip-path
裡的 polygon
屬性值,不妨可透過「CSS clip-path maker」這個網站,快速產生裁切形狀所需的座標位置。
小結
clip-path
是一個非常有趣的樣式屬性,雖然過去的瀏覽器對於這個樣式的支援度不高,但隨著科技的進步,目前大部分瀏覽器都已經支援,也可以開始使用這個樣式屬性,做出各種有趣的動畫效果!
意見回饋
如果有任何建議或問題,可傳送「意見表單」給我,謝謝~