Summer Collection
上の画像の下の縁が、shape() で描いた曲線で切り抜かれています。
DEMO
上の画像の下の縁が、shape() で描いた曲線で切り抜かれています。
CODE
<div class="demo-stage shp-stage">
<article class="shp-card" id="shp-card">
<div class="shp-media" aria-hidden="true"></div>
<div class="shp-body">
<h3 class="shp-title">Summer Collection</h3>
<p class="shp-text">上の画像の下の縁が、shape() で描いた曲線で切り抜かれています。</p>
</div>
</article>
<button type="button" class="shp-btn" id="shp-btn" aria-pressed="false">アーチ形にする</button>
</div>
.shp-stage { position:relative; overflow:hidden; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:1rem; padding:2rem 1.25rem; background:#0B0B10; min-height:360px; }
.shp-card { width:100%; max-width:300px; border-radius:16px; overflow:hidden; background:#1A1A22; border:1px solid rgba(255,255,255,.1); }
.shp-media { height:150px; background:linear-gradient(135deg,#7B37A8,#D1177A 55%,#F59E0B);
/* 未対応のブラウザ向け:直線の斜め切り */
clip-path: polygon(0 0, 100% 0, 100% 80%, 0 94%); }
@supports (clip-path: shape(from 0 0, line to 100% 0, close)) {
.shp-media {
/* 同じ命令の並び(hline・vline・curve・curve)どうしなら、形が滑らかに変わる */
clip-path: shape(from 0 0, hline to 100%, vline to 82%,
curve to 50% 82% with 75% 100%, curve to 0 82% with 25% 64%, close);
animation: shp-wave 4s ease-in-out infinite alternate;
transition: clip-path .7s cubic-bezier(.22,1,.36,1);
}
.shp-card.is-arch .shp-media {
animation:none;
clip-path: shape(from 0 0, hline to 100%, vline to 70%,
curve to 50% 100% with 92% 100%, curve to 0 70% with 8% 100%, close);
}
}
@keyframes shp-wave {
to { clip-path: shape(from 0 0, hline to 100%, vline to 82%,
curve to 50% 82% with 75% 64%, curve to 0 82% with 25% 100%, close); }
}
.shp-body { padding:.4rem 1.1rem 1.2rem; }
.shp-title { margin:0 0 .35rem; color:#fff; font-size:1.05rem; }
.shp-text { margin:0; color:#C9C9D1; font-size:.8rem; line-height:1.7; }
.shp-btn { min-height:44px; padding:0 1.1rem; border:0; border-radius:10px; background:#D1177A; color:#fff; font:inherit; font-weight:600; font-size:.86rem; cursor:pointer; }
.shp-btn:focus-visible { outline:2px solid #fff; outline-offset:3px; }
.shp-btn[aria-pressed="true"] { background:#7B37A8; }
@media (prefers-reduced-motion: reduce) {
.shp-media { animation:none !important; transition:none !important; }
}
(function(){
var card = document.getElementById('shp-card');
var btn = document.getElementById('shp-btn');
if (!card || !btn) return;
btn.addEventListener('click', function(){
var arch = card.classList.toggle('is-arch');
btn.setAttribute('aria-pressed', String(arch)); /* ラベルは変えず、状態は aria-pressed で伝える */
});
})();
AI PROMPT
カード上部の画像の下の縁を、CSS の clip-path: shape() で描いた曲線で切り抜いたカードを作って。shape(from 0 0, hline to 100%, vline to 82%, curve to 50% 82% with 75% 100%, curve to 0 82% with 25% 64%, close) のように、左上から右上へ横線、右の辺を下へ、2本の2次ベジェ曲線(curve to 終点 with 制御点)で波を描いて閉じる。座標は全て % で書き、カードの幅が変わっても形が崩れないようにする。@keyframes で制御点の上下を入れ替えた同じ命令の並びの形へ4秒で行き来させ(alternate)、波がゆらぐように見せる(命令の種類と数が同じなら形が補間される)。ボタン(aria-pressed を付け、押した状態はラベルを変えずに背景色で示す)でカードに class を付け、アニメーションを止めて、同じ並びの命令で中央が下へふくらむアーチの形へ clip-path の transition(0.7秒)で変える。shape() はこの宣言を @supports (clip-path: shape(from 0 0, line to 100% 0, close)) の中に書き、外には polygon() で斜めに切った形を未対応ブラウザ向けに置く。prefers-reduced-motion: reduce の時はアニメーションと transition を無効化する。 Acceptance criteria: works with prefers-reduced-motion (animation disabled), zero console errors, zero layout shift
AIエージェントでの実装ガイド → Claude Code でWebアニメーションを実装する
BOOKS · PR · AMAZON
※当サイトはAmazonアソシエイトプログラムの参加者です。リンクから商品をご購入いただくと、当方に紹介料が発生します。
学びを止めない · AMAZONサブスク
※当サイトはAmazonアソシエイトプログラムの参加者です。リンクから商品をご購入いただくと、当方に紹介料が発生します。
CREATOR TOOLS · スクール(PR)
※本サイトはアフィリエイトリンクを含みます。リンク経由のご購入・お申し込みで運営者が紹介料を受け取る場合があります。
shape() は、clip-path などで使う形を、始点と「線を引く」「曲線を引く」といった命令の並びで書く CSS の関数です。MDN では path() と比べた利点として、普通の CSS の書き方で形を書けることと、% や rem、em などの単位が使えることを挙げています。path() は SVG のパスの文字列で書くため、単位が px に限られます。
当サイトの Glassmorphism Card は背景を磨りガラスのようにぼかす半透明のカード、Bento Grid は不揃いな大きさのタイルが順に現れるグリッド、Expandable Card は一覧のカードがその場から広がって詳細になる演出です。本ページはカードの縁そのものの形を変える別テーマです。
ヒーロー画像の下の波の縁、チケット風の切り欠き、吹き出しの形のように、これまで SVG や画像で作っていた形を CSS だけで書けます。% で書けるので画面の幅に合わせて形が伸び縮みし、同じ命令の並びで数値だけを変えれば、形から形への変化もアニメーションにできます。
path() と比べて何が便利ですか?
MDN の説明では、shape() は普通の CSS の書き方で形を書け、% や rem、em などの単位を使えます。path() は SVG のパスの文字列で書くため単位が px に限られ、要素の大きさが変わると形がずれます。% で書ける shape() なら、カードの幅に合わせて波の位置も一緒に伸び縮みします。
形を滑らかに変えるための条件はありますか?
変化の前と後で、命令の種類と数を揃えます。本実装はどの形も「hline・vline・curve・curve・close」の同じ並びで書き、数値だけを変えているので、アニメーションやトランジションで形が補間されます。MDN の互換性データ(browser-compat-data 2026-09-24 版)では、shape() は Chrome・Edge 135、Firefox 148、Safari 18.4 から使え、それより古いブラウザには @supports の外に書いた polygon() の形が表示されます。
コードは無料で使えますか?
はい。Motion LabのコードスニペットとAIプロンプトは、クレジット表記なしで自由に使えます。コピーしてそのままプロジェクトに利用できます。