🎉

CSSだけで単色じゃない背景の上にドッグイヤー(折り返し)を作る方法

2021/10/30に公開

概要

CSSだけで単色じゃない背景の上にドッグイヤー(折り返し)を作れるよ、という話。IE11も対応します。

そもそもドッグイヤーとは?

ちょいちょい見かける紙の端を折り返したような表現のことをドッグイヤーと呼ぶらしいです。確かに名前の通り犬の耳に見えますね。

さて、早速ですがよく見るドッグイヤーの実装方法は下記のような感じです。

html
<div class="title">
  <p class="text">ドッグイヤー 01 - デモ</p>
</div>
css
.title {
  position: relative;
  width: 300px;
  padding: 30px;
  box-sizing: border-box;
  background: #bad3ff;
}
/* 擬似要素を使ってドッグイヤー部分を表現 */
.title::after {
  content: "";
  position: absolute;
  bottom: 0;
  right: 0;
  width: 14px;
  height: 14px;
  border: 7px solid #4689ff;
  border-right-color: #fff; /* 背景色 */
  border-bottom-color: #fff; /* 背景色 */
  box-sizing: border-box;
}

ドッグイヤーを実装したことある方にはよく見慣れたコードだと思います。borderを使って三角形を作成し、それを右下に重ねています。

基本的には問題ないのですが、上記の場合、背景が単色の時しか対応できません。

背景が単色じゃない時のドッグイヤーの実装 - IE対応 -

では背景が単色じゃない時の実装はどうするのかというと、今回紹介するのは

  • linear-gradient
  • clip-path

のプロパティを使う2通りになります。このうちIE11に対応できるのはlinear-gradientの方なのでまずはlinear-gradientの実装方法をみていきましょう。

CSSの変更箇所を以下に示します(HTMLは変更なし)。サンプルコードには示しませんが、背景をわかりやすくするため、グラデーションさせています。

css
.title {
  position: relative;
  width: 300px;
  padding: 30px;
  box-sizing: border-box;
  background: linear-gradient(
    -45deg,
    transparent 10px,
    #bad3ff 10px,
    #bad3ff 100%
  ); /* 切り取り部分を transparent で指定 */
}
.title::after {
  content: "";
  position: absolute;
  bottom: 0;
  right: 0;
  width: 14px;
  height: 14px;
  border: 7px solid #4689ff;
  border-right-color: transparent;
  border-bottom-color: transparent;
  box-sizing: border-box;
}

backgroundにlinear-gradientを指定し、右下に端の折り返し(切り取り部分)を作ります。見ての通りtransparentで指定しいるので折り返し(切り取り部分)が透明になります。

この時border幅の計算が若干面倒なので、簡単に説明します。linear-gradient で指定したtransparentの幅に √2 ÷ 2を掛けた値が目安になります。

linear-gradientで指定したtransparentの幅 × √2 ÷ 2

が目安となるので、サンプルコードでは

10(px) × √2 ÷ 2 = 7.07106781187(px)

となります。今回の場合は小数点を切り捨て、7pxとしているのですが、1px単位の微調整は、実際に目でも確認することをオススメめします。

影をつける

さらに面倒なことに影をつけたいという要望があるとします。シンプルに目的の要素にbox-shadowをつけてみると、表示がおかしくなることに気づきますね。

このような場合はdrop-shadowを使いましょう。

css
.title {
  position: relative;
  width: 300px;
  padding: 30px;
  box-sizing: border-box;
  background: linear-gradient(
    -45deg,
    transparent 10px,
    #bad3ff 10px,
    #bad3ff 100%
  );
  filter: drop-shadow(1px 1px 3px rgba(0, 0, 0, 0.9)); /* drow-shadow を使う */
}

ただご存知の通り上記のコードはIE11には対応できません。どうしてもIE11に対応したい場合は以下のようにします。多少影の見え方は変わってしまいますが、その辺りは細かく調整するしかないです、、。

css
.title::before {
  content: "";
  position: absolute;
  top: 7px;
  left: 7px;
  width: calc(100% - 14px); /* はみ出さないようにする */
  height: calc(100% - 14px); /* はみ出さないようにする */
  box-shadow: 2px 2px 12px -2px rgba(0, 0, 0, 0.9);
  z-index: -1; /* .title の親要素に position:relative と z-index:1 を忘れない */
}

背景が単色じゃない時のドッグイヤーの実装 - IE11非対応 -

IE11非対応でいいのであれば、もう少し簡単にドッグイヤーを実装できます。そうです。clip-pathを使いましょう。注意点として、もし影をつけたい場合は、親要素につけましょう。

<!-- 影は親要素煮付ける -->
<div class="shadow">
  <div class="title">
    <p class="text">ドッグイヤー 05 - デモ</p>
  </div>
</div>
css
.shadow {
  filter: drop-shadow(1px 1px 3px rgba(0, 0, 0, 0.9)); /* drow-shadow は親につける */
}
.title {
  position: relative;
  width: 300px;
  padding: 30px;
  box-sizing: border-box;
  background-color: #bad3ff;
  clip-path: polygon(
    0 0,
    100% 0,
    100% calc(100% - 14px),
    calc(100% - 14px) 100%,
    0 100%
  );
}

まとめ

ドッグイヤー実装方法の解説でした。IE11がなければ、わりとすんなりできるのですがIE11対応を考えると意外と大変ですね。

参考

Discussion