Comment Box (Speech Bubble) สร้างได้ง่ายด้วย CSS clip-path บน Pseudo-element (::after/::before) สร้าง "หาง" ชี้ไปที่ผู้พูด ตัวอย่างนี้แสดง 2 รูปแบบ: หางชี้ซ้าย และ หางชี้ขวา
Syntax
selector::after {
content: "";
position: absolute;
clip-path: polygon(...);
}
ตัวอย่างที่ 1: Comment Box 2 ฝั่ง (Left & Right)
<!DOCTYPE html>
<html>
<head>
<style>
.cb {
position: relative;
padding: 2%;
border-radius: 8%;
width: 25%;
}
.cb::after {
content: "";
position: absolute;
height: 30px;
width: 30px;
bottom: -30px;
left: 80%;
}
#one {
box-shadow: inset 0 0 12px green;
left: 65%;
}
#two {
box-shadow: inset 0 0 12px blue;
left: 4%;
}
#one::after {
left: 80%;
box-shadow: inset 0 0 12px green;
clip-path: polygon(0 0, 100% 0, 100% 80%);
}
#two::after {
left: 8%;
box-shadow: inset 0 0 12px blue;
clip-path: polygon(0 0, 100% 0, 0 80%);
}
</style>
</head>
<body>
<div class="cb" id="one">Demo Comment 1</div>
<div class="cb" id="two">Demo Comment 2</div>
</body>
</html>
วิเคราะห์ Clip-path
- #one::after (Right Tail):
polygon(0 0, 100% 0, 100% 80%)- สามเหลี่ยมมุมขวาล่าง ชี้ขึ้นไปที่กล่องด้านขวา - #two::after (Left Tail):
polygon(0 0, 100% 0, 0 80%)- สามเหลี่ยมมุมซ้ายล่าง ชี้ขึ้นไปที่กล่องด้านซ้าย
ตัวอย่างที่ 2: Comment Box เดียว + Highlight Text
<!DOCTYPE html>
<html>
<head>
<style>
.cb {
position: relative;
padding: 2%;
border-radius: 8%;
width: 15%;
box-shadow: inset 0 0 12px orange;
}
.cb::after {
content: "";
position: absolute;
height: 30px; width: 30px;
bottom: -30px; left: 80%;
box-shadow: inset 0 0 12px orange;
}
#one { left: 65%; }
#one::after { left: 10%; clip-path: polygon(0 0, 100% 0, 0 80%); }
span { background-color: lightblue; }
</style>
</head>
<body>
<div class="cb" id="one">accumsan</div>
<p>Aenean tempor lobortis porttitor. Nulla erat purus, commodo
<span>accumsan</span> viverra id, sollicitudin eget dui...
</p>
</body>
</html>
Modern Approach: CSS Custom Properties + Flexible Tail
.comment-box {
--tail-width: 20px;
--tail-height: 20px;
--tail-position: 20px; /* ระยะจากขอบซ้าย */
position: relative;
padding: 1rem 1.5rem;
border-radius: 12px;
background: var(--bg, #fff);
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
max-width: 400px;
}
.comment-box::after {
content: "";
position: absolute;
bottom: calc(-1 * var(--tail-height));
left: var(--tail-position);
width: var(--tail-width);
height: var(--tail-height);
background: var(--bg, #fff);
clip-path: polygon(0 0, 100% 0, 50% 100%);
/* Drop shadow สำหรับหาง */
filter: drop-shadow(0 2px 4px rgba(0,0,0,0.1));
}
/* Right-aligned tail */
.comment-box.right::after {
left: auto;
right: var(--tail-position);
clip-path: polygon(0 0, 100% 0, 50% 100%);
}
/* Top tail */
.comment-box.top::after {
top: calc(-1 * var(--tail-height));
bottom: auto;
clip-path: polygon(0 100%, 100% 100%, 50% 0);
}
HTML Usage
<div class="comment-box" style="--bg: #e3f2fd; --tail-position: 30px;"> <p>This is a comment with left tail</p> </div> <div class="comment-box right" style="--bg: #fce4ec; --tail-position: 30px;"> <p>This comment has right tail</p> </div>
Clip-path Patterns สำหรับ Tail รูปแบบต่างๆ
| รูปแบบ | Polygon | คำอธิบาย |
|---|---|---|
| Triangle (Center) | polygon(0 0, 100% 0, 50% 100%) | หางสามเหลี่ยมกลาง |
| Triangle (Left) | polygon(0 0, 100% 0, 0 100%) | หางชี้ซ้าย |
| Triangle (Right) | polygon(0 0, 100% 0, 100% 100%) | หางชี้ขวา |
| Curved (SVG Path) | ใช้ path() หรือ SVG | หางโค้งมน สวยกว่า |
| Rect + Triangle | polygon(0 0, 100% 0, 100% 60%, 50% 100%, 0 60%) | หางสี่เหลี่ยม+สามเหลี่ยม |
Accessibility
- ใช้
<blockquote>หรือ<div role="comment">สำหรับ Semantic - เพิ่ม
aria-labelหากไม่มี Avatar/Name - Tail เป็น Decoration เท่านั้น ใช้
aria-hidden="true"บน Pseudo-element (Auto)