You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

设置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;
              }
            }
          }
        }
      }
    }

问题根源

  1. 移动端导航栏使用position: absolute但未设置明确宽度,默认会撑满视口宽度,即使设置right: -100%,元素本身的占位依然会影响布局。
  2. nav-container使用固定宽度1024px,小屏幕下超出视口,且未设置position: relative,导致绝对定位的导航栏以页面为基准定位,而非导航容器。
  3. 无关元素添加了多余的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
相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 09:28:44