CSS伪元素动画问题:导航项hover时父元素背景异常
导航栏悬停背景动画问题解决
问题描述
我制作了一个包含2个锚点(a)元素的导航栏,使用CSS的::before和::after伪元素实现了鼠标悬停(:hover)时背景动态变化的动画,但目前存在问题:悬停时整个父元素的背景发生变化,而非仅当前导航项。
我尝试过给每个锚点添加包裹div、删除部分div以简化结构,同时也修改过CSS相关配置,但这些操作都未能解决问题。
原代码
CSS
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@100;300;400;500;700;900&display=swap'); *{ padding:0; margin: 0; outline: none; } body{ font-family: 'Roboto', sans-serif; font-size: 18px; width:100%; background-color: #ffffff; } a{ text-decoration: none; color: #000000; } .navbar{ display: flex; padding: 1rem 0; align-items: stretch; /* background-color: green; */ } .container{ display: flex; /* background-color: #1e1e2b; */ align-items: stretch; width: 100%; margin: 0 auto; max-width: 1152px; } .MonLogo_image{ display: flex; padding: 0.5rem 0.75rem; align-items: center; } .nav-buttons { /* background-color: rgb(0, 255, 255); */ display:flex; align-items: stretch; text-align: center; position: relative; padding: 0.5em 1em; } .Monlogo{ /* background-color: #ff4444; */ position:relative; } .nav-bar-items{ display: flex; align-items: center; padding: 0.5rem 0.75rem; transition: .5s ease; } .material-symbols-outlined{ /* background-color: rgb(230, 174, 174); */ font-size: 2em; padding-right: 10px; } .nav-bar-item-container{ width: 400px; } /** A partir de là c'est pour les transitions des boutons de navigations en haut */ .nav-bar-items::before { content: ''; position: absolute; left: 0; bottom: 0; height: 0.1em; width: 0; background-color: rgb(228, 156, 22); transition: .5s ease; } .nav-bar-items:hover { color: #ffffff; transition-delay: .5s; } .nav-bar-items:hover::before { width: 100%; } .nav-bar-items::after { content: ''; position: absolute; left: 0; bottom: 0; height: 0; width: 100%; background-color: rgb(228, 156, 22); transition: .4s ease; z-index: -1; } .nav-bar-items:hover::after { height: 100%; transition-delay: 0.4s; color: #fff; } /* *et ca s'arrête là */
HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet" /> <link rel="stylesheet" href="style.css"> <script src="MyScript.js"></script> <title>CV Personnel N°1</title> </head> <body> <nav class="navbar"> <div class="container"> <div class="Monlogo"> <img class="MonLogo_image" src="images/logoplussobre2.png" alt="Logo Jason"> </div> <div class="nav-buttons"> <div class="nav-bar-item-container"> <a class="nav-bar-items" href=""><span class="material-symbols-outlined nav-icon-about">task</span>Projets</a> </div> <div class="nav-bar-item-container"> <a class="nav-bar-items" href="..."><span class="material-symbols-outlined nav-icon-contact">local_post_office</span>Contacts</a> </div> </div> </div> </nav> <header class="container"> </header> </body> </html>
问题根源
问题出在定位关系上:
- 给
.nav-bar-items的伪元素设置了position:absolute,但.nav-bar-items本身没有设置position:relative,导致伪元素会向上寻找最近的带有position属性的父元素(也就是.nav-buttons)作为定位基准。 - 所以hover时,伪元素的宽高会覆盖整个
.nav-buttons容器,而不是单个导航项。
修复方案
- 给
.nav-bar-items添加position:relative,让伪元素以当前导航项为定位基准。 - 移除
.nav-buttons的position:relative,避免干扰。 - 调整
.nav-bar-item-container的宽度设置,让导航项自适应内容(如果不需要固定宽度的话)。
修改后的CSS
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@100;300;400;500;700;900&display=swap'); *{ padding:0; margin: 0; outline: none; } body{ font-family: 'Roboto', sans-serif; font-size: 18px; width:100%; background-color: #ffffff; } a{ text-decoration: none; color: #000000; } .navbar{ display: flex; padding: 1rem 0; align-items: stretch; } .container{ display: flex; align-items: stretch; width: 100%; margin: 0 auto; max-width: 1152px; } .MonLogo_image{ display: flex; padding: 0.5rem 0.75rem; align-items: center; } .nav-buttons { display:flex; align-items: stretch; text-align: center; /* 移除position:relative */ padding: 0.5em 1em; } .Monlogo{ position:relative; } .nav-bar-items{ display: flex; align-items: center; padding: 0.5rem 0.75rem; transition: .5s ease; /* 添加position:relative,让伪元素以当前元素为基准定位 */ position: relative; } .material-symbols-outlined{ font-size: 2em; padding-right: 10px; } .nav-bar-item-container{ /* 移除固定宽度,让导航项自适应 */ /* width: 400px; */ display: flex; align-items: center; } /** 导航项悬停动画 */ .nav-bar-items::before { content: ''; position: absolute; left: 0; bottom: 0; height: 0.1em; width: 0; background-color: rgb(228, 156, 22); transition: .5s ease; } .nav-bar-items:hover { color: #ffffff; transition-delay: .5s; } .nav-bar-items:hover::before { width: 100%; } .nav-bar-items::after { content: ''; position: absolute; left: 0; bottom: 0; height: 0; width: 100%; background-color: rgb(228, 156, 22); transition: .4s ease; z-index: -1; } .nav-bar-items:hover::after { height: 100%; transition-delay: 0.4s; color: #fff; }
修改后的HTML(可选,结构可简化)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet" /> <link rel="stylesheet" href="style.css"> <title>CV Personnel N°1</title> </head> <body> <nav class="navbar"> <div class="container"> <div class="Monlogo"> <img class="MonLogo_image" src="images/logoplussobre2.png" alt="Logo Jason"> </div> <div class="nav-buttons"> <a class="nav-bar-items" href=""><span class="material-symbols-outlined nav-icon-about">task</span>Projets</a> <a class="nav-bar-items" href="..."><span class="material-symbols-outlined nav-icon-contact">local_post_office</span>Contacts</a> </div> </div> </nav> </body> </html>
效果说明
修改后,每个导航项的伪元素会以自身为定位基准,hover时只会给当前导航项添加背景动画,不会影响整个父容器。
内容的提问来源于stack exchange,提问作者Patate
相关产品推荐
相关产品推荐

