导航栏捐赠按钮内添加跳动CSS心形图标问题及解决
导航栏捐赠按钮左侧添加跳动心形图标的实现方案
问题背景
需要在导航栏的捐赠按钮内,「Donate」文字左侧添加一个跳动的心形图标。尝试用CSS制作心形后,出现了心形位置偏离按钮、形状显示异常或按钮布局被拆分的问题,希望实现心形稳定位于按钮内部文字左侧的效果。
初始代码
CSS
.donate-btn>a { text-align: center; color: #fff; text-decoration: none; background-color: #ca0e17; padding: 5px 10px 5px 35px; border-radius: 5px; margin-left: 20px; } .box-heartbeat { width: 15px; height: 15px; background: #fff; transform: rotate(-45deg); box-shadow: 0 2px 20px rgba(0, 0, 0, 0.5); animation: heartbeat 0.8s linear infinite; position: absolute; top: 15px; left: 30px; } .box-heartbeat:before { content: ''; position: absolute; width: 15px; height: 15px; background: #fff; top: -50%; border-radius: 15px; } .box-heartbeat:after { content: ''; position: absolute; width: 15px; height: 15px; background: #fff; right: -50%; border-radius: 15px; } @keyframes heartbeat { 0% { transform: rotate(-45deg) scale(1.05); } 100% { transform: rotate(-45deg) scale(1.0); } 100% { transform: rotate(-45deg) scale(0.9); } }
HTML
<ul> <li> <div class="donate-btn"> <a href="{!! route('marketing.donate') !!}">{{ trans('layouts/master/navigation.donate') }}</a> </div> </li> </ul>
已验证的解决方案
通过以下步骤解决了问题,同时保证移动端适配:
- 给按钮容器
.donate-btn添加position: relative,作为绝对定位心形的参考基准,避免心形脱离按钮布局 - 保留按钮左侧的
padding: 5px 10px 5px 35px,为心形预留足够空间 - 调整心形的定位方式,使用
top: 50%配合translateY(-50%)实现垂直居中,避免固定值导致的适配问题 - 将心形元素插入到按钮容器内,确保结构关联
修改后的核心代码
CSS
.donate-btn { position: relative; /* 新增:设置为绝对定位的父容器 */ } .donate-btn>a { text-align: center; color: #fff; text-decoration: none; background-color: #ca0e17; padding: 5px 10px 5px 35px; border-radius: 5px; margin-left: 20px; } .box-heartbeat { width: 15px; height: 15px; background: #fff; transform: rotate(-45deg) translateY(-50%); /* 合并旋转与垂直居中 */ box-shadow: 0 2px 20px rgba(0,0,0,0.5); animation: heartbeat 0.9s linear infinite; position: absolute; top: 50%; left: 15px; /* 调整左侧距离,适配按钮内边距 */ } /* 保持心形的before/after样式不变 */ .box-heartbeat:before { content: ''; position: absolute; width: 15px; height: 15px; background: #fff; top: -50%; border-radius: 15px; } .box-heartbeat:after { content: ''; position: absolute; width: 15px; height: 15px; background: #fff; right: -50%; border-radius: 15px; } /* 优化动画关键帧,修复重复的100%节点问题 */ @keyframes heartbeat { 0% { transform: rotate(-45deg) scale(1); } 25% { transform: rotate(-45deg) scale(1.1); } 50% { transform: rotate(-45deg) scale(1); } 75% { transform: rotate(-45deg) scale(0.9); } 100% { transform: rotate(-45deg) scale(1); } }
HTML
<ul> <li> <div class="donate-btn"> <div class="box-heartbeat"></div> <a href="{!! route('marketing.donate') !!}">{{ trans('layouts/master/navigation.donate') }}</a> </div> </li> </ul>
更优实现思路
如果想简化HTML结构,可以用按钮的::before/::after伪元素替代单独的.box-heartbeatdiv,减少DOM节点:
.donate-btn>a { position: relative; /* 将按钮本身设为定位容器 */ text-align: center; color: #fff; text-decoration: none; background-color: #ca0e17; padding: 5px 10px 5px 35px; border-radius: 5px; margin-left: 20px; } /* 心形主体 */ .donate-btn>a::before { content: ''; width: 15px; height: 15px; background: #fff; transform: rotate(-45deg) translateY(-50%); box-shadow: 0 2px 20px rgba(0,0,0,0.5); animation: heartbeat 0.9s linear infinite; position: absolute; top: 50%; left: 15px; } /* 心形左半圆 */ .donate-btn>a::after { content: ''; width: 15px; height: 15px; background: #fff; position: absolute; top: calc(50% - 7.5px); left: 15px; border-radius: 50%; } /* 心形右半圆 */ .donate-btn>a::before { content: ''; width: 15px; height: 15px; background: #fff; position: absolute; top: calc(50% - 15px); left: 22.5px; border-radius: 50%; } /* 心跳动画保持优化后的版本 */ @keyframes heartbeat { 0% { transform: rotate(-45deg) scale(1); } 25% { transform: rotate(-45deg) scale(1.1); } 50% { transform: rotate(-45deg) scale(1); } 75% { transform: rotate(-45deg) scale(0.9); } 100% { transform: rotate(-45deg) scale(1); } }
对应的HTML可以简化为:
<ul> <li> <div class="donate-btn"> <a href="{!! route('marketing.donate') !!}">{{ trans('layouts/master/navigation.donate') }}</a> </div> </li> </ul>
内容的提问来源于stack exchange,提问作者Ryan M
相关产品推荐
相关产品推荐

