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

如何修复Angular Material侧边栏的滚动异常问题

问题描述

预期效果

  • 桌面端:左侧显示固定侧边栏,高度占满屏幕,宽度为226px
  • 移动端:显示工具栏,可从左侧打开侧边面板
  • 工具栏固定不随滚动消失,仅内容区域可滚动

当前问题

实现第3点时遇到高度与溢出设置问题:底部padding无法显示,页面出现两个滚动条,需同时滚动才能到达顶部/底部,无法直接隐藏滚动条。怀疑高度设置错误,但无法定位问题。

需求

如何实现仅mat-sidenav-content区域显示一个滚动条,仅滚动内容?

*注:测试桌面版需将isMobile()设为false,示例已最大程度还原代码。


侧边栏HTML代码

@if (isMobile()) {
  <mat-toolbar class="mobile-toolbar" aria-label="Toolbar">
    <button (click)="sidenav.toggle()">Toggle</button>
  </mat-toolbar>
}

<mat-sidenav-container class="sidenav-container" [class.mobile]="isMobile()">
  <mat-sidenav
    #sidenav
    class="sidenav"
    [class.mobile]="isMobile()"
    [mode]="isMobile() ? 'over' : 'side'"
    [opened]="!isMobile()"
  >
    <div class="sidebar-content">
      <button>
        test
      </button>
    </div>
  </mat-sidenav>

  <mat-sidenav-content
    class="sidenav-content"
    [class.mobile]="isMobile()">
    <router-outlet></router-outlet>
    <div class="test-long-content">
      <h1>Test</h1>
    </div>
  </mat-sidenav-content>
</mat-sidenav-container>

侧边栏SCSS代码

.sidenav-container {
  height: 100vh;

  &.mobile {
    overflow-y: auto;
    height: calc(100vh - 64px);
  }
}

.sidenav-content {
  background-color: grey;
  overflow-y: auto;

  &.mobile {
    padding: 2vh 5vw 2vh 5vw;
  }

  .test-long-content {
    height: 1000px;
    background-color: red;
  }
}

.sidenav {
  background-color: black;

  overflow-y: auto;
  width: 226px;

  display: flex;
  flex-direction: column;
  justify-content: space-between;

  .mobile {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 1000;
    margin-top: 64px;
  }

  .sidebar-content {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    height: 100%;
  }
}

.mobile-toolbar {
  background: black;
  height: 64px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  position: sticky;
  top: 0;
  left: 0;
  z-index: 1000;
}

解决方案

问题核心是多层滚动容器嵌套和高度计算未考虑盒模型导致的冲突,按以下步骤修改即可解决:

  1. 全局禁用页面级滚动
    把滚动权限完全交给内容区域,避免双重滚动:

    body {
      margin: 0;
      overflow: hidden;
    }
    
  2. 修正移动端容器的溢出设置
    移除sidenav-container的overflow-y: auto,让内容区域独自处理滚动:

    .sidenav-container {
      height: 100vh;
    
      &.mobile {
        // 移除overflow-y: auto
        height: calc(100vh - 64px);
      }
    }
    
  3. 确保内容区域填满容器并修复padding截断
    给sidenav-content设置height:100%,同时用box-sizing:border-box确保padding不会额外增加高度:

    .sidenav-content {
      background-color: grey;
      height: 100%;
      overflow-y: auto;
      box-sizing: border-box;
    
      &.mobile {
        padding: 2vh 5vw 2vh 5vw;
      }
    }
    
  4. 修复移动端侧边栏的样式选择器
    原.sidenav .mobile选择器错误,应改为.sidenav.mobile(类名同时作用于元素),并补充高度设置:

    .sidenav {
      // ... 原有代码
      &.mobile {
        position: fixed;
        top: 0;
        left: 0;
        z-index: 1000;
        margin-top: 64px;
        height: calc(100vh - 64px);
      }
    }
    

修改完成后,只有mat-sidenav-content会显示滚动条,底部padding正常展示,页面不会出现双重滚动问题。

内容的提问来源于stack exchange,提问作者user p

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 17:35:23