CommentOut

【CSS】画像を使わず、逆角丸(border-radiusの反対)を作る方法 【CSS】画像を使わず、逆角丸(border-radiusの反対)を作る方法

【CSS】画像を使わず、逆角丸(border-radiusの反対)を作る方法

公開日:  最終更新日:

まず、以下のサンプルを見てください。

See the Pen
逆角丸のサンプル
by Uilou (@uilou754)
on CodePen.0

最近、こういう角を丸めたようなデザインのサイトが増えたと思いませんか?
様々な所で作り方が紹介されていますが、SVGを使ったり、clip-pathを使って作られています。
しかし、CSSだけでも作れたので、この角丸デザインを画像を使わずに作る方法をご紹介します。

逆角丸の解説サンプル

段階的にわかるようにサンプルを用意しました。

See the Pen
逆角丸の作り方
by Uilou (@uilou754)
on CodePen.0

逆角丸の作り方

まず、初めにdivタグで囲った画像を用意します。

<div class="container">
    <img src="~~" />
</div>

さらに、divの中にdivとspanを定義して、positionはabsoluteします。

<div class="container">
    <img src="~~" />
    <div class="news">
        <span class="corner"></span>
    </div>
</div>
.container {
    position: relative;
}

.news {
    width: 400px;
    position: absolute;
}
.corner {
    display: block;
    width: 20px;
    height: 20px;
}

そして、top, left, right, bottomなどで、位置を調整します。

<div class="container">
    <img src="~~" />
    <div class="news">
        <span class="corner"></span>
    </div>
</div>
.container {
    position: relative;
}

.news {
    width: 400px;
    position: absolute;
    right: 0px;
    bottom: 0px;
}
.corner {
    display: block;
    width: 20px;
    height: 20px;
    position: absolute;
    left: 0px;
    bottom: 0px;
    transform: translateX(-100%);
}

疑似要素(::before)に影を付ける

ここからキモです。
divの外に出されたspanの疑似要素をborder-radiusを使って丸くして、左上に配置します。
さらに、span::beforeにbox-shadowを使って、同じサイズの影を付けます

これ、『::before』は使ってるから『::after』で良いじゃないかと思うかもしれませんが、box-shadowじゃないとダメなんです。filter: drop-shadowでもダメなんです

<div class="container">
    <img src="~~" />
    <div class="news">
        <span class="corner"></span>
    </div>
</div>
.container {
    position: relative;
}

.news {
    width: 400px;
    position: absolute;
    right: 0px;
    bottom: 0px;
}
.corner {
    display: block;
    width: 20px;
    height: 20px;
    position: absolute;
    left: 0px;
    bottom: 0px;
    transform: translateX(-100%);
}
.corner::before {
    display: block;
    width: 200%;
    height: 200%;
    position: absolute;
    top: 0px;
    left: 0px;

    content: '';
    background: orange;
    border-radius: 50%;
    box-shadow: 20px 20px 0 0 red;
    transform: translate(-50%, -50%);
}

.cornerの疑似要素(::before)は.cornerの2倍の幅と高さにします。
あとではみ出した部分を消しますが、使うのは疑似要素(::before)の右下の部分なので、あえてはみ出るサイズにします。

そして、疑似要素(::before)にはbox-shadowを付けますが、box-shadowは.cornerのサイズ分位置をずらします。

影のはみ出た部分をoverflow: hiddenで隠す

そして、spanからはみ出た部分を隠します。
ここはoverflow: hidden;でも、overflow: clip;でも大丈夫です。

あとは、span::before自体を透明化して、box-shadowの色を揃えれば、完成です!

<div class="container">
    <img src="~~" />
    <div class="news">
        <span class="corner"></span>
    </div>
</div>
.container {
    position: relative;
}

.news {
    width: 400px;
    position: absolute;
    right: 0px;
    bottom: 0px;
}
.corner {
    display: block;
    width: 20px;
    height: 20px;
    position: absolute;
    left: 0px;
    bottom: 0px;
    transform: translateX(-100%);
}
.corner::before {
    display: block;
    width: 200%;
    height: 200%;
    position: absolute;
    top: 0px;
    left: 0px;
    overflow: hidden;

    content: '';
    background: transparent;
    border-radius: 50%;
    box-shadow: 20px 20px 0 0 white;
    transform: translate(-50%, -50%);
}

box-shadowとdrop-shadowと疑似要素で影を作った場合を比較

試しに、box-shadowとdrop-shadowと疑似要素で作った影を比較してみます。

See the Pen
逆角丸の影の付け方を検証
by Uilou (@uilou754)
on CodePen.0

box-shadowで影を作った場合には、要素自体が透明でも、ちゃんと影が付きました。
これはbox-shadowが要素の形に合わせて影を付けてくれるためです。
あくまで「影」なので、本来要素がある部分はえぐれて表示されています。

対して、filterのdrop-shadowを使った場合には、枠しか表示されていません。
これはdrop-shadowは要素の中で色のついている部分にだけ影を付けるためです。

だから、背景が透過された画像(.pngとか)に影を付ける時には、filter: drop-shadowは超優秀ですが、こういう場面では使えないんですね。

そして、疑似要素のafterで影を付けた場合には、表示されるけど、重なっている部分がえぐれてくれません。
これではoverflow: hiddenを使っても逆コーナーにならないですよね。

そういうわけで、ここではbox-shadowじゃないといけないのです。

宣伝
WordPressサイトのテンプレート編集やトラブル対応、バグ修正、簡単なJavascriptの作成(カルーセルやバリデーション等)など、小規模なスポット対応を受け付けております。
もしお困りごとがありましたら、お問い合わせフォームよりご相談ください。

この記事を書いた人

uilou

uilou

プログラマー

基本的に、自分自身の備忘録のつもりでブログを書いています。 自分と同じ所で詰まった人の助けになれば良いかなと思います。 システムのリファクタリングを得意としており、バックエンド、フロントエンド、アプリケーション、SQLなど幅広い知識と経験があります。 広いだけでなく、知識をもっと深堀りしていきたいですね。