レスポンシブ クリッピングに shape() を使用する

公開日: 2025 年 4 月 8 日

clip-path プロパティを使用すると、円、ポリゴン、SVG パスにクリップして要素の形状を変更できます。ただし、Chrome 135 と Safari 18.4 より前は、レスポンシブ ポリゴンと、SVG パスを使用してレスポンシブではない複雑な形状のどちらかを選択する必要がありました。新しい shape() 関数を使用すると、clip-path は要素をレスポンシブな非ポリゴン シェイプにクリップできます。

Browser Support

  • Chrome: 135.
  • Edge: 135.
  • Firefox: 148.
  • Safari: 18.4.

Source

旗の形を作成する

たとえば、clip-path: path()clip-path: shape() を使用してフラグの形状を作成する場合を比較します。

上部と下部に曲線がある緑色の旗の形。

旗の形は、上端と下端の境界線が直線や丸みを帯びた角ではなく、3 次ベジエ曲線であるため、厳密にはポリゴンではありません。

clip-path: path() を使用してフラグを作成する

この旗のような形状は、SVG パスを使用して表すことができます。

.flag {
  clip-path: path(
    "M 0 20 \
     C 25 0 75 40 100 20 \
     V 80 \
     C 75 100 25 60 0 80 \
     z");
}

SVG パスは、一連のパスコマンドです。

  1. 0, 20 に移動します。
  2. コントロール ポイント(25,0 と 75, 40)を使用して、100, 20 にカーブします。
  3. 縦線を 80 にします。
  4. コントロール ポイント(75,100 と 25,50)を使用して 0 から 80 まで曲線を描画します。
  5. パスを閉じます(0,20 への線)。

これにより、旗の形が描画されますが、すべての単位はピクセルです。SVG はこれらのピクセルをビューボックスにスケーリングできますが、常にシェイプ全体の幾何学的なスケールのように見えます。

たとえば、長方形全体を拡大縮小しつつ、曲線の高さと幅を 20px に維持したい場合、SVG では実現できません。

shape() を使用してフラグを作成する

shape() を使用して同じ結果を比較します。シェイプ関数は、SVG パス コマンドと同様の一連のコマンドを受け取ります。ただし、これらのコマンドは、任意の CSS 単位で CSS の長さとパーセンテージを受け入れます。

次の CSS は、フラグをパーセンテージ単位の shape() に変換します。

.flag {
  clip-path: shape(from 0% 20%,
     curve to 100% 20% with 25% 0% / 75% 40%,
     vline to 80%,
     curve to 0% 80% with 75% 100% / 25% 60%,
     close
  );
}

レスポンシブにする

CSS の長さの全範囲を使用できるため、各座標に使用する長さを選択できます。

たとえば、フラグ全体のサイズを要素のサイズに合わせて調整し、曲線の高さを一定に保つには、次のようにします。

.flag {
  clip-path: shape(from 0% 20px,
     curve to 100% 20px with 25% 0% / 75% 40px,
     vline to calc(100% - 20px),
     curve to 0% calc(100% - 20px) 
           with 75% 100% / 25% calc(100% - 40px),
     close
  );
}

カスタム プロパティとアニメーションを追加する

CSS でシェイプが定義されたので、カスタム プロパティを使用して高さを簡単に操作することもできます。

.flag {
  --wave-height: 40px;
  clip-path: shape(
    from 0px var(--wave-height),
    curve to 100% var(--wave-height) 
          with 25% 0px / 75% calc(var(--wave-height) * 2),
    vline to calc(100% - var(--wave-height)),
    curve to 0 calc(100% - var(--wave-height))
          with 75% 100% / 25% calc(100% - var(--wave-height) * 2),
    close
  )
}

@property ディスクリプタを使用して CSS プロパティをアニメーション化し、範囲を超えないようにクランプすることもできます。

@property --animated-wave-height {
  syntax: "<length>";
  inherits: false;
  initial-value: 40px;
}

@keyframes curve {
  from { --animated-wave-height: 0px; }
  to { --animated-wave-height: 180px; }
}

.flag {
  width: 600px;
  height: 400px;
  background: green;
  animation: curve 1s infinite alternate;
  --wave-height: calc(min(var(--animated-wave-height, 40px), 40%));
  clip-path: shape(
    from 0px var(--wave-height),
    curve to 100% var(--wave-height)
          with 25% 0px / 75% calc(var(--wave-height) * 2),
    vline to calc(100% - var(--wave-height)),
    curve to 0 calc(100% - var(--wave-height)) 
          with 75% 100% / 25% calc(100% - var(--wave-height) * 2),
    close
  )
}

デモを試す

Chrome 135 または Safari 18.4 では、clip-path: shape() を使用して作成されたアニメーションの旗の形をこちらの CodePen デモで確認できます。

概要

clip-path: shape() を使用すると、任意のレスポンシブなシェイプを使用して要素をクリップできます。これは以前は、円錐グラデーションや JavaScript で構築された SVG などの手法でのみ可能でした。

完全な構文については、仕様をご覧ください。

現時点では、clip-path でのみ機能します。将来的には、この種のシェイプを要素の枠線のシェイプを設定するために使用することを想定しています。これにより、長方形以外の表現方法がさらに増えるでしょう。