CSS clip-path の使い方

CSS clip-path の基本的な使い方について。基本シェイプを使った切り抜きや clip-source で SVG の clipPath 要素の定義を参照してクリッピングする方法、CSS clip-path ジェネレーター(Clippy)の使い方、geometry-box などについての覚書です。

作成日:2021年1月18日

CSS clip-path や mask-image の仕様などについては以下のサイトで確認することができます。

以下で clip-path や mask-image 関連のブラウザの対応状況を確認できます。

関連ページ:

clip-path

clip-path プロパティを使うと要素をクリッピング(切り抜いてその部分を表示)することができます。

clip-path プロパティでクリッピング領域を設定すると、クリッピング領域の内側の部分は表示され、外側の部分は非表示になります。

クリッピング領域の境界となる線をクリッピングパスと呼び、基本シェイプ(basic-shape)や SVG の clipPath 要素で定義されます。

参考:切り抜き

以下は clip-path プロパティで基本シェイプの関数 polygon( ) を使って三角形のクリッピングパスを定義して、画像(img 要素)をクリッピングする例です。

HTML
<div class="sample">
  <img class="cp-00" src="images/sample.jpg" alt="クリッピングサンプル">
</div>
CSS
.cp-00 {
  /* polygon( ) に3つの頂点の座標を指定して三角形のパスを定義 */
  clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
.sample img {
  max-width: 300px;
  width: 100%;
}

画像にクリッピングが適用されて以下のように表示されます。

クリッピングサンプル

clip-path プロパティは画像(img 要素)だけではなく、どのような要素にも適用できます。以下は div 要素にクリッピングを適用する例です。

HTML
<div class="cp-00 div-sample">
  <p>Sample</p>
</div>
CSS
.cp-00 {
  clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
.div-sample {
  width: 150px;
  height: 100px;
  position: relative;
  background-color: mediumpurple;
}
.div-sample p {
  color: white;
  position: absolute;
  bottom: 10px;
  left: 50px;
}

Sample

clip-path プロパティの構文と値

以下が clip-path プロパティの構文です。

clip-path : clip-source | [ basic-shape || geometry-box ] | none

以下のような指定が可能です。

clip-path : clip-source
SVG の clipPath 要素の定義を参照してクリッピング
clip-path : basic-shape
基本シェイプを定義してクリッピング
clip-path : basic-shape geometry-box または geometry-box basic-shape
basic-shape と geometry-box を両方指定する場合(※):
ジオメトリボックスを基準ボックスとして基本シェイプでクリッピング
clip-path : geometry-box
geometry-box だけを指定する場合(※):
ジオメトリボックスが生成する辺を切り抜きパスとしてクリッピング
clip-path : none
初期値。クリッピングパスは作成されない

(※)2021年1月の時点では geometry-box をサポートしていないブラウザ(Chrome など)もあります。そのため、基本シェイプとジオメトリボックスを一緒に指定すると、サポートされていないブラウザではクリッピングされないので注意が必要です。

clip-source
意味
URL クリップパスが定義されている SVG の clipPath 要素の id を url() 関数を使って指定します。
basic-shape 基本シェイプの指定
意味
inset() 矩形(四角形)を定義します。
circle() 正円を定義します。
ellipse() 楕円を定義します。
polygon() 多角形を定義します。
path() パスによる図形を定義します。(2021/01 時点では Firefox のみがサポート)

CSS Shapes Module Level 1(日本語訳)サポートされる図形

geometry-box キーワードによる基準ボックス
意味
content-box 要素の内容ボックス(内容辺に囲まれたボックス) shape-box
padding-box 要素のパディングボックス(パディング辺に囲まれたボックス) shape-box
border-box 要素のボーダーボックス(ボーダー辺に囲まれたボックス) shape-box
margin-box 要素のマージンボックス(マージン辺に囲まれたボックス) shape-box
fill-box オブジェクトの境界ボックス
stroke-box ストロークの境界ボックス
view-box 要素に最も近い SVG 表示域(ビューポート)が成すボックス。

基本シェイプでクリッピング

基本シェイプ(basic-shape)を使った切り抜きの方法です。

以下の例では次の画像(img 要素)を使います。

300px 225px

img 要素にクラスを指定して、そのクラスに対して clip-path を使ったスタイルを設定します。

HTML
<div class="bg">
  <img class="cp-inset00" src="images/sample.jpg" alt="クリッピングサンプル">
</div>

また、img 要素には以下のような基本的なスタイルを設定しています(以降の説明では省略)。

CSS
img {
  max-width: 300px;
  width: 100%;
}

img 要素を囲む div 要素には以下のようなスタイルを設定して背景色を指定して、切り抜いた部分の位置がわかりやすいようにしています。

.bg {
  width: 300px;
  background-color:#eee;
}
inset()

inset() は内側へオフセットされた矩形(四角形)を定義します。inset() を使うと矩形のシェイプを切り抜くことができます。

inset( length [ round ] )
意味
length 要素(正確には基準ボックス)の各端からの距離(オフセット)を単位付きの値または % で指定します。指定方法は margin などと同じで値を1〜4個まで半角スペースで区切って指定します。
  • 値が1つ:「上下左右」
  • 値が2つ:「上下」と「左右」
  • 値が3つ:「上」と「左右」と「下」
  • 値が4つ:「上」と「右」と「下」と「左」(時計回り)
round ボックスの角を丸くする(角丸にする)場合に角丸の半径の値を指定します。指定方法は border-radius の略式プロパティと同じです。
  • 値が1つ:全ての角の半径
  • 値が2つ:「左上と右下」と「右上と左下」
  • 値が3つ:「左上」と「右上と左下」と「右下」
  • 値が4つ:「左上」と「右上」と「右下」と「左下」(時計回り)

以下は inset() に値を1つ指定しているので、基準ボックスの上下左右の各端から同じ距離(30px)で切り抜きます。

CSS
.cp-inset01 {
  clip-path: inset(30px);
}
HTML
<div class="bg">
  <img class="cp-inset01" src="images/sample.jpg" alt="">
</div>
30px 30px 30px 30px 300px 225px

パーセントでの指定

内側への距離を値を1つだけ指定する際にパーセントを使用する場合、クリッピングする要素の縦横比が異なる場合は注意が必要です。

パーセントを使って上記と同じようにクリッピングするには、この例の場合は以下のようになります。

この例の場合、クリッピングする画像の縦横比が異なっているので、上下の辺から30pxの距離は 30/225*100 で約13.33%、左右の辺から30pxの距離は 30/300*100 で10% になります。

clip-path: inset(13.33% 10%);

また、クリッピングする対象の要素が伸縮する場合、パーセントで指定すれば伸縮にあわせて距離が変わりますが、絶対値の場合は伸縮しても距離は一定です。

以下はクリッピングする対象の画像の幅を300pxから400pxに変更した場合の例です。

  • clip-path: inset(30px) でのクリッピング:外側(半透明部分)
  • clip-path: inset(13.33% 10%) でのクリッピング:内側
30px 13.3% 30px 10% 400px 300px clip-path: inset(13.33% 10%); clip-path: inset(30px);

以下は基準ボックスの「上」「右」「下」「左」(時計回り)の端からそれぞれ 30px 40px 50px 60px の距離で切り抜き、round に値を1つ指定しているので、全ての角を半径 20px の角丸にします。

CSS
.cp-inset02 {
  clip-path: inset(30px 40px 50px 60px round 20px);
}

以下は距離をパーセントで指定して上記と同じようにクリッピングする例です。

.cp-inset02 {
  clip-path: inset(13.33% 13.33% 22.22% 20% round 20px);
  /*
  30/225 * 100 = 13.33%
  40/300 * 100 = 13.33%
  50/225 * 100 = 22.22%
  60/300 * 100 = 20%
  */
}
HTML
<div class="bg">
  <img class="cp-inset02" src="images/sample.jpg" alt="">
</div>
60px 40px 30px 50px

以下は基準ボックスの上下の端から 30px、左右の端から 50px で切り抜き、round に4つの値を指定して、「左上」「右上」「右下」「左下」の角をそれぞれ半径 10px 20px 30px 50px の角丸にします。

CSS
.cp-inset03 {
  clip-path: inset(30px 50px round 10px 20px 30px 50px);
}
HTML
<div class="bg">
  <img class="cp-inset03" src="images/sample.jpg" alt="">
</div>
50px 50px 30px 30px r=10 r=20 r=30 r=50

元の画像に重ねる

以下は元の画像(.bg-img)を配置し、その後にクリッピングした画像(.cp-inset04)を絶対配置して重ねる例です。

画像の親要素の div 要素には絶対配置の基準となるように position: relative; を指定し、クリッピングした画像には position: absolute; 及び top: 0; と left: 0; を指定します。

また、画像の違いがわかるように元の背景になる画像には不透明度を指定しています。

HTML
<div class="sample-over">
  <img class="bg-img" src="images/sample.jpg" alt="">
  <img class="cp-inset04" src="images/sample.jpg" alt="">
</div>
 .sample-over {
  max-width: 300px;
  position: relative;  /* 絶対配置の img 要素の基準とする */ 
}    
.bg-img {
  opacity: 0.4;
}
.cp-inset04 {
  position: absolute;  /* 絶対配置にして img 要素に重ねる */ 
  top: 0;
  left: 0;
  clip-path: inset(30px 50px round 10px 20px 30px 50px);
} 

余白の削除

クリッピングした要素の位置はそのままなので、切り抜いた部分を左上に配置するには内側へ指定したオフセット分をネガティブマージンで指定します。

CSS
.cp-inset05 {
  clip-path: inset(30px 50px round 10px 20px 30px 50px);
  margin: -30px -50px;
}
HTML
<div class="bg">
  <img class="cp-inset05" src="images/sample.jpg" alt="">
</div>
circle()

circle() は正円を定義します。circle() を使うと正円のシェイプを切り抜くことができます。

circle( shape-radius [at position ] )
意味
shape-radius 正円の半径を単位付きの値またはパーセントで指定します。 パーセントで指定する場合、要素(基準ボックス)に対しての比率になり、基準ボックスの[ 幅, 高さ ]から式[ √( 横幅の 2 乗 + 縦幅の 2 乗 ) ÷ √ 2 ]を基準に算出されます。
at position 円の中心を定義します。at に続けて円の中心の座標(半角スペース区切りのX座標とY座標)やキーワードを指定します。
  • 省略時の既定は center (基準ボックスの中心)になります。
  • position に指定するキーワードは
    • left | center | right (X軸方向)
    • top | center | bottom(Y軸方向)
    center 以外のキーワードでは一緒にオフセット値を指定することができます。

以下は circle() に円の半径 100px と中心 center を指定しているので、画像の中心から半径 100px で切り抜きます。

CSS
.cp-circle01 {
  clip-path: circle(100px at center);
} 

at position はこの例の場合、以下のように指定しても同じ結果になります。

clip-path: circle(100px at 150px 112.5px); /* 中心のX,Y座標を指定 */
clip-path: circle(100px at left 150px top 112.5px); /* キーワードとオフセット */
clip-path: circle(100px at 50% 50%); /* 中心座標をパーセントで指定 */
clip-path: circle(100px); /* 省略した場合は center */
HTML
<div class="bg">
  <img class="cp-circle01" src="images/sample.jpg" alt="">
</div>
112.5 (center) 150 (center) r=100px

半径をパーセントで指定

以下は円の半径をパーセントで指定した場合の例です。

この例の場合、幅が300px、高さが225pxなのでパーセントで指定する場合の基準値は以下になります。

√( 300 の 2 乗 + 225 の 2 乗 ) ÷ √ 2 = 265.16505

この値の50%なので半径は 265.16505 の半分の 132.58252px になります(多分)。

CSS
.cp-circle02 {
  clip-path: circle(50%); 
} 
HTML
<div class="bg">
  <img class="cp-circle02" src="images/sample.jpg" alt="">
</div>
112.5 (center) 150 (center) r=132.58px (50%) (300, 225)

以下は中心座標にキーワードとオフセットを指定する場合の例です。この場合、円の中心は右辺から 60px、上辺から 80p になります。

CSS
.cp-circle03 {
  clip-path: circle(120px at right 60px top 80px );
} 
HTML
<div class="bg">
  <img class="cp-circle03" src="images/sample.jpg" alt="">
</div>
80 240 r= 120px right 60px top 80px (300, 225) 60px 80px

パーセントで指定すると以下のようになります。

中心座標のX軸方向のオフセット60pxは 60/300*100 で 20%、Y軸方向のオフセット80pxは 80/225*100 で 35.56% になります。

半径は基準値が √( 300 の 2 乗 + 225 の 2 乗 ) ÷ √ 2 = 265.16505 なので、120/265.16505*100 で 45.25% になります。

clip-path: circle(45.25% at right 20% top 35.56% );

クリッピングを重ねる

以下は複数のクリッピングした要素を重ねる例です。

この例の場合、3つの circle() を使ってクリッピングした円形の要素を絶対配置で重ねています。

親要素の div 要素には絶対配置の基準となるように position: relative が指定されています。

CSS
.cp-circle04 {
  clip-path: circle(90px at center);
} 
.over-layer {
  position: absolute;
  top: 0;
  left: 0;
}
.cp-circle04a {
  clip-path: circle(40px at 70px 60px);
} 
.cp-circle04b {
  clip-path: circle(40px at 230px 60px);
} 
HTML
<div class="bg">
  <img class="cp-circle04" src="images/sample.jpg" alt="">
  <img class="cp-circle04a over-layer" src="images/sample.jpg" alt="">
  <img class="cp-circle04b over-layer" src="images/sample.jpg" alt="">
</div>
ellipse()

ellipse() は楕円を定義します。ellipse() を使うと楕円のシェイプを切り抜くことができます。

ellipse( shape-radius [at position ] )
意味
shape-radius 楕円のX軸半径とY軸半径を半角スペース区切りで、単位付きの値または % で指定します。 % で指定する場合、X軸半径とY軸半径はそれぞれ要素(基準ボックス)の幅と高さに対しての比率になります。
at position 楕円の中心を定義します。at に続けて楕円の中心の座標(半角スペース区切りのX座標とY座標)やキーワードを指定します。
  • 省略時の既定は center (基準ボックスの中心)になります。
  • position に指定するキーワードは
    • left | center | right (X軸方向)
    • top | center | bottom(Y軸方向)
    center 以外のキーワードでは一緒にオフセット値を指定することができます。

以下はX軸半径とY軸半径を50%にして at position は省略しているので at center を指定したのと同じことになります。

この例の場合、X軸半径50%は幅の半分なので150px、Y軸半径50%は高さの半分なので112.5px になります。

.cp-ellipse01 {
  clip-path: ellipse(50% 50%)
}  
HTML
<div class="bg">
  <img class="cp-ellipse01" src="images/sample.jpg" alt="">
</div>
center rx=50% (150px) ry=50% (112.5px) 300px 225px

以下は楕円の中心を右辺から(幅の)20%の位置、下辺から(高さ)の30%の位置に設定する例です。

この例の場合、X軸半径30%は90px、Y軸半径60%は135px になります。

.cp-ellipse02 {
  clip-path: ellipse(30% 60% at right 20% bottom 30%)
}  
HTML
<div class="bg">
  <img class="cp-ellipse02" src="images/sample.jpg" alt="">
</div>
center ry=60% rx=30% 20% 30%
polygon()

polygon() は多角形を定義します。polygon() を使うと多角形のシェイプを切り抜くことができます。

polygon( [fill-rule,] 頂点の座標1, 頂点の座標2, ... )
意味
fill-rule 塗り潰し方法を指定します。nonzero(初期値)または evenodd(領域が囲まれている線の本数が奇数の場合は塗り潰し、偶数の場合は塗らない)を指定できます。参考:SVG fill-rule プロパティ
頂点の座標 多角形の頂点のスペース区切りのX座標とY座標のペアをカンマ区切りで指定します。

以下は polygon() に3つの頂点の座標を指定して三角形のシェイプで切り抜く例です。

最後の頂点と最初の頂点は自動的に結ばれて図形が閉じます。

CSS
.cp-polygon01 {
  clip-path: polygon(5% 10%, 94% 10%, 48% 100%);
}  
HTML
<div class="bg">
  <img class="cp-polygon01" src="images/sample.jpg" alt="">
</div>
(5%, 10%) (94%, 10%) (48%, 100%)

以下は polygon() に7つの頂点の座標を指定してシェイプで切り抜く例です。

この例では(28%, 20%) の頂点から開始して、時計回りで順に頂点の座標を指定しています(どの頂点からでも、反時計回りでも同じ)。

CSS
.cp-polygon02 {
  clip-path: polygon(28% 20%, 47% 12%, 67% 22%, 76% 47%, 60% 81%, 35% 81%, 18% 49%);
}
HTML
<div class="bg">
  <img class="cp-polygon02" src="images/sample.jpg" alt="">
</div>
(28%, 20%) (47%, 12%) (67%, 22%) (76%, 47%) (60%, 81%) (35%, 81%) (18%, 49%)

以下は polygon() に一筆書きのように5つの頂点の座標を指定して星型のシェイプで切り抜く例です。

CSS
.cp-polygon03 {
  clip-path: polygon(45% 3%, 76% 99%, 2% 29%, 95% 29%, 15% 99%);
}
HTML
<div class="bg">
  <img class="cp-polygon03" src="images/sample.jpg" alt="">
</div>
1 (45%, 3%) 2 (76%, 99%) 3 (2%, 29%) 4 (95%, 29%) 5 (15%, 99%)

上記の場合、一筆書きのように頂点を指定しているため、パスが交わってパスの内側と外側が定義され fill-rule に evenodd を指定すると以下のような表示になります。

.cp-polygon03 {
  clip-path: polygon( evenodd, 45% 3%, 76% 99%, 2% 29%, 95% 29%, 15% 99%);
}

わかりやすいように背景色をピンクに変更しています。

CSS clip-path maker などのオンラインサービスを利用すると簡単に polygon() の値を生成することができます。

関連項目:CSS clip-path ジェネレーター

path()

path() はパスによる図形を定義します。SVG の path() 要素を使って定義した図形のシェイプを切り抜くことができます。

但し、2021/01 時点ではこの機能をサポートしていないブラウザもあります。

can i use | clip-path: path()

path( fill-rule, string )
意味
fill-rule 塗り潰し方法を指定します。nonzero(初期値)または evenodd(領域が囲まれている線の本数が奇数の場合は塗り潰し、偶数の場合は塗らない)を指定できます。
string SVG パスデータ文字列(有効な SVG path コマンドの文字列)。 パスを閉じるコマンド(z または Z)が無い場合には、暗黙的にパスは閉じられます。

以下は path() を使ってハートの形にクリッピングする例です。

SVG の path 要素の d 属性の値を使ってハート型のシェイプを定義しています。

この機能をサポートしていないブラウザではクリッピングはされず、画像そのままが表示されます。

CSS
.cp-path01 {
  clip-path: path("M120,32.48 c-31.48,-54.02 -120,-38.25 -120,29.44 0,46.61 55.71,94.27 120,158.08 64.3,-63.81 120,-111.47 120,-158.08 0,-67.92 -88.75, -83.06 -120,-29.44z");
}
HTML
<div class="bg">
  <img class="cp-path01" src="images/sample.jpg" alt="">
</div>

以下は上記で使用したパスコマンド(path 要素の d 属性の値)を使った SVG ファイルを表示する例です。

my-heart-240.svg(SVG ファイル)
<svg xmlns="http://www.w3.org/2000/svg" width="240" height="240" viewBox="0 0 240 240">
  <style type="text/css">
    .st0{fill:red;}
  </style>
  <!-- 以下の path 要素の d 属性の値を使用 --> 
  <path class="st0" d="M120,32.48 c-31.48,-54.02 -120,-38.25 -120,29.44 0,46.61 55.71,94.27 120,158.08 64.3,-63.81 120,-111.47 120,-158.08 0,-67.92 -88.75, -83.06 -120,-29.44z"/>
</svg>
<p><img src="images/my-heart-240.svg" width="50" height="50" alt="赤いハート"></p>

赤いハート

関連ページ:Photoshop で SVG

CSS clip-path ジェネレーター

Clippy は CSS clip-path を生成してくれるオンラインサービスで、簡単にクリッピングパスを作成することができます。

CSS clip-path maker : Clippy (https://bennettfeely.com/clippy/)

使い方はとても簡単で、右側にあるシェイプを選択して頂点の位置を変更したり削除できます。操作すると自動的にクリッピングパスのコードが生成されるのでそのコードをコピーするだけです。

画像の URL を指定すれば独自の画像で操作することができ、画像のサイズも指定することができます。

以下は独自の画像の URL を指定して、カスタムシェイプを選択した場合の例です。カスタムシェイプの場合は、自分で頂点をクリックして指定していきます。

頂点を3つ指定した時点でその部分をクリッピングされるので、「Show outside path」を On にしておくと便利です。

始点にマウスオーバーするとチェックが表示されるので、クリックすることでパスを閉じることができます。

パスを閉じた後では、頂点を選択して位置を変更したり、削除することができます。

パスが決定したら生成されたコードをコピーしてそのまま CSS に使用できます。

CSS
.cp-clippy01 {
  clip-path: polygon(26% 29%, 16% 40%, 23% 57%, 28% 79%, 46% 76%, 66% 80%, 65% 60%, 77% 29%, 63% 25%, 41% 11%);
}  
HTML
<div class="bg">
  <img class="cp-clippy01" src="images/sample.jpg" alt="">
</div>
(26%, 29%)

clip-source

clip-path プロパティでは SVG の clipPath 要素の定義を参照してクリッピングすることができます。

この場合、クリッピング(切り抜き)に使用するパスを SVG の clipPath 要素で別途定義し、ID を付与しておきます。そして clip-path プロパティで clipPath 要素の ID を url() 関数を使って参照します。

clip-path : url(clipPath 要素の ID)

以下の例では次の画像(img 要素)を使います。

300px 225px

clipPath 要素は svg 要素内で定義します。基本的には defs 要素の中で定義します。

以下の例では img 要素にクラスを指定して、そのクラスに対して clip-path を設定し、定義した clipPath 要素を参照します。

HTML
<svg class="svg"><!-- svg 要素自体はスタイルで非表示に -->
  <defs>
    <clipPath id="clip-path-x">
      <!-- 切り抜きに使用するパスを定義(以下は circle 要素を使った円の例) -->
      <circle cx="150" cy="112.5" r="100"/>
    </clipPath>
  </defs>
</svg>

<div class="bg">
  <img class="cp-source00" src="images/sample.jpg" alt="クリッピングサンプル">
</div>
CSS
.cp-source00 {
  clip-path: url(#clip-path-x);  /* clipPath 要素を参照 */
}

以降の例では img 要素と img 要素を囲む div 要素には以下のような基本的なスタイル及び背景色を指定しています(以降の説明では省略)。

CSS
img {
  max-width: 300px;
  width: 100%;
}

bg {
  width: 300px;
  background-color:#eee;
}

svg 要素にはクラス .svg を指定して、svg 要素自体の幅と高さを0にして position: absolute を指定しています。SVG の clipPath 要素自体は直接描画されることはありませんが、svg 要素を記述すると一定の領域が確保されてしまいます。svg 要素にインラインで height="0" width="0" style="position:absolute;" を指定することもできます。

CSS
.svg {
  position: absolute;
  width: 0;
  height: 0;
}

以下は clipPath 要素に id を指定してハート型のクリッピングパスを定義し、clip-path プロパティでその id を参照してクリッピングする例です。

HTML
<svg class="svg">
  <defs>
    <clipPath id="clip-path-heart">
      <!-- 切り抜きに使用するパスを path 要素を使って定義 -->
      <path d="M149.942,51.621C117.581-23.97,25.592-6.333,24.986,81.4c-0.335,48.186,43.8,66.2,73.191,85.46,28.5,18.682,48.778,44.238,51.956,55.117,2.721-10.659,25.311-36.938,51.69-55.639,28.843-20.448,73.526-37.277,73.191-85.461C274.4-7.074,180.816-20.955,149.942,51.621Z"/>
    </clipPath>
  </defs>
</svg>

<div class="bg"> 
  <img class="cp-source01" src="images/sample.jpg" alt=""> 
</div>
CSS
.cp-source01 {
  clip-path: url(#clip-path-heart);  /* clipPath 要素の id を参照 */
}

clipPath 要素(SVG)の使い方については以下を御覧ください。

HTML SVG の基本的な使い方 clipPath 要素

この例の clipPath 要素で定義しているハート型のパスは photoshop のシェイプを使って作成しています。

画像と同じサイズ(300x225)のカンバスにカスタムシェイプツールでハートを選択して、縦横比を保持して適当なサイズ(この例では 250x218)に描画します。

ファイルメニューから「書き出し」→「書き出し形式」を選択します。

ファイル設定で SVG を選択して書き出します。

書き出した SVG ファイルを例えば Chrome で開いてソースを表示させると以下のようになっています。

clipPath 要素には path 要素を指定します。但し、必要なのはパスを定義している d 属性(d="M149.94・・・51.621Z")のみで、id や data-name, class 属性は不要です。

フリー素材などの SVG ファイルも同様に path 要素の d 属性の値を使って clipPath 要素で切り抜きパスを定義できます。

heart.svg
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" height="225" viewBox="0 0 300 225">
  <defs>
    <style>
      .cls-1 {
        fill-rule: evenodd;
      }
    </style>
  </defs>
  <image id="背景" width="300" height="225" xlink:href="data:img/png;base64,・・・中略・・・VORK5CYII="/>
  <path id="ハートカード_1" data-name="ハートカード 1" class="cls-1" 
    d="M149.942,51.621C117.581-23.97,・・・中略・・・149.942,51.621Z"
  />
</svg>

以下は上記の SVG ファイル(heart.svg)を 50x50 ピクセルで表示する例です。

<p><img src="images/heart.svg" width="50" height="50" alt="黒いハートのアイコン"></p>

黒いハートのアイコン

テキストで切り抜き

clipPath 要素のパスの定義で <text> 要素を使えば、簡単にテキストで切り抜きすることができます。

text 要素では改行はできないので、2行にする場合は以下のように座標(x, y 属性)を指定します。

また、以下では circle 要素ellipse 要素の中心を重ねた図形も合わせて切り抜くようにしています。

HTML
<svg class="svg">
  <clipPath id="clip-path-hello">
    <!-- 切り抜きに使用するパスを text 要素を使って定義 -->
    <text x="10" y="100" font-size="90" font-family="Arial Black">Hello</text>
    <text x="10" y="190" font-size="90" font-family="Arial Black">World</text>
    <!-- circle 要素と ellipse 要素の中心を重ねた図形の定義 -->
    <circle cx="270" cy="30" r="15" />
    <ellipse cx="270" cy="30" rx="25" ry="5"/>
  </clipPath>
</svg>

<div class="bg"> 
  <img class="cp-source02" src="images/sample.jpg" alt=""> 
</div>
CSS
.cp-source02 {
  clip-path: url(#clip-path-hello); 
}

※2021/01 時点では iOS などでは text 要素や複数の図形は表示されないようです。

Hello World

use 要素で複製(再利用)

use 要素を使うと、他の要素を参照してその内容を指定した位置に描画(複製)することができます。

以下は id="circle1" を付与した circle 要素で半径30pxの円を描画して、その要素を use 要素で参照して複製する例です。

2つ目円(1つ目の use 要素)は、元の円からX軸方向70px、Y軸方向0pxの位置に描画されます。

HTML
<svg class="svg">
  <defs>
    <clipPath id="clip-path-circles">
      <circle id="circle1" cx="45" cy="40" r="30"/>
      <use href="#circle1" x="70" y="0"/>
      <use href="#circle1" x="140" y="0"/>
      <use href="#circle1" x="210" y="0"/>
      <use href="#circle1" x="0" y="70"/>
      <use href="#circle1" x="70" y="70"/>
      <use href="#circle1" x="140" y="70"/>
      <use href="#circle1" x="210" y="70"/>
      <use href="#circle1" x="0" y="140"/>
      <use href="#circle1" x="70" y="140"/>
      <use href="#circle1" x="140" y="140"/>
      <use href="#circle1" x="210" y="140"/>
    </clipPath>
  </defs>
</svg>
<div class="bg"> 
  <img class="cp-source02c" src="images/sample.jpg" alt="">
</div>
CSS
.cp-source02c {
  clip-path: url(#clip-path-circles); 
}

※2021/01 時点では iOS などでは複数の図形を使用すると表示されないようです。

(45,40) 30 70px 70px
transform 属性

svg 要素には transform 属性があり、transform 属性を使うと要素に対して移動(translate)、回転(rotate)、伸縮(scale)、傾斜(skew)の変形処理ができます。

以下は前述のハート型を定義した clipPath 要素の path 要素に transform 属性を使って30度の回転と0.7倍の縮小を適用する例です。

HTML の transform と異なり、SVG 要素の場合、変形の原点は SVG キャンバスの左上(0 0)になります。そのため、以下では rotate と scale を行う前に中心の座標(150, 112.5)を一度 translate(-150,-112.5) で左上(0 0)に移動してから適用しその後元の位置に戻しています(5行目)。

※ 複数指定した変換関数は右側から適用されます。

<svg class="svg">
  <defs>
    <clipPath id="clip-path-heart-tr">
      <path d="M149.942,51.621C117.581-23.97,25.592-6.333,24.986,81.4c-0.335,48.186,43.8,66.2,73.191,85.46,28.5,18.682,48.778,44.238,51.956,55.117,2.721-10.659,25.311-36.938,51.69-55.639,28.843-20.448,73.526-37.277,73.191-85.461C274.4-7.074,180.816-20.955,149.942,51.621Z" 
      transform="translate(150,112.5), scale(0.7), rotate(30), translate(-150,-112.5)"/>
    </clipPath>
  </defs>
</svg>

<div class="bg"> 
  <img class="cp-source01tr" src="images/sample.jpg" alt=""> 
</div>
.cp-source01tr {
  clip-path: url(#clip-path-heart-tr); 
}   

以下は元になるハート型のシェイプを別途 defs 要素内で定義して ID を付与し、use 要素で ID を参照して複製し、それぞれに異なる変形を適用する例です。

<svg class="svg">
  <defs>
    <path id="heart-shape" d="M149.942,51.621C117・・・中略・・・51.621Z" />
    <clipPath id="clip-path-heart-tr2">
      <use href="#heart-shape" transform="translate(150,112.5), scale(0.6), rotate(30), translate(-150,-112.5)"/>
      <use href="#heart-shape" transform="translate(60,170), scale(0.3), rotate(-30), translate(-150,-112.5)"/>
      <use href="#heart-shape" transform="translate(230,50), scale(0.2), rotate(60), translate(-150,-112.5)"/>
    </clipPath>
  </defs>
</svg>
<div class="bg"> <img class="cp-source01tr2" src="images/sample.jpg" alt=""> </div>
.cp-source01tr2 {
  clip-path: url(#clip-path-heart-tr2); 
}   

※2021/01 時点では iOS などでは複数の図形を使用すると表示されないようです。

絶対パスから相対パスへの変換

前述の例では clipPath 要素に定義した切り抜きに使用するパスは画像のサイズに合わせて絶対値で指定していますが、相対的な値を使って指定することもできます。

以下は Photoshop で作成したカンバスサイズが 128x128 ピクセルの蝶のシェイプの SVG ファイルです。path 要素のパスコマンド(d 属性)を見ると、M123.383,17.841 のように絶対値を使った指定になっています。

butterfly.svg
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128" viewBox="0 0 128 128">
  <defs>
    <style>
      .cls-1 {
        fill-rule: evenodd;
      }
    </style>
  </defs>
  <image id="背景" width="128" height="128" xlink:href="data:img/png;base64,iVBORw0KGgoAA...中略...QAAAAASUVORK5CYII="/>
  <path id="蝶_1" data-name="蝶 1" class="cls-1" d="M123.383,17.841c-2.182-11.607-18.177..中略...125.564,29.449,123.383,17.841Z"/>
</svg>

ファイルメニューから「書き出し」→「書き出し形式」を選択し、ファイル設定で SVG を選択して書き出します。

蝶のアイコン

以下は絶対値で指定された上記 SVG の path を使って clipPath を定義してクリッピングする例です。

<svg class="svg">
  <clipPath id="clip-path-butterflyA">
    <path class="st0" d="M123.383,17.841c-2.182...中略...17.841Z"/>
  </clipPath>
</svg>
<div class="bg"> 
  <img class="cp-source03" src="images/sample.jpg" alt=""> 
</div>
.cp-source03 {
  clip-path: url(#clip-path-butterflyA); 
}
300px 225px 128px 128px (64, 64)

以下のように transform 属性を使えば、切り抜きに使用するパスの大きさや位置などを調整することができます。

この例の場合、元の SVG のパスの中心(64, 64)を左上原点に移動してから2倍に拡大し、その後画像要素の中心(150, 112.5)に移動しています。

<svg class="svg">
  <clipPath id="clip-path-butterflyAT">
    <path class="st0" d="M123.383,17.841c-2.182...中略...17.841Z"
    transform="translate(150,112.5), scale(2),translate(-64,-64)" />
  </clipPath>
</svg>
<div class="bg"> 
  <img class="cp-source04" src="images/sample.jpg" alt=""> 
</div>
.cp-source04 {
  clip-path: url(#clip-path-butterflyAT); 
}

clipPathUnits 属性

デフォルトでは clipPath 要素の clipPathUnits 属性は userSpaceOnUse で、クリッピング領域の定義はユーザー座標系上(クリッピングが適用される要素の座標上)で行われます。今までの例では、クリッピングが適用される要素の座標上で絶対的な値を使ってパスを定義していました。

クリッピング領域の定義を相対的な値で行うには clipPathUnits 属性に objectBoundingBox を指定します。相対的な値は0〜1の間の数値を使って比率で指定します。

相対パスへの変換

最初から相対的なパスでクリッピング領域を定義していれば問題ありませんが、すでに絶対的な値で定義したパスを相対的な値に変換するのは大変です。

そこで以下のサイトを利用すれば、すでに絶対的な座標で作成したパスを相対パスへ変換することができます。但し、すべてのパスがうまく変換されるわけではないようなのと、完璧(?)に変換されるわけではないようです。

Convert SVG absolute clip-path to relative

関連項目:SVG の基本的な使い方/絶対パスから相対パスへの変換

以下は前述の蝶のパスを相対パスに変換した際のスクリーンショットです。

この例の場合、Remove offset にチェックを入れないとうまく変換できませんでした(余白のせい?)。

ページの下の方には、背景画像としてクリッピングする場合の CSS の値や HTML、SVG なども出力してくれます。

以下は相対パスに変換した値を使った例です。

clipPath 要素の clipPathUnits 属性には objectBoundingBox を指定する必要があります。

<svg class="svg">
  <!-- clipPathUnits 属性には objectBoundingBox を指定 -->
  <clipPath id="clip-path-butterflyR" clipPathUnits="objectBoundingBox">
    <path class="st0" d="M0.99,0.111 C0.971,0,・・・中略・・・ 0.99,0.111" />
  </clipPath>
</svg>
<div class="bg"> <img class="cp-source05" src="images/sample.jpg" alt=""> </div>
.cp-source05 {
  clip-path: url(#clip-path-butterflyR); 
} 

この例の場合、横長の画像にクリッピングを適用するので結果は以下のように横に広がったようになってしまいます。

以下は transform 属性を使って横幅を 0.85333倍(256/300)にして、Y軸方向に -0.03% 移動して絶対値での例に近づけてみた例です。

変換する際に Remove offset にチェックを入れ余白を削除しているためか、絶対的な値でのクリッピング結果と同じにするのは難しそうです。

<svg class="svg">
  <clipPath id="clip-path-butterflyR2" clipPathUnits="objectBoundingBox">
    <path class="st0" d="M0.99,0.111 C0.971,0,・・・中略・・・ 0.99,0.111"" 
        transform="translate(0.5,0.47), scale(0.85333, 1),translate(-0.5,-0.5)" />
  </clipPath>
</svg>

以下は絶対値を使ったパスでのクリッピング(最初の例)です。

geometry-box

「図形は CSS ボックスモデルに定義される(各種の)辺への参照として定義することもできる」とのことで、以下のジオメトリボックスキーワードを clip-path プロパティに指定して切り抜きができます。

例えば clip-path プロパティの値に margin-box を指定すればマージン辺に囲まれたボックスがクリッピングされます。また、基本シェイプ(basic-shape)と一緒に指定した場合はジオメトリボックスを基準ボックスとしてクリッピングされます。

geometry-box(ジオメトリボックス)キーワードによる基準ボックス
意味
content-box 要素の内容ボックス(内容辺に囲まれたボックス) shape-box
padding-box 要素のパディングボックス(パディング辺に囲まれたボックス) shape-box
border-box 要素のボーダーボックス(ボーダー辺に囲まれたボックス) shape-box
margin-box 要素のマージンボックス(マージン辺に囲まれたボックス) shape-box
fill-box オブジェクトの境界ボックス
stroke-box ストロークの境界ボックス
view-box 要素に最も近い SVG 表示域(ビューポート)が成すボックス。SVG のビューポートを作成する要素に viewBox 属性が指定されている場合、
  • ボックスの位置は viewBox 属性で定義された座標系の原点になります。
  • ボックスのサイズは viewBox 属性で定義された width、 height になります。

shape-box 値(content-box, padding-box, border-box, margin-box)による基準ボックスは SVG 要素では定義されず、その他の値(fill-box, stroke-box, view-box)は CSS レイアウトでは定義されないとのことです(キーワードによる基準ボックス)。

  • CSS layout box が関連付けされている要素では fill-box に対しては content-box になり、 stroke-box と view-box 対しては border-box になります。2021/01 時点でこのように動作するのは Safari のみでした。
  • CSS layout box が関連付けられていない要素(SVG の要素)では content-box と padding-box に対しては fill-box になり、 border-box と margin-box に対しては stroke-box になります。2021/01 時点でこのように動作するのは Safari のみでした。(geometry-box 値に対する使用値

参考になる関連事項:

以下は img 要素のマージン、ボーダー、パディングにそれぞれ 30px 指定した場合の例です。

HTML
<div class="gbox-wrapper"> 
  <img class="gbox" src="images/sample.jpg" alt="">
</div>
CSS
.gbox {
  margin: 30px;
  padding: 30px;
  border: 30px solid #F7D7DC; /* 薄いピンク色のボーダー */
  background-color: #D1EAFA; /* 薄い水色の背景色 */
  width: 300px;
  height: 225px;
  clip-path: none;
}

.gbox-wrapper {
  width: 360px;
  background-color:#eee;
}
300px 225px margin: 30px border: 30px padding: 30px 内容辺 パディング辺 ボーダー辺 マージン辺 img 要素(内容) div 要素(.gbox-wrapper)

以下のセレクトメニューでジオメトリボックスの値を指定して動作を確認することができます。

2021/01 時点では Safari のみが対応しています(Firefox は一部のみ、Chrome は機能しません)。

clip-path:

以下は svg 要素の rect 要素に clip-path プロパティを適用する例です。

HTML
<div style="max-width: 300px">
  <svg viewBox="0 0 300 225">
    <rect class="svg-gbox" x="15" y="15" width="270" height="195" 
          stroke-width="30" fill="#D1EAFA" stroke="#F7D7DC"/>
  </svg>
</div>
CSS
.svg-gbox {
  clip-path: none;
}

HTML(CSS)の border は要素を囲むように要素の外に描画されますが、SVG の stroke は要素の外形線を中心に内と外の両側に描画されます。

stroke-width: 30 (0,0) (300,225) (15,15) (285, 210) rect 要素の fill

以下のセレクトメニューでジオメトリボックスの値を指定して動作を確認することができます。

2021/01 時点では Safari のみが対応しています(Firefox は一部のみ、Chrome は機能しません)。

clip-path:

基本シェイプと併用

以下は基本シェイプ(basic-shape)と一緒にジオメトリボックスを指定する場合のサンプルです。

以下は初期状態ではジオメトリボックスを指定していません(2021/01 時点では Chrome でジオメトリボックスを一緒に指定すると、クリッピング自体が機能しません)。

HTML
<div class="gbox-wrapper"> 
  <img class="gbox2" src="images/sample.jpg" alt="">
</div>
CSS
.gbox2 {
  margin: 30px;
  padding: 30px;
  border: 30px solid #F7D7DC; /* 薄いピンク色のボーダー */
  background-color: #D1EAFA; /* 薄い水色の背景色 */
  width: 300px;
  height: 225px;
  clip-path: polygon(50% 0%, 0% 100%, 100% 100%) ;
}

.gbox-wrapper {
  width: 360px;
  background-color:#eee;
}
内容辺 パディング辺 ボーダー辺 マージン辺 img 要素(内容) div 要素(.gbox-wrapper) ボーダー:薄いピンク 背景色:薄い水色

以下のセレクトメニューでジオメトリボックスの値を指定して動作を確認することができます。

2021/01 時点では Safari のみが対応しています(Firefox は一部のみ、Chrome は機能しません)。

ジオメトリボックスの値:

clip-path アニメーション

CSS の transitionanimation を使って clip-path の値を変更することで、簡単にアニメーションを作成することができます。

また、Web Animation API を使えば CSS で作成したアニメーションを JavaScript で制御したり、clip-path アニメーションを JavaScript で設定することもできます。

関連ページ:JavaScript でアニメーション Web Animation API

以下の例では次のような HTML とスタイルを設定してあり、img 要素のサイズは 300 x 225 で表示しています。アニメーションを設定するための img 要素に付与するクラス名(.animation1 や .animation1 など)は実際にはそれぞれ異なりますが、 HTML の構成は同じなので HTML は省略します。

HTML
<div class="sample"> 
  <img class="animation" src="/images/sample.jpg" alt="">
</div>
CSS
.sample {
  margin: 50px 0;
}

.sample img {
  max-width: 300px;
  width: 100%;
}

以下は ellipse() のX軸半径の値を transition で変更して、マウスオーバーすると楕円から円にアニメーションする例です。

.animation1 {
  clip-path: ellipse(50% 50%);
  cursor: pointer;
  transition: .6s;
}
.animation1:hover {
  /* X軸半径を 37.5%  にすると真円になる */ 
  clip-path: ellipse(37.5% 50%);
}
マウスオーバーでアニメーション

以下は ellipse() の楕円の中心を transition で変更する例です。

.animation2 {
  clip-path: ellipse(50% 50% at left);
  cursor: pointer;
  transition: .6s;
}
.animation2:hover {
  clip-path: ellipse(50% 50% at center);
}
マウスオーバーでアニメーション

以下は inset() のオフセットと角丸の値を animation で変更して、マウスオーバーしている間アニメーションを繰り返す例です。

.animation3:hover {
  animation: animation03 1s ease-in-out infinite alternate both;
}
@keyframes animation03 {
  0% {
    clip-path: inset(0% round 10px);
  }
  100% {
    clip-path: inset(10% round 50%);
  }
}
マウスオーバーでアニメーション

以下は polygon() の頂点の座標の値を変更してアニメーションさせる例です。

※ polygon() のアニメーションでは変化させる際に、頂点の数は同じにします。

以下の例ではクリックしたらアニメーションを1回実行するように、JavaScript でクリックイベントを設定しています。

また、アニメーションはアニメーションを設定したクラスを JavaScript で追加するので、HTML ではアニメーション用のクラスは付与せず、JavaScript 側で操作します。

HTML
<div class="sample"> 
  <img id="animation_04" src="/images/sample.jpg" alt="">
</div>
CSS
#animation_04 {
  clip-path: polygon(0% 0%, 100% 0%, 50% 100%);
} 

/* JavaScript で追加するアニメーション用のクラス */
.animation4 {
  animation: animation04 2s 1 both;
}       
@keyframes animation04 {
  0% {
    clip-path: polygon(0% 0%, 100% 0%, 50% 100%);
  }
  20% {
    clip-path: polygon(0% 0%, 100% 50%, 0% 100%);
  }
  40% {
    clip-path: polygon(100% 0%, 100% 100%, 0% 0%);
  }
  60% {
    clip-path: polygon(0% 0%, 100% 50%, 50% 100%);
  }
  100% {
    clip-path: polygon(50% 100%, 0% 0%, 100% 0%);
  }
}

クリックでアニメーションを開始するように JavaScript の addEventListener でクリックとアニメーション終了のイベントを登録しています。

img 要素をクリックした際にアニメーションを設定したクラスを追加し、アニメーションが終了したタイミングでこのクラスを外します。

クラスの追加と削除(クラス操作)には classList を利用しています。

JavaScript
//イベントを登録する要素を取得
let img = document.getElementById("animation_04");
//要素のクラスのリスト(ライブオブジェクト)を変数に代入
let animation_04_class = img.classList;
 
//要素にイベントリスナーを登録  
img.addEventListener('click', () => {
  //クリックしたらアニメーションを設定したクラスを付加
  animation_04_class.add('animation4');
});   
//要素にアニメーション終了のイベントリスナーを登録
img.addEventListener('animationend', () => {
  //アニメーション終了イベント(animationend)でクラスを削除
  animation_04_class.remove('animation4');
});
クリックでアニメーション

以下も polygon() の頂点の座標の値を変更してアニメーションさせる例です。この例の場合も、前述の polygon() 同様、頂点の数(この場合は6)はアニメーションの変化において同じになってています。

CSS
.animation5 {
  clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
  animation: 4s animation05 infinite alternate ease-in-out;
}

@keyframes animation05 {
  from {
    clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
  }
  to {
    clip-path: polygon(99% 78%, 0 82%, 33% 96%, 100% 1%, 0 1%, 61% 99%);
  }
}

一見、複雑そうに見えるかも知れませんが、アニメーションに設定している内容は単純で、clip-path ジェネレーターを使うと簡単に作成できます。

この例の場合は、Clippy で最初に六角形を作成してそのコードを取得して from に設定し、適当に頂点を移動して生成されたコードを取得して to に指定しているだけです。

以下は circle() の半径と中心の座標の値を変更してアニメーションさせる例です。

この例では、不透明度(opacity)を適用した画像を配置し、その上に絶対配置で同じ画像を重ねて clip-path を適用しています。

HTML
<div class="sample"> 
  <img class="img-bg" src="/images/sample.jpg" alt="">
  <img class="animation6" src="/images/sample.jpg" alt="">
</div>
CSS
.sample {
  position: relative; /* 絶対配置の基準に */
}
.img-bg {
  opacity: 0.4;
}
.animation6 {
  position: absolute; 
  top: 0; 
  left: 0;
  clip-path: circle(30% at 47% 50%);
  animation: animation06 7s ease-in-out infinite alternate;
}
@keyframes animation06 {
  0% {
  clip-path: circle(5% at 100% 0);
  }
  50% {
  clip-path: circle(90% at 0 100%);
  }
  75% {
  clip-path: circle(40%);
  }
  100% {
  clip-path: circle(30% at 47% 50%);
  }
}

shape-outside

shape-outside プロパティに clip-path に指定した値と同じ値を指定することで、clip-path で切り抜いた要素の回りに後続のテキストを回し込むことができます。

※shape-outside はフロートした要素に適用するように設計されているため、必ず float を設定する必要があります。要素に float が設定されていない場合は無効となります。

以下は clip-path: circle(100px) で円形に切り抜いた img 要素に、float を設定し、shape-outside にも circle(100px) を指定してテキストを円の形状に回り込ませる例です。

HTML
<div class="sample bg"> 
  <img class="cp-so-circle" src="images/sample.jpg" alt="">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit... pariatur voluptatem.</p>
</div>
CSS
.cp-so-circle {
  clip-path: circle(100px);
  /* フロートを設定 */
  float: left;
  /* clip-path と同じ値を設定し、同じ形状のシェイプを作成 */
  shape-outside: circle(100px);
  /* 画像の位置を調整 */
  margin-left: -50px;
} 

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Placeat hic maiores rerum quae, adipisci minus consequuntur voluptatum amet libero veritatis itaque quidem nam repellat, eos voluptate dicta nulla pariatur voluptatem.

shape-outside プロパティや CSS Shapes(シェイプ)の詳細は以下を御覧ください。

CSS Shapes / shape-outside