
borderを使わない三角付き角丸ボックス
三角付き(ふきだし風)のボックスを作るとき、三角部分をどうやって作りますか?
borderの3方向を透明にして三角に見せる方法は昔から使われていますが、記述が複雑ですし、何より困ったことがあります。
borderは幅や高さに%が使えない!
borderを使った方法では、三角のサイズを決めるborderの幅に%を使うことができないため、幅や高さが可変する場合は使用できません。
無理やり使うためにボックス部分に「overflow: hidden;」を書いて、borderの幅は余裕を持たせたサイズをpxなどで指定したりしますが、親ボックスがoverflow: hiddenになるのは何かと不便ですし、余裕のあるサイズとはいえ完全ではありません。
borderがダメなら三角を描けばいいじゃない
まずはHTMLを簡単に書きます。
タグはなんでもいいですが、今回はリストにしておきます。
親に「.polygon」クラスを付けておきます。
<ul class="polygon">
<li><figure><img src="image.jpg"></figure><p>リスト</p></li>
<li><figure><img src="image.jpg"></figure><p>リスト</p></li>
<li><figure><img src="image.jpg"></figure><p>リスト</p></li>
</ul>
▼ 親の横並び設定などを書きます。ここはご自由に。
.polygon {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 40px;
padding: 0;
list-style: none;
}
▼ 続いて子要素を角丸ボックスに整えます。
「position: relative;」のみ必須です。
また、「border-radius」に設定した値は覚えておいてください。
.polygon > * {
background: #eee;
padding: 20px;
margin: 0;
border-radius: 10px;
position: relative;
}
▼ ボックスの中はご自由に。
.polygon > * figure {
margin: 0;
padding: 0;
}
.polygon > * figure img {
border-radius: 5px;
max-width: 100%;
}
.polygon > * p {
margin:20px 0 0 0;
padding: 0;
}
▼ ここまでで、こんな感じだと思います。

三角を付けます
.polygon > *::after {
content: '';
position:absolute;
background: #eee;
left:99.9%;
top: 50%;
transform: translateY(-50%);
width: 40px;
height: calc(100% - (10px * 1.5));
clip-path: polygon(0% 0%, 100% 50%, 0% 100%);
}
三角は、after疑似要素を使います。(ボックスの後ろなので)
上記CSSをすこしずつ見ていきましょう。
▼ まずは要素を生成して自由配置に。
「background: #eee;」はボックスの背景色と同じです。
content: '';
position:absolute;
background: #eee;
▼ 位置を調整します。今回は右側に付くのでこんな感じ。
右に付く場合はleft、左に付く場合はright、下に付く場合はtop・・・というように、逆方向から指定すると、三角の幅を考える必要がないので楽です。
99.9%としているのは、ボックスサイズが割り切れない場合にボックスと三角の間に隙間が生まれることを防ぐためです。
top: 50%;
transform: translateY(-50%);
は、上下中央にする際のお約束ですね。
left:99.9%;
top: 50%;
transform: translateY(-50%);
width: 40px;
三角の幅です。
隣のボックスにくっつけたい場合は、gapで指定した幅と同じにします。
height: calc(100% - (10px * 1.5));
呪文です。
10pxの部分は、border-radiusと同じ数値にします。
clip-path: polygon(0% 0%, 100% 50%, 0% 100%);
このままで大丈夫です。
三角形に切り抜きしています!
この数値を変えることで、三角の形を自由に変更できます。


簡単でしょう?

Have a nice CSS!