文章最后更新时间:2024年04月13日
6、灵活多变的障眼法
上述使用::after简单地绘制气泡对话框的尾巴,然而复杂一点的带边框气泡对话框能否也使用伪元素绘制呢。看到这里先不要往下看代码,自行思考1分钟想想实现方法。
答案当然是可行的。以下是整个带边框气泡对话框的拆解,整体由三部分组成:带边框圆角矩形、黑色三角形、橙色三角形。先将两个三角形错位叠加生成一个箭头状的图形,再将该图形叠加到带边框圆角矩形的右边,最后将黑色三角形着色成白色,就能得到上图的带边框气泡对话框了。
<div class="bubble-empty-box">iCSS</div>
.bubble-empty-box { position: relative; border: 2px solid #f90; border-radius: 5px; width: 200px; height: 50px; line-height: 46px; text-align: center; font-size: 20px; color: #f90; &::before { position: absolute; left: 100%; top: 50%; margin: -5px 0 0 2px; border: 5px solid transparent; border-left-color: #f90; content: ""; } &::after { position: absolute; left: 100%; top: 50%; margin-top: -4px; border: 4px solid transparent; border-left-color: #fff; content: ""; } }
整体实现思路就是一种障眼法,正确来说就是将图形错位叠加产生另一种效果,在平面设计中叫做「占位叠加」。有了这种设计思想,其实能使用CSS创造出很多意向不到的障眼法效果。
当你遇见心仪妹纸时,心里噗通噗通地跳动,此时此刻可用纯CSS描绘你的心情。使用单个<div>结合::before和::after,通过错位叠加的方式生成一个心形。在叠加前看看以下图形,是不是发现很像米老鼠呢。
- 声明<div>形状为正方形并以中心顺时针旋转45deg
- 声明::before和::after继承<div>尺寸并分别绝对定位到左上角和右上角
- 声明::before和::after的圆角率为100%
<div class="heart-shape"></div>
.heart-shape { position: relative; width: 200px; height: 200px; background-color: #f66; transform: rotate(45deg); &::before, &::after { position: absolute; left: 0; top: 0; border-radius: 100%; width: 100%; height: 100%; background-color: #f66; content: ""; } &::before { transform: translateX(-50%); } &::after { transform: translateY(-50%); } }
最后巧妙利用transform将::before和::after平移到相应位置产生叠加错觉。这时分别对::before和::after着色,看看其中的奥秘。
在这个基础上来一个更高级的玩法,添加渐变效果让心形变得更么么哒。
- 声明<div>从上到下(实际效果是从右上角到左下角)渐变着色
- 由于::before从旋转后的<div>X轴往左平移过去,所以其着色效果与<div>一致
- 由于::after从旋转后的<div>Y轴往上平移过去,所以其中线位置渐变着色必须与<div>顶部渐变着色的颜色一致(具体往下分析)
整体渐变效果的重点在::after上,由于::after下半部叠加在<div>上,所以下半部颜色必须透明,上半部底部(中线位置)渐变着色必须与<div>顶部渐变着色的颜色一致,这样才能做到无缝衔接。通过Windows系统和MacOS系统的测试,在Windows系统下的透明渐变位置需在51%的地方开始,这与屏幕设备的分辨率和广色域有关。
最后为了让渐变心形看起来更具立体感,给它绘制个阴影吧。若觉得这个渐变动感心形很美,可随手转发给女友哇!
<div class="gradient-heart-shape"></div>
.gradient-heart-shape { position: relative; width: 200px; height: 200px; background-image: linear-gradient(to bottom, #09f, #f66); box-shadow: 0 0 20px rgba(#000, .8); transform: rotate(45deg); &::before, &::after { position: absolute; left: 0; top: 0; border-radius: 100%; width: 100%; height: 100%; content: ""; } &::before { background-image: linear-gradient(to bottom, #09f, #f66); transform: translateX(-50%); } &::after { background-image: linear-gradient(to bottom, #3c9, #09f 50%, transparent 50%, transparent); transform: translateY(-50%); } }
还没有评论,来说两句吧...