🔰はじめての方へ

【背景画像に対応】CSSだけでリボン風デザインを作る方法|clip-path

CSS
記事内に広告が含まれています。
スポンサーリンク

よく見かけるリボンCSS

よく見かけるリボンの作り方は、色付き四角の左右に三角の背景と同じ色のものを被せてリボン風にするやり方です。

疑似要素(::before / ::after)で白い三角形を重ねる方法です。

下の画像は背景が画像になっているのですが、背景を「黒」と仮定します。

上の長方形の赤い色のついたラインを

両サイドに背景と同じ色である「黒」の三角を擬似要素でつけます。

背景色が黒の場合は、これでリボンの形になります。

ちなみにこのコード例は下記です。

コード例①

HTML

<p class="line-name1">リボン</p>

CSS

.line-name1 {
    font-size: clamp(10px, 4vw, 24px);
    position: relative;
    display: inline-block;
    line-height: 1.8;
    padding: 0 1.5em;
    background-color: #d23726;
    color: #ffffff;
    font-weight: bold;
    text-align: center;
}

.line-name1::before,
.line-name1::after {
    position: absolute;
    content: '';
    top: 0;
    width: 0px;
    height: 0px;
    border-color: transparent #2b2120;
    border-style: solid;
}

.line-name1::before {
    left: 0;
    border-width: 25px 0px 25px 15px;
}

.line-name1::after {
    right: 0;
    border-width: 25px 15px 25px 0px;
}

下記コードでもできると思います(できなかったら教えてください!)

コード例②

HTML

<p class="line-name2">リボン</p>

CSS

.line-name2 {
    font-size: clamp(10px, 4vw, 24px);
    position: relative;
    display: inline-block;
    line-height: 1.8;
    padding: 0 1.2em;
    background-color: #d23726;
    color: #ffffff;
    font-weight: bold;
    text-align: center;
}

.line-name2::before,
.line-name2::after {
    position: absolute;
    content: '';
    top: 0;
    bottom: 0;
    width: 15px;
    background: #000;
}

.line-name2::before {
    left: 0;
    clip-path: polygon(0 0, 0 100%, 75% 50%);
}

.line-name2::after {
    right: 0;
    clip-path: polygon(100% 0, 25% 50%, 100% 100%);
}

これで十分なのですが、

背景を画像にしている場合、両サイドの切り抜いている風の三角は、色がついていてかなり気になります・・・

余談・・・三角形の%の早見表

三角を作るために私が使用したのは

右向き三角▶︎
 clip-path: polygon(0 0, 0 100%, 75% 50%); 

左向き三角◀︎
 clip-path: polygon(100% 0, 25% 50%, 100% 100%);

clip-path: polygon の仕組みについては後述しますが、簡単に他の向きの数値も置いておきます。

▲上   clip-path: polygon(50% 0, 100% 100%, 0 100%);
▶︎右  clip-path: polygon(0 0, 100% 50%, 0 100%);
▼下   clip-path: polygon(0 0, 100% 0, 50% 100%);
◀︎左   clip-path: polygon(0 50%, 100% 0, 100% 100%);

今回説明するリボン完成図

背景画像を残しながら、ラインの方を切り抜く方法です。

解決策:clip-path で要素そのものを切り抜く

clip-path: polygon() を使えば、要素の形そのものを多角形に切り抜けます。

疑似要素は不要で、背景が画像でも透けてくれます。

完成コード

<p class="ribbon">リボン</p>
.ribbon {
    font-size: 24px;
    display: inline-block;
    line-height: 1.8;
    padding: 0 1.5em;
    background-color: #d23726;
    color: #ffffff;
    font-weight: bold;
    text-align: center;
    clip-path: polygon(
        0% 0%,      /* 左上 */
        100% 0%,    /* 右上 */
        92% 50%,    /* 右の食い込み ◀ */
        100% 100%,  /* 右下 */
        0% 100%,    /* 左下 */
        8% 50%      /* 左の食い込み ▶ */
    );
}

clip-path: polygon() の仕組み

polygon()頂点の座標を順番に指定して、多角形の形に切り抜きます。

位置を自由に何個も指定することができるため、いろんな形の切り抜きが可能です。

座標は (横% 縦%) で、左上が 0% 0%、右下が 100% 100% です。

今回のリボンは6つの頂点で構成されています。

①左上(0,0)───────────────②右上(100,0)
  \                           /
   ⑥左の食い込み(8,50)  ③右の食い込み(92,50)
  /                           \
⑤左下(0,100)─────────────④右下(100,100)

ポイントは③と⑥です。左右の辺の中央(50%)に、内側に食い込む頂点を置くことでリボンの形になります。

食い込みの深さを調整する

③と⑥の横位置の数値を変えるだけで、食い込みの深さが変わります。

/* 浅め(ほぼ四角に近い) */
clip-path: polygon(0% 0%, 100% 0%, 96% 50%, 100% 100%, 0% 100%, 4% 50%);

/* 標準 */
clip-path: polygon(0% 0%, 100% 0%, 92% 50%, 100% 100%, 0% 100%, 8% 50%);

/* 深め(くっきりリボン) */
clip-path: polygon(0% 0%, 100% 0%, 85% 50%, 100% 100%, 0% 100%, 15% 50%);

向きを反転させる(外向き矢印)

食い込みではなく、外に突き出すリボンにしたい場合は、頂点の位置を逆にします。

/* 外向き  */
clip-path: polygon(8% 0%, 92% 0%, 100% 50%, 92% 100%, 8% 100%, 0% 50%);

どの頂点の指標から書けばいいの?

clip-path: polygon(8% 0%, ・・・); と、どの頂点から書けばいいのかわかりにくですよね。

基本は、左上からスタートして、時計回りに頂点を順番に指定していきます。

①→②→③→④→⑤→⑥→①に戻る

    ①───────→②
    ↑            ↘
    ⑥              ③
    ↗            ↙
    ⑤←───────④

反時計回りでも動作しますが、時計回りが一般的で読みやすいです。

また、始点は左上でなくてもOKです。

どの頂点から始めても同じ形になります。

ただ、左上スタートの時計回りが一番直感的なので、慣習としてそうしている人が多いです。

疑似要素との違いまとめ

疑似要素で三角を重ねるclip-pathで切り抜く
背景が白OKOK
背景が画像NG(白が見える)OK
レスポンシブ高さに合わせて調整が必要自動で追従
コード量多い(::before, ::after)1プロパティで完結
ブラウザ対応全ブラウザIE非対応(モダンブラウザはOK)

注意点

  • clip-path は要素の外側を見えなくするだけで、クリック領域やレイアウト上のサイズは四角のままです
  • border は切り抜かれた部分に沿わないため、ボーダーを付けたい場合は box-shadow や filter: drop-shadow() で代用します