设置overflow:hidden后,导航栏滑出屏幕仍导致左侧边距增大
导航栏右滑隐藏时左侧空间异常增大的问题排查与修复
我尝试实现导航栏向右滑出屏幕的效果,但应用CSS规则right: -100%;时,左侧空间会增大,引发布局问题(截图见:
)。我已为所有父元素添加overflow: hidden,但问题仍未解决。以下是我的React组件及相关SCSS代码,请问哪里操作有误?
React组件:
import React, { useContext, useState } from 'react'; import { Link, NavLink } from 'react-router-dom'; import Logo from '../img/code.svg'; import { AuthContext } from '../context/authContext'; import { MdMenu } from "react-icons/md"; import { IoClose } from "react-icons/io5"; const links = ['News', 'Tutorials', 'Resources', 'Bootcamps']; const Navbar = () => { const [isMenuActive, setIsMenuActive] = useState(false); const { currentUser, logout } = useContext(AuthContext); const isAdminOrWriter = currentUser && (currentUser.role === 'admin' || currentUser.role === 'writer'); const handleMenuClick = () => { setIsMenuActive(!isMenuActive); }; return ( <div className='navbar'> <div className='nav-container'> <Link to='/'> <div className="logo"> <img src={Logo} alt=""/> <p className='logo-text'>JuanCDEV</p> </div> </Link> <div className={isMenuActive ? "links" : "links off"}> <div className="nav-links"> {links.map((link) => ( <NavLink end className='link' key={link} to={`/?category=${link.toLowerCase()}`}> <h6>{link}</h6> </NavLink> ))} </div> <div className="session"> {currentUser && ( <> <span className='session'>{currentUser.username}</span> <span className='session' onClick={logout}>Log out</span> </> )} {!currentUser && <Link className='link' to="/login">Login</Link>} </div> {isAdminOrWriter && <Link className='link' to='/write'> <div className='write-button'>Write</div> </Link>} </div> <div className="menu"> <div className={isMenuActive ? 'burger off' : 'burger'} onClick={handleMenuClick}> <MdMenu /> </div> <div className={isMenuActive ? 'close' : 'close off'} onClick={handleMenuClick}> <IoClose /> </div> </div> </div> </div> ); }; export default Navbar;
SCSS文件:
$lightGreen: #0353a4; @import 'sass-files/media-queries'; @import url("https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap"); @keyframes move { 0%, 49.99% { opacity: 0; z-index: 1; } 50%, 100% { opacity: 1; z-index: 5; } } body { padding: 0; margin: 0; font-family: roboto, sans-serif; text-decoration: none; background-color: #222831; overflow-x: hidden; @include small-screen { max-width: 800px; } } .app { display: flex; justify-content: center; .container { display: flex; flex-direction: column; align-items: center; width: 100%; .link { text-decoration: none; color: inherit; } h1 { font-size: 30px; color: #0353a4; margin-bottom: 20px; } .auth_container { padding: 0; margin: 0; box-sizing: border-box; display: flex; flex-direction: column; align-items: center; justify-content: center; background: rgb(0, 24, 69); background: linear-gradient(34deg, rgba(0, 24, 69, 1) 0%, rgba(0, 0, 0, 1) 49%); height: 100vh; width: 100vw; .card { border-radius: 30px; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.35); position: relative; overflow: hidden; background: linear-gradient(135deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.1)); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(10px); width: 800px; max-width: 100%; min-height: 650px; .form-container { display: flex; flex-direction: column; justify-content: center; align-items: center; position: absolute; top: 0; height: 100%; transition: all 0.6s ease-in-out; &.sign-in { left: 0; width: 50%; z-index: 10; } &.register { left: 0; width: 50%; opacity: 0; z-index: 1; } h1 { color: white; } form { display: flex; flex-direction: column; justify-content: center; gap: 20px; background: white; padding: 50px; width: 230px; min-height: 300px; border-radius: 3%; box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); margin-bottom: 40px; input { font-size: 14px; padding: 10px; border: none; border-bottom: 1px solid gray; margin-bottom: 20px; background-color: transparent; } input::placeholder { color: grey; } button { font-size: 14px; padding: 10px; border: none; background-color: #0466c8; color: white; cursor: pointer; border-radius: 3px; } p { display: flex; font-size: 14px; color: rgb(206, 14, 52); justify-content: center; align-items: center; height: auto; width: auto; background-color: rgba(199, 43, 74, 0.2); border-radius: 5px; margin: 10px; padding: 10px; text-align: center; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } span { font-size: 14px; text-align: center; a { text-decoration: none; color: #014f86; } } } } .toggle-container { position: absolute; top: 0; left: 50%; width: 60%; height: 100%; overflow: hidden; transition: all 0.6s ease-in-out; border-radius: 100px 0 0 100px; z-index: 1000; .toggle { height: 100%; width: 200%; background: linear-gradient(to right, #48bfe3, #0466c8); position: relative; left: -100%; transform: translateX(0); transition: all 0.6s ease-in-out; color: white; .toggle-panel { position: absolute; width: 50%; height: 100%; gap: 20px; .login-img { width: 300px; } h1 { color: #fff; } display: flex; align-items: center; justify-content: center; flex-direction: column; text-align: center; transition: all 0.6s ease-in-out; top: 0; padding: 0 30px; text-align: center; transform: translateX(0); } .toggle-left { transform: translateX(-200%); } .toggle-right { right: 0px; transform: translateX(0); } .toggle-left { transform: translateX(0); } } } } .form-container { &.active { &.sign-in { transform: translateX(100%); opacity: 0; z-index: 0; } &.register { transform: translateX(100%); opacity: 1; z-index: 5; animation: move 0.6s; } } } .toggle-container { &.active { transform: translateX(-100%); border-radius: 0px 150px 100px 0px; .toggle { transform: translateX(50%); .toggle-panel { padding: 0; &.toggle-left { padding-left: 30px; } } } } } } .navbar { width: 100%; background-color: #000; text-decoration: none; z-index: 2; display: flex; align-items: center; justify-content: center; overflow: hidden !important; .nav-container { padding: 10px 0px; display: flex; flex-direction: row; align-items: center; justify-content: space-between; color: white; width: 1024px; overflow: hidden !important; isolation: isolate; a { text-decoration: none; } .logo { display: flex; gap: 10px; padding-left: 10px; overflow: hidden; .logo-text { color: #fff; font-size: large; font-weight: bold; text-decoration: none; text-decoration-line: none; cursor: pointer; overflow: hidden; } img { width: 50px; cursor: pointer; overflow: hidden; } @include medium-screen { padding-left: 30px; } } .links { display: flex; align-items: center; gap: 8px; overflow: hidden; .nav-links { display: flex; align-items: center; gap: 15px; h6 { font-size: 16px; font-weight: 300; } span { cursor: pointer; } a { &::after { content: ""; height: 2px; width: 0%; background-color: #0353a4; display: block; position: relative; top: -34px; transition: width 0.4s ease; } &:hover::after { width: 100%; } } } .session { display: flex; gap: 15px; overflow: hidden; } .write-button { background-color: black; width: 50px; height: 50px; border-radius: 50%; display: flex; align-items: center; color: #fff; justify-content: center; font-weight: 300; border: 1px solid black; transition: all; transition-duration: 250ms; overflow: hidden; &:hover, &:focus { color: #fff; background-color: black; border: 1px solid #0353a4; } } @include medium-screen { padding-right: 30px; } @include small-screen { &.off { right: -100%; } background-color: #333; height: 100%; position: absolute; top: 78px; right: 0; flex-direction: column; } } .menu { display: none; align-items: center; @include small-screen { display: flex; } .burger { display: none; svg { width: 26px; height: auto; } @include small-screen { display: block; padding-right: 30px; &.off { display: none; } } } .close { display: none; &.off { display: none; } svg { width: 26px; height: auto; } @include small-screen { display: block; padding-right: 30px; &.off { display: none; } } } } } }
问题根源
- 移动端导航栏使用
position: absolute但未设置明确宽度,默认会撑满视口宽度,即使设置right: -100%,元素本身的占位依然会影响布局。 nav-container使用固定宽度1024px,小屏幕下超出视口,且未设置position: relative,导致绝对定位的导航栏以页面为基准定位,而非导航容器。- 无关元素添加了多余的
overflow: hidden,真正需要限制溢出的容器配置缺失。
修复步骤
1. 给移动端导航栏设置明确宽度
在小屏幕媒体查询中,为.links添加固定宽度,确保right: -100%能精准将其移出视口:
@include small-screen { &.off { right: -100%; } background-color: #333; height: 100%; position: absolute; top: 78px; right: 0; flex-direction: column; width: 100%; // 添加这一行,或设置固定宽度如300px }
2. 给导航容器添加相对定位
让绝对定位的导航栏以nav-container为基准,避免脱离容器影响全局布局:
.nav-container { padding: 10px 0px; display: flex; flex-direction: row; align-items: center; justify-content: space-between; color: white; width: 1024px; overflow: hidden !important; isolation: isolate; position: relative; // 添加这一行 }
3. 适配小屏幕下的容器宽度
将nav-container的固定宽度改为最大宽度,确保在小屏幕下自适应:
.nav-container { padding: 10px
相关产品推荐
相关产品推荐

