下拉菜单未正常下拉(CSS/HTML/JS):菜单偏移至右侧求助
导航栏下拉菜单偏移问题修复方案
问题描述
尝试为导航栏的“Snooze Land”项实现下方展开的下拉菜单,但菜单始终偏移到导航栏右侧,修改display属性为block会导致导航栏布局混乱。
原始代码
HTML代码
<!DOCTYPE html> <html lang=""> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title></title> <link rel="stylesheet" href="styles.css"> </head> <body> <nav> <ul> <li><a href="#meetArtist">Slothie's Nests</a></li> <li id="snooze"><a href="#assignments" >Snooze Land</a></li> <ul id="test"> <li><a href="#">Services-1</a></li> <li><a href="#">Services-2</a></li> </ul> <li><a href="#snoozelings">Mini Games</a></li> <li><a href="#contact">Social Web</a></li> <li><a href="#contact">Log Out</a></li> </ul> </nav> <script> document.getElementById("snooze").addEventListener("mouseover", function () { document.getElementById('test').style.display = 'inline-block'; console.log('attempt'); document.getElementById("snooze").addEventListener("mouseout", function () { document.getElementById('test').style.display = 'none'; }) }) </script> </body> </html>
CSS代码
/* Universal Styles */ html { scroll-padding-top: 8em; font-size: 10px; font-family: Karla, serif; } body { display: flex; justify-content: center; background-image: url(resources/PurpleSquares.png); background-repeat: repeat; background-size: 290px; background-attachment: fixed; text-align: center; margin-top: 6rem; } .body-container { display: flex; flex-direction: column; align-items: center; width: 70%; height: 100rem; background-color: #eff7fa; } .art-container { display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; } .art { grid-column: 1 / span 1; grid-row: 1 / span 1; } .arttwo { grid-column: 2 / span 1; grid-row: 1 / span 1; } .artthree { grid-column: 1 / span 1; grid-row: 2 / span 1; } .artfour { grid-column: 2 / span 1; grid-row: 2 / span 1; } img { width: 25rem; } /* Nav Styles */ nav { margin-top: .5rem; background-color: white; position: fixed; width: 100%; height: 3rem; border-top: gray 2px solid; border-bottom: gray 2px solid; padding-top: .5rem; padding-bottom: .5rem; top: 0; z-index: 2; display: flex; align-items: center; justify-content: center; } nav li { display: inline-block; padding-right: 10px; padding-top: .5rem; padding-bottom: .5rem; font-size: 2rem; } nav a { background-color: transparent; border: 0px solid; font-weight: 300; padding: 0 4rem; color: black; text-decoration: none; font-size: rem; } nav a:hover { opacity: 100%; background-color: #F8F8F8; padding-top: .8rem; padding-bottom: .8rem; border-radius: 10px; } .line { border-width: 2px; background-color: pink; z-index: 1; } nav ul ul { display: none; } #test { display: none; }
修复步骤
修正HTML结构
下拉菜单的<ul id="test">必须嵌套在对应的父<li id="snooze">内部,否则会被当作导航栏的同级元素,导致布局偏移。修改后结构如下:<li id="snooze"> <a href="#assignments">Snooze Land</a> <ul id="test"> <li><a href="#">Services-1</a></li> <li><a href="#">Services-2</a></li> </ul> </li>设置父元素相对定位
给父<li>添加相对定位,让下拉菜单可以基于它定位:#snooze { position: relative; }调整下拉菜单CSS样式
把下拉菜单设置为绝对定位,脱离文档流,避免影响导航栏布局,同时让它显示在父元素正下方:#test { display: none; position: absolute; top: 100%; /* 紧贴父元素底部 */ left: 0; background-color: white; border: 2px solid gray; border-top: none; /* 和导航栏底部边框衔接 */ padding: 0; margin: 0; width: auto; white-space: nowrap; /* 防止菜单项换行 */ } #test li { display: block; /* 菜单项垂直排列 */ padding: 0.5rem 4rem; font-size: 2rem; }优化JS事件绑定
避免嵌套绑定事件,改用mouseenter和mouseleave(比mouseover/mouseout更适合菜单场景,不会因为子元素触发事件):const snoozeItem = document.getElementById("snooze"); const dropdownMenu = document.getElementById("test"); snoozeItem.addEventListener("mouseenter", () => { dropdownMenu.style.display = "block"; }); snoozeItem.addEventListener("mouseleave", () => { dropdownMenu.style.display = "none"; });
效果说明
修改后,下拉菜单会准确显示在“Snooze Land”项的正下方,不会偏移到导航栏右侧,同时展开/收起不会影响导航栏的整体布局。
内容的提问来源于stack exchange,提问作者Megan Caza
相关产品推荐
相关产品推荐

