はじめに
↑こちらは、2025年に使えるようになったCSSの新機能をChrome DevRelチームが紹介しているサイトです。
今回は、shape()関数について学びます ![]()
shape()関数とは?
- 要素を複雑でレスポンシブな形状に切り抜くことができる
-
clip-pathoffset-pathで使用可能な関数
path()関数とshape()関数の違い
clip-pathなどで使用できる関数として、path()関数があります。
shape()関数とpath()関数には以下のような違いがあります。
- pxだけでなく%、em、remなどの単位を扱える
- path()がSVGの文法を扱うのに対し、shape()はコマンドを使い読み解きやすい形で記述できる
- CSSの数式(calc()、max()、abs())やCSS変数を使える
その違いについて、詳しくみていきます。
以下はpath()関数とshape()関数で、同じクリップパスを描画した例です。
See the Pen shape() by 加藤璃子 (@kbsovgkd-the-solid) on CodePen.
一見同じ見た目に見えます。
しかし、画面幅の縮小によって、ボックスのサイズが変わると以下のように違いがわかります。
path()関数で指定しているクリップパスは、サイズが変わると崩れてしまっています。
一方、shape()関数で指定しているクリップパスは、そのままの形を維持しています。
-
path()関数:固定の数値(px)のみ指定可能
要素のサイズが変わっても図形は動かない
-
shape()関数:相対的な単位(%,rem等)でも指定可能
要素のサイズが変わっても、図形の比率を維持できる
path() と shape() の書き方の違い
path()の書き方
.path-demo {
clip-path: path("M 0 20 C 75 0, 225 40, 300 20 V 280 C 225 300,
75 260, 0 280 Z");
}
-
M:Move to (座標を移動する)-
M 0 20:座標 (x:0, y:20) へ移動
-
-
C:Cubic Bezier(ベジェ曲線をかく)-
C 75 0, 225 40, 300 20- 制御点1 (75, 0):25%地点で真上(y=0)へ引っ張る
- 制御点2 (225, 40):75%地点で下(y=40)へ引っ張る
- 終点 (300, 20): 右端(x=300)の高さ20px地点に着地
-
-
V:Vertical Line(垂直線を引く)-
V 280:横位置はそのままで、縦を280pxの地点まで一気に真っ直ぐ下ろす
-
-
Z:パスを閉じる
shape() の書き方
.shape-demo {
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 /* パスを閉じる */
);
}
from x座標 y座標:図形を書き始める点
-
from 0% 20px- x座標:ボックス左端
- y座標:上端から20px下
curve to [x] [y] with [x1] [y1] [x2] [y2]:ベジェ曲線を描画
-
fromで指定した始点(0% 20px)からベジェ曲線を描画 - 100% 20px:カーブの終点
- with 25% 0% 75% 40px:ベジェ曲線の制御点のx,y座標
X座標の各指定を%で書いていることで、サイズが変わってもカーブが維持される
line:直線を描画
-
vline:lineの派生で垂直線を描くために使う -
vline to calc(100% - 20px)-
calc(100% - 20px):ボックスの一番下から20px上
-
shape()関数では、CSSの数式(calc()、max()、abs())やCSS変数を使える
curve to 100% 20px with 25% 0% 75% 40px,
-
curve to 0% calc(100% - 20px) with 75% 100% 25% calc(100% - 40px),-
0% calc(100% - 20px):カーブの終点 -
with 75% 100% 25% calc(100% - 40px),:ベジェ曲線の制御点のx,y座標
-
close:描画を終了させる
-
closeの直前のコマンド終点からfromで指定した点を直線でつなげる
path()のSVG文法に比べて、shape()のコマンドは役割が直感でわかりやすい
shape()のその他のコマンド
shape()のその他のコマンドを紹介します
-
move to x座標 y座標:次のコマンドの開始位置を指定 -
hline:水平線を描く -
smooth:curveよりも直前の線とのつながりが滑らかになる -
arc:円弧で曲線を描画する
shape() と path() のコマンド対応表
| 機能 |
shape() のコマンド |
path() (SVG) |
備考 |
|---|---|---|---|
| 開始地点 | from <x> <y> |
M x y |
Move to。描画の起点 |
| 直線 | line to <x> <y> |
L x y |
現在地から指定座標へ直線を引く |
| 水平線 | hline to <x> |
H x |
Y座標を固定したまま水平に移動 |
| 垂直線 | vline to <y> |
V y |
X座標を固定したまま垂直に移動 |
| 2次ベジェ曲線 | curve to <x> <y> via <cx1> <cy1> |
Q cx1 cy1, x y |
1つの制御点を持つ曲線 |
| 3次ベジェ曲線 | curve to <x> <y> with <cx1> <cy1> [<cx2> <cy2>] |
C cx1 cy1, cx2 cy2, x y |
2つの制御点を持つ滑らかな曲線 |
| 円弧 | arc to <x> <y> of <r> [large] [cw] |
A rx ry rot la sw x y |
shape() は半径指定のみで直感的 |
| 閉じる | close |
Z |
開始地点まで直線を引いてパスを閉じる |
最後に
今回はpath()関数とshape()関数の比較をしてみました!
shape()関数は path()関数よりも自由度高く、コードの可読性も上がりそうです。
最後までお読みいただき、ありがとうございます!
サポート状況を確認して使用してください
参考





