Takoyaki

Front-end Engineer

  1. Home
  2. Blog
  3. clip-path: shape() でセクションの境目を曲線にする — 凸・凹・波のパターン集

clip-path: shape() でセクションの境目を曲線にする — 凸・凹・波のパターン集

clip-path: shape() でセクションの境目を曲線にする — 凸・凹・波のパターン集

セクションの区切りを曲線にしたいとき、かなり迷いませんか?

きっと今までは画像を使ったりSVGで切り抜いてみたりしてきたかと思いますが…
なな、なんと!!!CSSの clip-path: shape() だけでできるようになりました。

この記事では、凸・凹・波の3パターンを「コピペで使えるコード + 考え方」のセットで解説します。

shape() の基本

shape() は、要素の切り抜き形状を線とカーブで自由に描ける関数です。

clip-path: shape(
  from 開始点,
  curve to 終点 with 制御点, /* カーブ(2次ベジェ) */
  line to 次の点,            /* 直線 */
  line to 次の点,            /* 直線 */
  close                     /* 始点に戻って閉じる */
);

ポイントは2つです。

  • %とpxを混ぜられる。「横位置は%、カーブの深さはpx」と書けるので、画面幅が変わってもカーブの深さが崩れません
  • カーブの形は 制御点(with のあとの座標)の置き方で決まります。ここさえ掴めば、以下のパターンは全部同じ理屈です

パターン① 凸カーブ — 上辺がゆるくふくらむ

.section {
  clip-path: shape(
    from 0 50px,
    curve to 100% 50px with 50% -50px,  /* 制御点を上(-50px)へ */
    line to 100% 100%,
    line to 0 100%,
    close
  );
}

図解の①→②→③→④の順に、時計回りで輪郭を一周しています。両端を 50px 下げてスタートし、制御点を中央の -50px(上方向)に置くと、カーブの頂点がちょうど要素の上端(0px)に来ます。2次ベジェの頂点は「両端と制御点のちょうど中間の高さ」に来る、と覚えておくと深さの計算がラクです。

パターン② 凹カーブ — 上辺がへこむ

.section {
  clip-path: shape(
    from 0 0,
    curve to 100% 0 with 50% 50px,  /* 制御点を下(50px)へ */
    line to 100% 100%,
    line to 0 100%,
    close
  );
}

パターン①と逆に、両端は上端(0)のまま、制御点を下(`50px`)へ。中央が 50px へこみます。凸と凹は「制御点を上に置くか下に置くか」だけの違いです。

パターン③ 波 — カーブを2つ連ねる

.section {
  clip-path: shape(
    from 0 25px,
    curve to 50% 25px with 25% -25px,  /* 前半は上へ(頂点は0px) */
    curve to 100% 25px with 75% 75px,  /* 後半は下へ(谷は50px) */
    line to 100% 100%,
    line to 0 100%,
    close
  );
}

curve to は何個でも連ねられます。前半のカーブは制御点を上、後半は下に置くと、なめらかなS字の波に。つなぎ目(50%地点)の高さを両カーブで揃えるのがコツです。

応用のヒント

- curveを足せば波は何個でも刻める: 区間を3等分して制御点を上→下→上と交互に置けば3連波に。刻むほど細かい波になります

- 下辺にも使える: line to 100% 100% の部分を curve to に変えれば、下辺も曲がります(上下で波をつなげると"リボン"のような帯にも)

- 深さの調整だけで表情が変わる: 上のコードのpx値をいじるだけ。

レスポンシブに強い理由

似たことは ellipse() でもできますが、`ellipse()` の半径は要素サイズ基準の%なので、コンテンツ量でセクションの高さが変わるとカーブの深さも変わってしまいます。`shape()` は深さをpxで固定できるため、スマホで高さが2倍になってもカーブはそのまま。可変高さのセクションでは shape() が安心です。

ブラウザ対応

shape()2026年2月にBaseline入りした新しめの機能です。古い環境も考慮する場合はフォールバックを記述しましょう。

参考:https://caniuse.com/wf-shape-function

.section {
  clip-path: ellipse(140% 100% at 50% 100%); /* 非対応環境向け */
}
@supports (clip-path: shape(from 0 0, close)) {
  .section {
    clip-path: shape(from 0 32px, curve to 100% 32px with 50% -32px,
                     line to 100% 100%, line to 0 100%, close);
  }
}

おわりに

境目を曲げるのに画像もSVGも要らず、CSS 1プロパティで完結します。制御点の置き方(上か下か・いくつ連ねるか)だけで凸・凹・波が全部作れるので、ぜひお手元で遊んでみてください。

X(@takoyaki_dayo_)でもこういう実装小ネタを流しています。よければフォローしてください!

Contact

ご依頼・ご相談はメールにて承っております。
お気軽にお問い合わせください。

k-takaishi[At mark]sakulabo1025.com

※[At mark]を@に変えて送信してください。