CSS clip-path:SVGの複雑さなしにカスタム形状を作る
📷 Magicle Studio / PexelsCSS clip-path:SVGの複雑さなしにカスタム形状を作る
ポリゴン、円、楕円、カスタム形状 — ビジュアルジェネレーターを使ってクリエイティブなCSSレイアウトをclip-pathで構築。SVGの知識不要。
六角形アバターを初めて目にした時
ゲームのリーダーボードで六角形のユーザーアバターを見た時、思わず目が止まりました。円形ではなく — 六角形。6つの辺。最初はカスタムPNGマスクかcanvasトリックを使っているに違いないと思いました。実は、6行のCSSだったのです。
それが clip-path との出会いで、Webデザインにおける形状の考え方が根本から変わりました。以前は「形状」といえばborder-radius、SVG、または画像を意味していました。今ではブラウザ自体がカッティングツールになっています。
簡単な歴史:現在に至るまで
clip-path がCSSプロパティになる以前、非矩形の形状を作るには苦労しました。SVGの clipPath 要素を使ってCSSから参照することができましたが、完全に異なる構文でマークアップの別の部分に形状を定義する必要がありました。あるいは、overflow: hidden と巧みなポジショニングとborder-radiusハックを使う方法もありましたが、丸い形状しか得られず、真に角張ったや任意の形状は作れませんでした。
CSS clip-path プロパティはこれを標準化しました。SVGを扱う代わりに、CSSに直接形状定義を書きます。ブラウザがマスキングを行います。以前のアプローチがいかに多くの時間を無駄にしていたか、後から気づかされる機能の一つです。
形状関数の解説
polygon() — 主役
polygon() が最もよく使われます。形状の頂点を定義する座標ペアのリストを取ります。デフォルトでは、座標は要素の幅と高さのパーセンテージです。
基本的な三角形:
.triangle {
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
上中央、左下、右下と読みます。3つのポイントで1つの三角形。
平行四辺形(対角線セクション区切りに最適):
.parallelogram {
clip-path: polygon(10% 0%, 100% 0%, 90% 100%, 0% 100%);
}
六角形 — clip-pathの旅を始めたきっかけの形状:
.hexagon {
clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
}
6つのポイント、6組の座標ペア。それだけです。
ポイントが多くなるほど構文は冗長になりますが、これがビジュアルジェネレーターが非常に便利な理由です。例えば星形の頂点を手動で計算するには三角関数が必要で、手でやりたくはありません。
5角星の参考例:
.star {
clip-path: polygon(
50% 0%, 61% 35%, 98% 35%, 68% 57%,
79% 91%, 50% 70%, 21% 91%, 32% 57%,
2% 35%, 39% 35%
);
}
10組の座標ペア。手動で入力したくないものです。
circle() — シンプル、柔軟性は低い
.avatar {
clip-path: circle(50%);
}
半径50%の円に要素をクリップします — border-radius: 50% と実質同じですが、レイアウトに影響しません。中心点も指定できます:
.off-center-circle {
clip-path: circle(40% at 60% 50%);
}
正直なところ、シンプルな円形画像には border-radius の方がほとんどの場合優れています。clip-path: circle() が有効なのは、他のclip-path効果と組み合わせる必要がある場合や、アニメーションさせたい場合です。
ellipse() — 円の細長いいとこ
.ellipse-crop {
clip-path: ellipse(60% 40% at 50% 50%);
}
最初の2つの値は水平と垂直の半径です。楕円形の画像クロップやレンズフレアスタイルの形状に便利です。
inset() — 過小評価された機能
あまり注目されませんが、inset() は各辺からのインセット値で定義された矩形領域に要素をクリップします — パディングの逆のようなものです:
.inset-crop {
clip-path: inset(10px 20px 10px 20px);
/* 上 右 下 左 */
}
インセット矩形にborder-radiusを追加することもできます:
.rounded-inset {
clip-path: inset(10% round 12px);
}
inset() が真価を発揮するのはカードの切り欠き効果 — カードの角が「打ち抜かれた」ように見えるデザインです。標準CSSでは難しいですが、inset() とクリエイティブな背景を組み合わせれば簡単です。
実際のユースケース
斜めのヒーローセクション区切り
ヒーローセクションとその下のコンテンツの間の傾いたセパレーターはどこでも見られます。その方法はこちら:
.hero {
clip-path: polygon(0 0, 100% 0, 100% 85%, 0 100%);
}
これはヒーローの下端を角度でクリップし、対角線カットを作ります。その下のコンテンツは自然に流れ込みます。
六角形ユーザーアバター
定番。img タグに直接適用:
.avatar-hex {
width: 120px;
height: 120px;
clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
object-fit: cover;
}
object-fit: cover により、クリッピング前に画像がスペースを埋めます。これがないとレターボックスになります。
角度のあるカード装飾
右下角がクリップされたカード — 洗練されたタッチ:
.notched-card {
clip-path: polygon(0 0, 100% 0, 100% calc(100% - 20px), calc(100% - 20px) 100%, 0 100%);
}
注意すべき2つの落とし穴
落とし穴1:clip-pathがbox-shadowを消す
初めて試す時にほぼ全員が引っかかります。カードにシャドウを追加し、対角線カットのためにclip-pathを適用すると、シャドウが消えます。clip-path は形状境界外のすべてをクリップするためです — 要素のボックス外にレンダリングされるシャドウも含みます。
修正策は filter: drop-shadow() です:
/* これはクリップされる */
.broken {
clip-path: polygon(0 0, 100% 0, 100% 85%, 0 100%);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
}
/* これは正しく機能する */
.fixed {
filter: drop-shadow(0 8px 24px rgba(0, 0, 0, 0.2));
clip-path: polygon(0 0, 100% 0, 100% 85%, 0 100%);
}
filter: drop-shadow() はコンポジット後に適用され、実際の可視形状のアウトラインに従います。トレードオフとして、インセットシャドウや複数シャドウレイヤーはサポートしていませんが、クリップされた要素のシャドウには正しいツールです。CSS Box Shadowジェネレーターでシャドウを設計し、値を変換することができます。
落とし穴2:ホバーとクリックエリアもクリップに従う
論理的に考えれば当然ですが、多くの人が驚きます。クリップされた領域は視覚的にも機能的にも消えます。マウスイベントはクリップされたエリアでは発生しません。ユーザーがクリックしようとする角をデザインがクリップしているなら、そのクリックは登録されません。
ほとんどの場合、視覚的な装飾をクリップしているので問題ありません。しかし複雑な形状のインタラクティブ要素では、ヒットエリアを慎重にテストしてください。
clip-pathのアニメーション(と機能しない場合)
良いニュース:clip-path はアニメーション可能です。ブラウザは2つのポリゴン形状をスムーズに補間できます:
.btn {
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
transition: clip-path 0.3s ease;
}
.btn:hover {
clip-path: polygon(0 0, 100% 0, 85% 100%, 0 100%);
}
これはホバー時に矩形ボタンが対角線カットの角を持つようにアニメーションします。クリーンで滑らか、JavaScriptなし。
悪いニュース:同じ形状関数で同じポイント数の間でのみアニメーション可能です。circle() から polygon() へのトランジションはハードスナップになります。異なるポイント数を持つ2つのポリゴン間のトランジションも失敗します。
レスポンシブなclip-path
clip-pathはレスポンシブに機能しますか?はい、パーセンテージベースの値を使用すれば可能です。
/* これは正しくスケールする */
.responsive-diagonal {
clip-path: polygon(0 0, 100% 0, 100% 90%, 0 100%);
}
clip-pathの固定ピクセル値はスケールしません:
/* 小画面では見た目が悪くなる */
.broken-responsive {
clip-path: polygon(0 0, 800px 0, 800px 90%, 0 100%);
}
流体コンテナ内にある形状にはパーセンテージを使用してください。特定の調整には calc() とパーセンテージを組み合わせられます:
.notched {
clip-path: polygon(0 0, 100% 0, 100% calc(100% - 30px), calc(100% - 30px) 100%, 0 100%);
}
ジェネレーターの活用
ポリゴン座標を手動で入力するのは苦痛です。ビジュアルclip-pathジェネレーターはワークフローを完全に変えます — プレビューのハンドルをドラッグし、リアルタイムで形状を確認し、見た目が良くなったらCSSをコピーします。
最大限活用するために:
-
プリセットから始める — ほとんどのジェネレーターには三角形、六角形、平行四辺形、星などの一般的な形状が含まれています。プリセットから始めてハンドルをドラッグする方がゼロから構築するより速いです。
-
実際のコンテンツでプレビューを確認 — 実際のコンテンツに近いプレースホルダー画像や色付きのdivでジェネレートします。形状はソリッドカラーと写真では全く異なって見えます。
-
デスクトップとモバイル両方の幅を確認 — 浅い角度の形状はデスクトップでは優雅に見えても、スマートフォンでは窮屈に見えることがあります。
-
必要なものだけコピー — ジェネレーターは完全な
clip-pathプロパティを提供します。filter: drop-shadow()も必要な場合は両方一緒に貼り付けます。
clip-pathと他のCSSツールの組み合わせ
clip-path は実際のプロジェクトで単独で使われることは少ないです。一般的な組み合わせ:
-
CSSグラデーション:グラデーション背景をポリゴンにクリップして幾何学的な装飾セクションを作ります。グラデーションが最初にレンダリングされ、次に形状がクリップします。
-
CSS Flexbox:Flexboxはクリップされた要素の周りのレイアウトを処理します。clip-pathはドキュメントフローに影響しません — 要素はレイアウト内で元の矩形を占有し続けます。
-
CSS Box Shadow:ここでシャドウ値を設計し、クリップされた要素に適用する際には
filter: drop-shadow()構文に変換します。
ブラウザサポート
基本的な clip-path 形状関数 — polygon()、circle()、ellipse()、inset() — は最新ブラウザで確実にサポートされています。Chrome、Firefox、Safari、Edgeはすべてプレフィックスなしでサポートしています。
問題が生じる場合:
- 古いiOS Safari(13.4以前)は基本形状に
-webkit-プレフィックスが必要でした - 非常に古いAndroid WebViewバージョンは複雑なポリゴンパスに問題がある場合があります
- SVGベースの
clip-path: url(#myClip)は古い環境向けのより良いレガシーカバレッジを持ちます
まとめ
clip-path は一度使いこなすと、ほぼ強力すぎると感じるCSSプロパティの一つです。対角線セクション、幾何学的アバター、切り欠きカード — 以前は画像アセットやSVGの回避策が必要だったものが、今では数行のCSSで実現できます。
覚えておくべき主な点:
polygon()が最も汎用的 — レスポンシブな動作にはパーセンテージを使用clip-pathはbox-shadowをクリップする — 代わりにfilter: drop-shadow()を使用- クリックとホバーエリアはクリップ境界に従う
- 同じ関数、同じポイント数の形状間のみアニメーション可能
- 迷ったらビジュアルジェネレーターを使う — 六角形の頂点を手計算する時間を無駄にしない