画像を使わずに擬似要素のみで実装するシンプルな逆角丸【CSS小ネタ】
下記の画像のような逆角丸のデザインを実装する場合、画像を使うのが一般的かもしれません。しかしborder-radiusとbox-shadowを組み合わせることで、純粋なCSSのみで再現可能です。

この記事では画像を使わない逆角丸の実装方法を、具体的なコード例とともに段階的に解説しています。
実装例
早速ですが、以下が実装例です。
見出しボックスの右下部分に逆角丸を採用したデザインです。
近年のモダンなデザインのコーポレートサイトなどでよくみかけるデザインで、流線型を多用することで少し柔らかな印象を与える効果があると考えています。
コードの仕組み
どのようにコードで再現しているのか簡単に解説します。
HTML
今回は画像を使わずに擬似要素のみで実装しているため、HTMLはとてもシンプルです。.boxの中に見出しとコンテンツを配置しています。逆角丸は見出し要素で実装しています。
<div class="box"> <h2 class="box__header">見出しが入ります</h2> <div class="box__content"> <p>テキストが入ります。テキストが入ります。テキストが入ります。</p> <p>テキストが入ります。テキストが入ります。テキストが入ります。</p> <p>テキストが入ります。テキストが入ります。テキストが入ります。</p> </div></div>CSS
CSSについては段階的に解説していきます。初期状態では次のようなコードになっています。見出しボックスの右上のみ角丸がかかっている状態です。
.box__header { display: inline-block; font-size: 20px; background-color: #fff; border-top-right-radius: 20px; padding: 20px 60px;}
ここに透明な擬似要素を右下に配置して、角丸の部分を覆います。擬似要素のサイズは角丸の設定値と同じにし、形状は正方形にします。
.box__header { display: inline-block; font-size: 20px; background-color: #fff; border-top-right-radius: 20px; padding: 20px 60px; position: relative;}
.box__header::after { content: ""; width: 20px; aspect-ratio: 1; position: absolute; bottom: 0; left: 100%;}
次に追加した擬似要素に角丸を設定します。
.box__header::after { content: ""; width: 20px; aspect-ratio: 1; position: absolute; bottom: 0; left: 100%; border-bottom-left-radius: 20px;}ただ当然ながら擬似要素自体は透明なため、角丸を設定しても何も変化はありません。

そこで擬似要素にbox-shadowプロパティを設定して、角丸の周囲を覆います。box-shadowの設定がわかりやすいように便宜的に赤色で設定しています。これで擬似要素本体と擬似要素に設定した角丸が見えるようになりました。
.box__header::after { content: ""; width: 20px; aspect-ratio: 1; position: absolute; bottom: 0; left: 100%; border-bottom-left-radius: 20px; box-shadow: 0 0 0 20px red;}
ただこの状態だとbox-shadowが上と右にはみ出してしまっているため、位置を調整します。
.box__header::after { content: ""; width: 20px; aspect-ratio: 1; position: absolute; bottom: 0; left: 100%; border-bottom-left-radius: 20px; box-shadow: 0 0 0 20px red; box-shadow: -20px 20px 0 20px red;}box-shadowの値を以下のように設定しています。
- 1つ目の値(X方向のシャドウの位置):左に20pxずらす
- 2つ目の値(Y方向のシャドウの位置):下に20pxずらす
- 3つ目の値(ぼかしの大きさ):0なのでぼかしはなし
- 4つ目の値(スプレッドの量):20px分(角丸のサイズ)だけ影が広がる
すると次のように、本体部分に沿って赤色の影が移動してくれました。

最後に影の色を、見出しボックスの背景色と同じにします。また擬似要素がコンテンツより上に配置されるのを避けるために、コンテンツにposition: relative;を設定します。以上で完成です。
.box__header::after { content: ""; width: 20px; aspect-ratio: 1; position: absolute; bottom: 0; left: 100%; border-bottom-left-radius: 20px; box-shadow: -20px 20px 0 20px red; box-shadow: -20px 20px 0 20px #fff;}
.box__header + * { position: relative;}
冒頭に示したコード例では、「角丸のサイズ」と「ボックスの背景色」をカスタムプロパティとして定義し、連動する箇所にそれらを指定することでより汎用性の高いコードにしています。
この方法のメリットデメリット
この方法のメリットとデメリットを整理します。
メリット
画像を使用していないため、「角丸のサイズ」と「ボックスの背景色」を柔軟に変更できる点です。例えば角丸のサイズをもう少し抑えたいという場合には以下のコード変更のみで対応できます。
.box { /* 角丸を 20px -> 15px に変更 */ --_rounded: 15px; --_box-color: #fff;}またわずかではありますが、画像未使用のためファイルサイズが小さくなる点もメリットとして挙げられます。
デメリット
デメリットとしては次のケースには対応できない点が挙げられます。
- 背景色に画像を使用している。
- 背景色にグラデーションを使用している。
こようなケースでは画像を使うか、maskもしくはclip-pathプロパティの使用を検討する必要があると考えています。
