<h1>Speech balloon without pseudo-elements</h1>
<div class="layout">
<p class="speech-balloon dir-top-left">Top-Left</p>
<p class="speech-balloon dir-top-center">Top-Center</p>
<p class="speech-balloon dir-top-right">Top-Right</p>
</div>
<div class="layout">
<p class="speech-balloon dir-bottom-left">Bottom-Left</p>
<p class="speech-balloon dir-bottom-center">Bottom-Center</p>
<p class="speech-balloon dir-bottom-right">Bottom-Right</p>
</div>
<div class="layout">
<p class="speech-balloon dir-left-top">Left-Top</p>
<p class="speech-balloon dir-left-center">Left-Center</p>
<p class="speech-balloon dir-left-bottom">Left-Bottom</p>
</div>
<div class="layout">
<p class="speech-balloon dir-right-top">Right-Top</p>
<p class="speech-balloon dir-right-center">Right-Center</p>
<p class="speech-balloon dir-right-bottom">Right-Bottom</p>
</div>
body {
background: #c0c0c0;
margin: 32px;
}
h1 {
inline-size: fit-content;
margin-inline: auto;
}
.layout {
display: flex;
flex-flow: wrap;
gap: 32px;
justify-content: center;
}
.speech-balloon {
& {
--background-color: #fff;
background: var(--background-color);
border-radius: 16px;
box-sizing: border-box;
inline-size: fit-content;
min-width: 48px;
min-height: 48px;
padding: 32px;
}
&[class*=" dir-top-"] {
box-shadow: 0 -32px 0 -16px var(--background-color);
}
&.dir-top-left {
clip-path: polygon(
0% 0%,
16px 0%,
16px -16px,
32px 0%,
100% 0%,
100% 100%,
0% 100%
);
}
&.dir-top-center {
clip-path: polygon(
0% 0%,
calc(50% - 8px) 0%,
50% -16px,
calc(50% + 8px) 0%,
100% 0%,
100% 100%,
0% 100%
);
}
&.dir-top-right {
clip-path: polygon(
0% 0%,
calc(100% - 32px) 0%,
calc(100% - 16px) -16px,
calc(100% - 16px) 0%,
100% 0%,
100% 100%,
0% 100%
);
}
&[class*=" dir-bottom-"] {
box-shadow: 0 32px 0 -16px var(--background-color);
}
&.dir-bottom-left {
clip-path: polygon(
0% 0%,
100% 0%,
100% 100%,
32px 100%,
16px calc(100% + 16px),
16px 100%,
0% 100%
);
}
&.dir-bottom-center {
clip-path: polygon(
0% 0%,
100% 0%,
100% 100%,
calc(50% + 8px) 100%,
50% calc(100% + 16px),
calc(50% - 8px) 100%,
0% 100%
);
}
&.dir-bottom-right {
clip-path: polygon(
0% 0%,
100% 0%,
100% 100%,
calc(100% - 16px) 100%,
calc(100% - 16px) calc(100% + 16px),
calc(100% - 32px) 100%,
0% 100%
);
}
&[class*=" dir-left-"] {
box-shadow: -32px 0 0 -16px var(--background-color);
}
&.dir-left-top {
clip-path: polygon(
0% 0%,
100% 0%,
100% 100%,
0% 100%,
0% 32px,
-16px 16px,
0% 16px
);
}
&.dir-left-center {
clip-path: polygon(
0% 0%,
100% 0%,
100% 100%,
0% 100%,
0% calc(50% + 8px),
-16px 50%,
0% calc(50% - 8px)
);
}
&.dir-left-bottom {
clip-path: polygon(
0% 0%,
100% 0%,
100% 100%,
0% 100%,
0% calc(100% - 16px),
-16px calc(100% - 16px),
0% calc(100% - 32px)
);
}
&[class*=" dir-right-"] {
box-shadow: 32px 0 0 -16px var(--background-color);
}
&.dir-right-top {
clip-path: polygon(
0% 0%,
100% 0%,
100% 16px,
calc(100% + 16px) 16px,
100% 32px,
100% 100%,
0% 100%
);
}
&.dir-right-center {
clip-path: polygon(
0% 0%,
100% 0%,
100% calc(50% - 8px),
calc(100% + 16px) 50%,
100% calc(50% + 8px),
100% 100%,
0% 100%
);
}
&.dir-right-bottom {
clip-path: polygon(
0% 0%,
100% 0%,
100% calc(100% - 32px),
calc(100% + 16px) calc(100% - 16px),
100% calc(100% - 16px),
100% 100%,
0% 100%
);
}
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.