2022-10-22

使用 CSS 实现 iMessage 气泡

最最喜欢你,绿子。
什么程度?
像喜欢春天的熊一样。
已送达

我观察过多个社交软件的聊天气泡,觉得最好看的还是 iMessage 的气泡,端庄且优雅。

本文会简单分析不使用任何素材用 CSS 实现 iMessage 气泡,只会实现基本的外观形状,不会考虑所有的细节。形状方面实现的难点明显在于气泡的箭头部分,在继续之前,先说明几个简单的 CSS 属性。border-radiusborder-bottom-left-radiusborder-bottom-right-radius。第一个属性很常见,作用就是设置元素四个角的圆角;第二个 border-bottom-left-radius 作用也是设置元素圆角,不过仅控制元素左下角的圆角;第三个控制的是右下角的圆角。

根据第二个和第三个 CSS 属性名可以推测可能还存在 border-top-left-radiusborder-top-right-radius 分别控制左上角和右上角的圆角,是的,这两个属性存在,但在本文中不会用到。

简单了解 border-bottom-left-radiusborder-bottom-right-radius 后就可以实现气泡的箭头了。气泡箭头的原理其实很简单,就是两个不同背景颜色,不同圆角的元素使用 position 叠加在一起。

一图胜千言:

下面是气泡箭头的具体实现,你可以直接复制代码到一个新的 HTML 文件中,然后在浏览器预览。

html
<div class="container"> <div class="item"> <div class="before"></div> <div class="after border"></div> </div> <div class="item"> <div class="before"></div> <div class="after"></div> </div> </div> <style> .container { display: flex; align-items: center; justify-content: space-around; overflow: hidden; height: 176px; } .item { position: relative; height: 64px; width: 64px; } .before { position: absolute; bottom: 0; right: 0; height: 64px; width: 64px; border-bottom-left-radius: 75px; background-color: #007aff; } .after { position: absolute; bottom: -4px; right: 0; height: 70px; width: 32px; border-bottom-left-radius: 50px; background-color: white; z-index: 1; } .border { border: 2px solid black; } </style>

知道了气泡箭头的实现原理剩下的就比较简单了,无非就是一个圆角矩形和气泡箭头拼接在一起。这里使用 beforeafter 伪元素实现气泡箭头部分。

html
<div class="bubbles"> <div class="bubble"> <div class="bubble-content"> <div class="msg">最最喜欢你,绿子。</div> </div> </div> <div class="bubble left"> <div class="bubble-content"> <div class="msg">什么程度?</div> </div> </div> <div class="bubble"> <div class="bubble-content"> <div class="msg">像喜欢春天的熊一样。</div> <div class="state">已送达</div> </div> </div> </div> <style> :root { font-size: 16px; } .bubbles { max-width: 448px; margin: 0 auto; } .bubble { display: flex; justify-content: flex-end; } .bubble.left { justify-content: flex-start; } .bubble-content { margin-bottom: 4px; max-width: 75%; } .msg { position: relative; border-radius: 20px; padding: 6px 12px; font-size: 1rem; line-height: 1.5rem; background-color: #007aff; color: white; } .left .msg { background-color: #e6e5e8; color: black; } .msg::before { content: ""; position: absolute; bottom: 0; height: 20px; width: 20px; background-color: inherit; right: -8px; border-bottom-left-radius: 15px; } .left .msg::before { left: -8px; right: unset; border-bottom-left-radius: unset; border-bottom-right-radius: 15px; } .msg::after { content: ""; position: absolute; bottom: -1px; z-index: 1; height: 21px; width: 10px; background-color: white; right: -10px; border-bottom-left-radius: 10px; } .left .msg::after { left: -10px; right: unset; border-bottom-left-radius: unset; border-bottom-right-radius: 10px; } .state { text-align: right; font-size: 12px; line-height: 16px; color: #888; } </style>

此时的效果:

最最喜欢你,绿子。
什么程度?
像喜欢春天的熊一样。
已送达

到此,我们已经大致实现了 iMessage 气泡的外观。

参考

  1. vercel.com (Wayback Machine 归档)

更改日志

日期更改内容
2024-08-19修改文章措辞;更新实例代码;使用元素替换图片。
使用 CSS 实现 iMessage 气泡
作者
Yaowei Zou
发布日期
2022-10-22
许可协议
转载或引用本文时请遵守许可协议,注明出处,不得用于商业用途!