🫥
CSSの疑似要素で逆角丸 with Tailwind
こんな逆角丸作りたい時ありますよね
これを余計なDOMを増やさず、Tailwindだけで実現する方法を紹介します
※Tailwindは入っている前提になります
結論
<div>
<div
class="relative w-fit max-w-[calc(100%-16px)] rounded-t-lg bg-green-500 before:absolute before:bottom-0 before:left-full before:h-2 before:w-2 before:bg-green-500 after:absolute after:bottom-0 after:left-full after:h-2 after:w-2 after:rounded-bl-lg after:bg-white"
>
<div class="truncate px-3 py-1 font-bold text-white">
タブ名
</div>
</div>
<div class="rounded-b-lg rounded-tr-lg border border-green-500 p-3">
コンテンツ
</div>
</div>
解説
まずは逆角丸なしのシンプルなタブデザインを実装
幅を狭めるとこうなるイメージです
<div>
<div class="w-fit max-w-[calc(100%-8px)] rounded-t-lg bg-green-500">
<div class="px-3 py-1 font-bold text-white">
タブ名
</div>
</div>
<div class="rounded-b-lg rounded-tr-lg border border-green-500 p-3">
コンテンツ
</div>
</div>
なんとなくtruncate
タブ名は改行したくない
ってときはこうですね
<div>
<div class="w-fit max-w-[calc(100%-8px)] rounded-t-lg bg-green-500">
- <div class="px-3 py-1 font-bold text-white">
+ <div class="truncate px-3 py-1 font-bold text-white">
タブ名
</div>
</div>
<div class="rounded-b-lg rounded-tr-lg border border-green-500 p-3">
コンテンツ
</div>
</div>
逆角丸のための背景を追加
まずは背景を追加
疑似要素の理解のため、あえてDOMを追加しています
<div>
- <div class="w-fit max-w-[calc(100%-8px)] rounded-t-lg bg-green-500">
+ <div class="relative w-fit max-w-[calc(100%-16px)] rounded-t-lg bg-green-500">
+ <div class="absolute bottom-0 left-full h-2 w-2 bg-green-500"></div>
<div class="truncate px-3 py-1 font-bold text-white">
タブ名
</div>
</div>
<div class="rounded-b-lg rounded-tr-lg border border-green-500 p-3">
コンテンツ
</div>
</div>
逆角丸にする
先ほどの背景に白い角丸を重ねるイメージ
背景色が白じゃない時がちょいと面倒
今回もいったん要素を追加
<div>
<div class="relative w-fit max-w-[calc(100%-16px)] rounded-t-lg bg-green-500">
<div class="absolute bottom-0 left-full h-2 w-2 bg-green-500"></div>
<div class="truncate px-3 py-1 font-bold text-white">
タブ名
</div>
+ <div class="absolute bottom-0 left-full h-2 w-2 rounded-bl-lg bg-white"></div>
</div>
<div class="rounded-b-lg rounded-tr-lg border border-green-500 p-3">
コンテンツ
</div>
</div>
疑似要素化
見た目は変わりませんがHTML上の要素数が減ります
疑似要素はその要素内の先頭、末尾に要素を一つ追加するイメージなので、その要素をrelativeにすれば好きな位置にいろんなものを配置できますね
だから末尾に「円」って入れたりもできますし、先頭に「¥」を追加したりもできるわけですね
<div>
- <div class="relative w-fit max-w-[calc(100%-16px)] rounded-t-lg bg-green-500">
+ <div
+ class="relative w-fit max-w-[calc(100%-16px)] rounded-t-lg bg-green-500 before:absolute before:bottom-0 before:left-full before:h-2 before:w-2 before:bg-green-500 after:absolute after:bottom-0 after:left-full after:h-2 after:w-2 after:rounded-bl-lg after:bg-white"
+ >
- <div class="absolute bottom-0 left-full h-2 w-2 bg-green-500"></div>
<div class="truncate px-3 py-1 font-bold text-white">
タブ名
</div>
- <div class="absolute bottom-0 left-full h-2 w-2 rounded-bl-lg bg-white"></div>
</div>
<div class="rounded-b-lg rounded-tr-lg border border-green-500 p-3">
コンテンツ
</div>
</div>
あとがき
Tailwind使うとどうしたってclass属性が長くなる
今回の最も長い行で270字近い
フレームワークを使うならこの逆角丸だけコンポーネントに切り出せば1行100字前後になるんだろうか?
と思ったが210字程度にしかならぬ。。。
フレームワークなら大抵クラスを配列で渡せるだろうからbeforeとafterで改行すれば110字前後
ここらへんが落としどころか。。。
<template>
<div
:class="[
'relative w-fit max-w-[calc(100%-16px)] rounded-t-lg bg-green-500',
'before:absolute before:bottom-0 before:left-full before:h-2 before:w-2 before:bg-green-500',
'after:absolute after:bottom-0 after:left-full after:h-2 after:w-2 after:rounded-bl-lg after:bg-white',
]"
></div>
</template>
Discussion