搜尋

CSS 裁切路徑 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 的元素只有裁切形狀的部分會顯示,裁切形狀外圍都會變成透明背景

CSS 函式 說明
circle() 圓形
ellipse() 橢圓形
rect() 四邊形
polygon() 多邊形
inset() 內縮邊距和圓角
xywh() 虛擬矩形
path() 路徑

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

  • 單位通常使用 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 屬性值可藉助「CSS clip-path maker」這個網站,快速產生裁切形狀所需的座標位置。

前往:CSS clip-path maker

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

下方範例會展示透過 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 使用 path 繪製不規則形狀

從「CSS 路徑 path」教學中可以知道,透過 CSS 的 path() 函式可以使用類似 SVG 的 path 路徑,而動畫 animation 和裁切路徑 clip-path 都能運用這些路徑做出特別的效果,舉例來說,先透過 Vectorpea 這套線上向量繪圖工具 ( 也可以自行使用 Illustrator ),使用「鋼筆工具」繪製一段路徑,繪製完成後儲存為 SVG 檔案,使用瀏覽器打開這個 SVG 觀察原始碼,在 d 屬性裡的就是路徑編碼

注意:

  • 檔案尺寸先不要設定太大,建議長寬使用 100px~300px 進行測試
  • 套用於 clip-path 的路徑必須是「封閉」路徑

CSS 教學 - 裁切路徑 clip-path - 觀察 SVG 的 path 編碼

下方範例會使用兩個自訂的路徑產生出兩個不規則形狀。

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

<!-- HTML 程式碼-->
<div class="a"></div>
<div class="b"></div>

<!-- CSS 程式碼 -->
<style>
  div {
    border: 1px solid #000;
    width: 200px;
    height: 200px; 
    float: left;
    margin: 5px;
    background: repeating-linear-gradient(
      orange 0%,  orange 10%,
      black 10%, black 20%);
  }
  .a {  
    clip-path: path("m97 47c0 0-5.1-32.4-40-24-34.9 8.4-43.3 38.1-26 75 17.3 36.9 83.2 79.2 83.2 79.2 0 0 1.6-47.3 41.1-51.5 59.4-6.3-17.9-33.5-33.2-42.5-15.3-8.9 48.2-93.5-25.1-36.2z");
  }
  .b {
    clip-path: path("m96 161c-36.9-17.3-56.4-25-70-51-13.6-26-12-52.2 2-66 14-13.8 50.2-22.6 66 16 18.9-41.4 56.7-50.8 80-24 23.3 26.8-0.4 92.5-31 115-30.6 22.5-10.1 27.3-47 10z");
  }
</style>

CSS 教學 - 裁切路徑 clip-path - clip-path 使用 path 繪製不規則形狀

小結

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

意見回饋

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

CSS 教學

基本介紹

認識 CSS 開始使用 CSS CSS 語法規則 CSS 命名原則 CSS 常用樣式屬性

CSS 選擇器

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

數值與單位

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

規則與定義

變數 ( Variables ) 媒體查詢 ( @media ) 容器查詢 ( @container ) 自訂屬性值 ( @property ) 匯入樣式 ( @import ) 分層優先順序 ( @layer )

函式類型

數學計算 文字與清單計數 形狀與線段 路徑 ( path ) 生成內容與引號

顏色與濾鏡

顏色單位 色彩模型 漸層色 影像濾鏡 ( filter ) 背景濾鏡 ( backdrop-filter ) 混合模式 ( mix-blend-mode )

文字與段落

設定字型 ( font-family ) 使用外部字型 定義字型 ( @font-face ) 文字尺寸 文字樣式 ( 常用 ) 文字樣式 ( 其他實用 ) 文字樣式 ( 特殊用途 ) 文字換行 文字空白與 Tab 大小 文字行高與縮排 文字水平與垂直對齊 文字書寫方向 文字自動分欄

元素容器

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

背景與陰影

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

清單與表格

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

基本排版與定位

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

Flexbox 彈性排版

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

Grid 網格排版

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

轉場與動畫

轉場 ( transition ) 轉場觸發事件 動畫 ( animation ) 自訂動畫路徑 ( offset ) 動畫觸發事件 多重動畫的權重與順序

變形、裁切與遮罩

裁切路徑 ( clip-path ) 影像遮罩 ( mask ) 物件填滿方式與定位 轉換函式 ( transform ) 平移、旋轉與縮放 3D 轉換與透視 3D 正多面體

視窗與使用者行為

捲軸樣式 ( scrollbar ) 滑鼠游標圖示 ( cursor ) 滑鼠事件 ( pointer-events ) 使用者選取 ( user-select ) 捲動行為 ( scroll、overscroll )

範例效果

CSS 圓餅圖 CSS 跑馬燈 Google 載入動畫 漸層色的轉場與動畫 電子時鐘數字 不規則形狀動畫