搜尋

裁切路徑 clip-path

clip-path 是個特別的 CSS 樣式屬性,可以在網頁元素裡定義一出個「裁切形狀」,讓元素只顯示裁切形狀的內容,裁切形狀外圍都會變成透明背景,這篇教學會介紹如何使用 clip-path 裁切路徑。

這篇教學只會介紹非 SVG 元素的用法,但 clip-path 也有針對 SVG 元素的屬性值,可先從這篇文章了解更多:SVG 研究之路 (9) - Clipping and Masking

快速導覽:

CSS 教學 - 裁切路徑 clip-path

clip-path 裁切形狀

通常使用 clip-path 會先透過下列的 CSS 定義形狀函式,裁切出特定的形狀,定義形狀之後,套用 clip-path 的元素只有裁切形狀的部分會顯示,裁切形狀外圍都會變成透明背景

定義形狀函式 說明
circle(半徑 at 圓心座標) 圓形
ellipse(長、短軸半徑 at 圓心座標) 橢圓形
inset(上右下左的邊距 round 上右下左圓角半徑) 內置矩形
polygon(座標, 座標, 座標...) 多邊形 ( 最少三個座標 )

定義形狀時,需要注意下列幾點:

  • 單位通常使用 px%
  • 若單位使用 %x 座標和左右長度為元素寬度的百分比,y 座標和上下長度為高度的百分比

下方範例會呈現四種不同的裁切形狀,並分別呈現 px 和 % 單位的差異 ( 使用另外的 div 呈現元素的實際大小 ),從中可以看出不只背景顏色被裁切,連同元素內容顯示的文字都會一起被裁切。

線上展示:https://codepen.io/oxxo/pen/MWNdEzM

<!-- 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>

CSS 教學 - 裁切路徑 clip-path - 四種不同的裁切形狀分別呈現 px 和 % 單位的差異

撰寫座標或寬度時,如果是「inset 內置矩形」,可以在「數值相同」的情況使用「縮寫」寫法:

  • 「邊距」遵守上 右 下左順時鐘寫法,縮寫為上 左右 下」、「上下 左右」或「上右下左
  • 「圓角半徑」遵守左上 右上 右下 左下順時鐘寫法,縮寫為左上 右上左下 右下」、「左上右下 右上左下」或「四角

下方範例會使用縮寫的方式呈現同樣的結果。

線上展示:https://codepen.io/oxxo/pen/aberLPd

<!-- 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>

CSS 教學 - 裁切路徑 clip-path - inset 內置矩形縮寫寫法

clip-path 繪製正多邊形

下方範例會運用 clip-path 裡的 polygon 函式,搭配一些數學計算公式,就能繪製各種正多邊形,但使用 polygon 繪製正多邊形需要注意「採用順時針方向繪製」,避免線段重疊時,發生面積區域相減的狀況。

線上展示:https://codepen.io/oxxo/pen/oNKRGJB

<!-- 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>

CSS 教學 - 裁切路徑 clip-path - 繪製正多邊形

clip-path 正多邊形變換動畫

如果已經可以使用 clip-path 製作正多邊形,就能參考下方程式碼,搭配 animation 做出正多邊形變化的動畫效果,範例中使用的技巧是先繪製出正八邊形的「八個座標點」,依序將這些座標點改變座標並互相「重疊」,就能做出正多邊形變換動畫。

延伸閱讀:動畫 animation

線上展示:https://codepen.io/oxxo/pen/PoMvJXR

<!-- 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>

CSS 教學 - 裁切路徑 clip-path - 正多邊形變換動畫

clip-path 三角形組合動畫

下方範例會運用 clip-path 做出四個等腰三角形組成正方形,接著透過 animation 讓四個等腰三角形分別變成四個正三角形。

線上展示:https://codepen.io/oxxo/pen/KKOLXbE

<!-- 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>

CSS 教學 - 裁切路徑 clip-path - 三角形組合動畫

clip-path 工具推薦

如果要使用 clip-path 裡的 polygon 屬性值,不妨可透過「CSS clip-path maker」這個網站,快速產生裁切形狀所需的座標位置。

前往:CSS clip-path maker

CSS 教學 - 裁切路徑 clip-path - clip-path 工具推薦

小結

clip-path 是一個非常有趣的樣式屬性,雖然過去的瀏覽器對於這個樣式的支援度不高,但隨著科技的進步,目前大部分瀏覽器都已經支援,也可以開始使用這個樣式屬性,做出各種有趣的動畫效果!

意見回饋

如果有任何建議或問題,可傳送「意見表單」給我,謝謝~

CSS 教學

基本介紹

認識 CSS 開始使用 CSS CSS 語法規則 CSS 命名原則

CSS 選擇器

認識 CSS 選擇器 優先順序 ( 權重 ) 樣式繼承與聯集 元素選擇器 ID 和 Class 選擇器 屬性選擇器 文件結構選擇器 虛擬類別選擇器 ( 結構 ) 虛擬類別選擇器 ( 類型 ) 虛擬類別選擇器 ( 輸入 ) 虛擬類別選擇器 ( 行為 ) 虛擬類別選擇器 ( 超連結 ) 虛擬類別選擇器 ( 邏輯 ) 虛擬類別選擇器 ( 其他 ) 虛擬元素選擇器 群組與組合選擇器

數值與單位

關鍵字與文字數值 長度與角度單位 顏色單位 位置名稱與時間單位

變數與內容函式

變數 數學計算 文字與清單計數 生成內容與引號

顏色與濾鏡

色彩模型 漸層色 影像濾鏡

文字樣式

使用通用字型 使用外部字型 @font-face 定義字型 文字尺寸 常用文字樣式 文字換行 文字空白與 Tab 大小 文字行高與縮排 文字水平與垂直對齊 文字書寫方向 特殊文字樣式

元素容器

容器顯示類型 ( display ) 元素 display 對照表 盒子模型 ( Box Model ) 寬度與高度 內邊距 ( padding ) 外邊界 ( margin ) 邊框 ( border ) 邊框圓角 影像邊框 輪廓 ( outline ) 可見性與透明度 內容溢出與裁切

背景與陰影

背景顏色 背景圖 ( 定位、尺寸 ) 背景圖 ( 固定、重複 ) 背景圖 ( 多重背景、混合 ) 背景縮寫 ( background ) 容器陰影 ( box-shadow )

清單與表格

清單樣式 清單計數器 定義計數規則 表格基本樣式 表格邊框樣式 表格內容寬度與對齊

基本排版與定位

元素排版方式 浮動 ( float ) 浮動形狀 定位 ( position )

Flexbox 彈性排版

Flexbox 彈性盒子 Flexbox 對齊方式 Flexbox 彈性伸縮

Grid 網格排版

Grid 網格容器與格線 Grid 網格空間與命名 Grid 網格流向與間距 Grid 排列網格項目 Grid 項目對齊與順序

轉場與動畫

轉場 ( transition ) 轉場觸發事件 動畫 ( animation ) 動畫觸發事件 多重動畫的權重與順序

變形、裁切與遮罩

裁切路徑 ( clip-path ) 影像遮罩 ( mask )