纯 CSS 实现导航栏下划线滑动需用 .nav::after 伪元素配合 transform: translateX() 和 transition,避免 border-bottom 无法定位与滑动;必须用绝对定位+相对定位父容器,推荐 :has()(现代浏览器)或手动 nth-child 规则;移动端应优先使用 transform 而非 left 以启用硬件加速,动画时长设为 0.3s、缓动用 ease-out。
transition 实现导航栏下划线滑动,关键在伪元素 + 定位切换纯 CSS 实现下划线跟随当前项滑动,不靠 JS,核心是用 ::after 伪元素画线,再通过 transform: translateX() 或 left 移动它,配合 transition 做缓动。直接写 width 或 background-position 动画会卡顿或无法精准对齐。
a 加 border-bottom 并 transition?因为 border-bottom 是静态样式,无法独立定位到某个菜单项下方;若强行给每个 a 单独设 border-bottom,hover 时只能“出现/消失”,做不到平滑滑动到目标位置。真正可 transition 的必须是同一个 DOM 节点(比如一个共享的 ::after),且它的 left / transform 值能随不同 a 的位置动态计算。
需要结合 position: relative 和 position: absolute 定位:
.nav)设 position: relative
a 设 position: relative(为后续获取 offsetLeft 做准备,但纯 CSS 不需要 JS,所以改用 transform + calc() 配合 CSS 变量更可控).nav::after 设 position: absolute,bottom: 0,宽度固定(或用 width: 100%),再用 transform: translateX() 移动实际推荐用 CSS 自定义属性 + :has()(现代浏览器)或逐个写 hover 规则(兼容性更好):
.nav {
position: relative;
display: flex;
}
.nav::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 80px;
height: 3px;
background: #007bff;
border-radius: 2px;
transition: transform 0.3s ease, width 0.3s ease;
}
.nav a {
padding: 12px 20px;
margin: 0 8px;
position: relative;
text-decoration: none;
color: #333;
}
/ 手动为每个 a 设置 hover 时的 translateX /
.nav a:nth-child(1):hover ~ .nav::after {
transform: translateX(0);
width: 80px;
}
.nav a:nth-child(2):hover ~ .nav::after {
transform: translateX(calc(80px + 16px));
width: 80px;
}
.nav a:nth-child(3):hover ~ .nav::after {
transform: translateX(calc(160px + 32px));
width: 80px;
}
⚠️ 注意:上面的 ~ 选择器无效(::after 是 .nav 的伪元素,不是 a 的兄弟)。正确写法是把伪元素挂到每个 a 上,或用 JS —— 但纯 CSS
更稳的方式是:把 ::after 放在 .nav 内部一个空 span 上,再用 JS 控制;若坚持零 JS,则必须用 :has()(Chrome 105+、Safari 15.4+):
.nav {
position: relative;
}
.nav::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 3px;
background: #007bff;
transition: all 0.3s ease;
}
.nav a:hover::after {
content: '';
position: absolute;
bottom: -3px;
left: 0;
width: 100%;
height: 3px;
background: inherit;
transition: none;
}
但这样每项都画一条线,不是“滑动一条线”。所以最实用的方案仍是:用一个绝对定位的 span.underline,配合 JS 监听 mouseenter 获取 getBoundingClientRect(),设置 left 和 width —— 如果你真不想写 JS,就老老实实写 N 条 hover 规则,用 nth-child 算好像素偏移。
transform 和 opacity 是仅有的能高效硬件加速的属性,left/top 会触发重排(layout),尤其在频繁 hover 时掉帧。所以务必用 transform: translateX() 替代 left;同时避免在 ::after 中使用 box-shadow 或渐变背景,它们在低端设备上动画易糊。
0.2s–0.35s,太长显得拖沓,太短看不出滑动感ease-out 比 ease 更自然(起始快,结束缓)width: 80px,改用 width: max-content + transform: scaleX() 配合 origin
真正难的不是写出来,而是让那条线在各种字号、缩放、RTL 页面里都对得准——这往往需要加 transform: translateZ(0) 强制 GPU 渲染,或用 will-change: transform 提前告知浏览器。
# css
# css3
# js
# 伪元素
# 浏览器
# safari
# 移动端适配
# 硬件加速
# 绝对定位
# 相对定位
# 为什么
# chrome
相关栏目:
【
Google疑问12 】
【
Facebook疑问10 】
【
网络优化76771 】
【
技术知识130152 】
【
IDC云计算60162 】
【
营销推广131313 】
【
AI优化88182 】
【
百度推广37138 】
【
网站推荐60173 】
【
精选阅读31334 】
相关推荐:
Win11怎么调整屏幕亮度_Windows 11调节显示器亮度护眼设置【步骤】
Win11怎么更改任务栏颜色_Windows11个性化重音色设置
Windows怎样拦截QQ浏览器广告_Windows拦截QQ浏览器广告方法【方法】
如何使用Golang实现微服务状态监控_Golang服务运行状态采集方法
为什么Go建议使用error接口作为错误返回_Go Error接口设计原因说明
Windows服务持续崩溃怎样修复_系统服务保护机制解析
如何使用Golang sync.Map实现并发安全map_避免锁竞争
英国搜索:多数英国人认为语言搜索是未来搜索
Win11如何设置开机问候语 Win11修改登录界面提示【技巧】
php8.4如何实现队列任务_php8.4redis队列简单实现方法【教程】
Win11怎么清理C盘虚拟内存_Win11清理虚拟内存设置【教程】
Win11怎么设置按流量计费_Win11限制后台流量消耗【网络】
Windows 11登录时提示“用户配置文件服务登录失败”怎么办_Windows 11修复损坏的用户配置文件
如何在 Django 中安全修改用户密码而不使会话失效
c++怎么实现大文件的分块读写_c++ 文件指针seekp与seekg偏移控制【方法】
VSC怎么配置PHP的Xdebug_远程调试设置步骤【详解】
php485在macos下怎么配置_php485 macOS系统配置指南【解答】
Win11怎么查看显卡显存_查询Win11显卡详细参数方法【步骤】
c++如何判断文件是否存在_c++ filesystem库用法
Win10怎样安装Word样式库_Win10安装Word样式教程【步骤】
c++中如何使用auto关键字_c++11类型推导用法说明
Win11怎么设置环境变量_Win11配置Path路径变量【详解】
Python路径拼接规范_跨平台处理说明【指导】
Python配置文件操作教程_JSONINIYAML解析与应用实战
Win11怎么忘记WiFi网络_Win11删除已保存无线连接【教程】
如何在Golang中写入JSON文件_保存结构体数据到文件
c++ unordered_map怎么用 c++哈希表用法【教程】
C++ static_cast和dynamic_cast区别_C++静态转换与动态类型安全转换
如何使用Golang实现聊天室消息存档_存储聊天记录到文件
Python项目回滚策略_发布安全说明【指导】
Windows蓝屏错误0x00000023怎么修复_FAT文件系统错误处理
php下载安装选zip还是msi格式_两种安装包对比【教程】
c++中explicit(bool)的用法 c++条件性explicit【C++20】
Python多进程教程_multiprocessing模块实战
Drupal 中 HTML 链接被重复转义导致渲染异常的解决方案
c++中的CRTP是什么 c++奇异递归模板模式【进阶】
Win11文件扩展名怎么显示 Win11查看文件后缀名设置【步骤】
Python技术债务管理_长期维护解析【教程】
Win11此电脑不在桌面上_Windows 11桌面图标设置找回【步骤】
如何在Golang中实现并发消息队列消费者_Golang channel消息消费实践
Win11如何添加/删除输入法 Win11切换中英文输入法快捷键【设置】
新手学PHP架构总混淆概念咋办_重点梳理【教程】
Windows10如何更改鼠标图标_Win10鼠标属性指针浏览
Win11怎样安装搜狗输入法_Win11安装搜狗输入法教程【步骤】
如何在Golang中实现RPC异步返回_Golang RPC异步处理与回调方法
c++如何用AFL++进行模糊测试 c++ Fuzzing入门【安全】
Win11怎么设置触控板手势_Windows11三指四指操作自定义
如何用::实现单例模式_php静态方法与作用域操作符应用【技巧】
Win11如何设置系统语言_Win11系统语言切换教程【攻略】
php本地部署后数据库连接报错_1045accessdenied错误解决方法详解【汇总】
2026-01-03
致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。