CSS实现:hover::after从relative到absolute的平滑过渡效果
问题原因
你写的过渡效果不生效,核心是三个错误:
- 把
::after伪元素的定义全写在了:hover状态下,意味着鼠标没悬停时这个伪元素根本不存在,浏览器无法对「从无到有生成」的元素执行过渡动画 - 过渡属性写错了位置,且指定了过渡
height,但你实际需要变化的是下划线的可见状态(宽度/透明度),不是父元素高度 - 额外问题:HTML标签闭合错误,
<div/>不是合法的普通div闭合写法,且不需要在导航项内部嵌套空div。
正确实现方案
核心思路是默认就创建好伪元素,把它的初始状态设为不可见(宽度为0/透明度为0),把过渡属性加在伪元素的默认样式上,hover时只修改它的可见状态属性即可。
完整可运行代码
.nav-item { display: flex; align-items: center; color: #ab9b8c; font-size: 20px; letter-spacing: 1.5px; text-decoration: none; height: 100%; cursor: pointer; position: relative; } /* 默认就定义伪元素,初始宽度为0不可见 */ .nav-item::after { content: ''; position: absolute; bottom: -1px; /* 左对齐:要从左向右展开效果就开这个,删掉下面两行居中的代码 left: 0; */ /* 居中对齐:要从中间向两边展开效果用这两行 */ left: 50%; transform: translateX(-50%); width: 0; height: 3px; border-radius: 200px; background: #9f9182; /* 用背景填充比border更稳定,不会出现尺寸偏移 */ /* 过渡属性加在伪元素默认状态,指定宽度变化的动画时长、缓动效果 */ transition: width 0.3s ease; } /* hover时仅修改宽度到目标值即可触发过渡 */ .nav-item:hover::after { width: 30px; }
<div class="nav-item">test</div>
可调参数说明
- 过渡速度:修改
transition里的时长值即可,导航下划线常用0.2s-0.4s的时长,你原来写的2s会显得非常迟钝 - 展开方向:按照代码里的注释切换left属性的写法,就能实现左往右展开/中间向两边展开的不同效果
- 如果要做多个导航项的悬停下划线效果,给所有导航项复用同一个类名和对应伪元素样式即可
内容的提问来源于stack exchange,提问作者Caick Sakay
相关产品推荐
相关产品推荐

