CSSのcorner-shapeで角を斜めに切る・へこませる方法
border-radius を付けた要素に corner-shape: bevel を足すと、丸い角が斜めにまっすぐ切った角に変わります。scoop なら角が丸くへこみ、notch なら四角くへこみます。clip-path で切り抜く方法と違い、枠線や影も切った形に沿って描かれます。
検証環境は Ubuntu 24.04、Node.js 22.23.4、Playwright 1.63.0、Chromium 153 です。HTML と CSS だけのページを Playwright で開き、スクリーンショットの画素の色と getComputedStyle() の値で形を確かめました。Firefox と Safari、スマートフォンの実機での表示は試していません。各ブラウザーの対応バージョンは、互換性データ(@mdn/browser-compat-data 8.1.8)の値です。
角を斜めに切る・へこませる書き方
corner-shape は、border-radius で丸めた角の範囲を、どんな形にするかを指定するプロパティです。角を斜めに切るなら bevel、へこませるなら scoop か notch を指定します。
.cut {
border-radius: 40px;
corner-shape: bevel; /* 斜めに切る */
}
.scoop {
border-radius: 40px;
corner-shape: scoop; /* 丸くへこませる */
}
.notch {
border-radius: 40px;
corner-shape: notch; /* 四角くへこませる */
}

指定できるキーワードは6つです。何も指定しないときは round で、これまでの border-radius の角丸と同じ形になります。
| 値 | 角の形 |
|---|---|
round |
普通の角丸(初期値) |
squircle |
round より四角に近い丸み |
square |
角丸なしの直角 |
bevel |
斜めにまっすぐ切る |
scoop |
内側に丸くへこませる |
notch |
内側に四角くへこませる |
検証環境で、200×120px の要素に border-radius: 40px を付け、左上の角の近くの点が塗られているかを調べました。以下、要素の左上の角から右へ 15px、下へ 15px の点を (15,15) のように書きます。(15,15) の点は、round では塗られ、bevel では空白になりました。(25,25) は scoop では空白、(35,35) は notch だけが空白です。切り落とす範囲は bevel、scoop、notch の順に広くなります。square では、border-radius を付けていても角の点まで塗られ、直角の角になりました。
切る大きさは border-radius で決まる
corner-shape は、角の形を変えるだけです。どこまで切るかは border-radius の大きさで決まります。
border-radius を付けずに corner-shape: bevel だけを書くと、何も変わりませんでした。角から (5,5) の点まで塗られた、ただの長方形のままです。MDN にも、border-radius がないときや 0 のときは効果がないと書かれています。
border-radius: 40px の bevel では、上の辺も左の辺も角から約 40px のところから切り口が始まり、その2点をまっすぐ結ぶ線になりました。縦と横で違う半径を書くと、角度が変わります。
.cut-wide {
border-radius: 60px / 30px; /* 横 60px、縦 30px */
corner-shape: bevel;
}
この指定では、上の辺は約 60px、左の辺は約 30px のところから切り口が始まりました。border-radius: 20% のように割合で書くと、横は幅の 20%、縦は高さの 20% になります。200×120px の要素では、上の辺は約 40px、左の辺は約 24px のところから始まりました。
角ごとに形を変える
corner-shape には、border-radius と同じく1〜4個の値を書けます。4個のときは左上、右上、右下、左下の順です。
.card {
border-radius: 24px;
corner-shape: bevel square square scoop;
/* 左上は斜め、右上と右下は直角、左下は丸くへこむ */
}
検証環境で、各角から内側へ 6px ずつ入った点の色を調べると、左上と左下だけが空白になりました。2個の値を書いた corner-shape: square bevel では、左上と右下が直角、右上と左下が斜めです。この並びも border-radius と同じです。
1つの角だけを変えたいときは、corner-top-right-shape のような角ごとのプロパティを使います。このとき、border-radius もその角だけに付けると、ほかの角は直角のままになります。
.notice {
border-top-right-radius: 28px;
corner-top-right-shape: bevel;
}
border-radius と組み合わせると、値札やチケットのような形も作れます。値札の形は、右側の2つの角だけに、横 24px・縦 50% の半径を付けて bevel にしています。上下の切り口が右の辺の真ん中で出会い、矢印の先のようになります。
.price-tag {
border-radius: 0 24px 24px 0 / 0 50% 50% 0;
corner-shape: bevel;
}
.ticket {
border-radius: 16px;
corner-shape: scoop;
}

値札の形では、右の辺の真ん中のすぐ内側は塗られ、右上と右下の角は空白になりました。
枠線と影も、切った形に沿う
角を斜めに切るだけなら、clip-path の polygon() でもできます。違いが出るのは、枠線や影を付けたときです。
/* clip-path で切る */
.clip {
border: 5px solid #067a98;
box-shadow: 0 0 0 8px #d85878;
clip-path: polygon(40px 0, 100% 0, 100% 100%, 0 100%, 0 40px);
}
/* corner-shape で切る */
.corner {
border: 5px solid #067a98;
box-shadow: 0 0 0 8px #d85878;
border-radius: 40px;
corner-shape: bevel;
}

clip-path は、描いたあとの見た目を形の外側で切り落とします。斜めの辺の上には枠線がなく、中の背景がそのまま見えました。要素の外側に出る影も切り落とされ、どの辺にも出ていません。
corner-shape では、斜めの辺の上にも枠線が引かれ、影も斜めの辺に沿って外側に出ました。MDN にも、背景、枠線、outline、box-shadow、overflow、backdrop-filter が角の形に従うと書かれています。
overflow: hidden を付けると、子要素も切った形で切り抜かれました。全面をピンクにした子要素を入れても、切り落とした角の部分は空白のままで、子要素は角からはみ出しませんでした。
クリックできる範囲も、切った形どおりになりました。切り落とした角の部分を document.elementFromPoint() で調べると、カードではなく、その下に重ねた要素が返りました。
丸みの度合いを superellipse() で細かく決める
キーワードのあいだの形は、superellipse() 関数で数値を指定して作れます。キーワードはそれぞれ、次の数値と同じ形です。検証環境で getComputedStyle() を読むと、キーワードを指定しても、この数値の形で返りました。
| キーワード | 計算値 |
|---|---|
square |
superellipse(infinity) |
squircle |
superellipse(2) |
round |
superellipse(1) |
bevel |
superellipse(0) |
scoop |
superellipse(-1) |
notch |
superellipse(-infinity) |
数値が大きいほど四角に近くふくらみ、0 で斜めの直線、マイナスになると内側にへこみます。最初の画像の superellipse(0.5) は、round と bevel のあいだの形です。
MDN にあるとおり、corner-shape は値と値のあいだを滑らかにアニメーションできます。round から bevel へ1秒の linear の transition を付けると、500ms の時点の計算値は superellipse(0.457105) でした。数値の真ん中の 0.5 ではありません。仕様では、数値をそのまま直線的に変えると、bevel から square への変化が、はじめは速く終わりは遅く見えるとしています。そのため、数値をいったん 0〜1 の値に変換してから途中の値を計算すると定めています。仕様の式で変換すると、round は 0.7071、bevel は 0.5 です。その真ん中を数値に戻すと 0.457105 になり、検証環境の値と一致しました。
transition: corner-shape 1s と一括指定の名前で書くと、4つの角のプロパティ(corner-top-left-shape など)がそれぞれ別に変化しました。
対応しているブラウザー
互換性データでは、corner-shape は実験的な機能とされています。
| ブラウザー | 対応 |
|---|---|
| Chrome・Edge | 139 から |
| Chrome(Android) | 139 から |
| Firefox | 対応なし(開発中の版のみ) |
| Safari | 対応なし(Technology Preview のみ) |
| Safari(iOS) | 対応なし |
対応していないブラウザー向けに別の書き方を用意したいときは、@supports で分けます。
@supports not (corner-shape: bevel) {
.cut {
/* corner-shape が使えないときの指定 */
}
}
検証環境の Chromium 153 では、CSS.supports('corner-shape', 'bevel') は true を返し、@supports not (corner-shape: bevel) の中の指定は使われませんでした。





