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

如何为CSS Grid子项添加overflow:auto实现局部滚动

界面布局示意图

问题描述

我制作了如图所示的界面:蓝色区域为侧边栏(sidenav),红色区域为页面标题,橙色区域为内容主体。需求是当橙色内容主体超出容器高度时,仅该区域显示滚动条并可独立滚动。以下是我的代码:

<div id="container" class="h-[var(--window-height)] grid grid-cols-[auto,1fr]">
    <div id="sidebar" class="bg-blue-500">
        <div class="w-[300px]"></div>
    </div>
    <div id="content" class="h-full grid grid-rows-[auto,1fr]">
        <div id="title">
            <div class="bg-red-600 h-[50px]"></div>
        </div>
        <div id="body" class="overflow-y-auto">
            <div class="h-[2000px] bg-orange-600"></div>
        </div>
    </div>
</div>

问题在于,div#body并未如预期显示滚动条,而是被内容撑开导致整个页面滚动。但移除div#sidebar(同时移除div#container的.grid类)后,滚动功能恢复正常;另外,将div#body内部div的.h-[2000px]改为.h-[2000%]时,滚动也能正常工作,代码如下:

<div id="container" class="h-[var(--window-height)] grid grid-cols-[auto,1fr]">
    <div id="sidebar" class="bg-blue-500">
        <div class="w-[300px]"></div>
    </div>
    <div id="content" class="h-full grid grid-rows-[auto,1fr]">
        <div id="title">
            <div class="bg-red-600 h-[50px]"></div>
        </div>
        <div id="body" class="overflow-y-auto">
            <div class="h-[2000%] bg-orange-600"></div>
        </div>
    </div>
</div>

请问该问题的原因是什么?如何修改代码才能实现预期的局部滚动效果?

完整代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Grid overflow</title>

    <script src="https://cdn.tailwindcss.com"></script>

</head>
<body>

    <div id="container" class="h-[var(--window-height)] grid grid-cols-[auto,1fr]">
        <div id="sidebar" class="bg-blue-500">
            <div class="w-[300px]"></div>
        </div>
        <div id="content" class="h-full grid grid-rows-[auto,1fr]">
            <div id="title">
                <div class="bg-red-600 h-[50px]"></div>
            </div>
            <div id="body" class="overflow-y-auto">
                <div class="h-[2000px] bg-orange-600"></div>
            </div>
        </div>
    </div>

    <script>

        function setCssVars() {
            document.documentElement.style.setProperty('--window-height', `${window.innerHeight}px`);
            document.documentElement.style.setProperty('--window-width', `${window.innerWidth}px`);
        }

        window.addEventListener('resize', setCssVars);
        setCssVars();

    </script>
    
</body>
</html>

问题原因

核心问题出在CSS Grid的默认行为上——Grid布局默认的align-items属性值是stretch,也就是网格项会被内容强行撑开,哪怕你给父容器设置了固定高度也无法限制。

具体到你的代码:

  • #container是Grid布局,#content作为右侧的网格项,当内部#body里的2000px高元素撑起来时,#content会直接突破#container的高度限制,导致整个页面跟着滚动,而不是触发#body的内部滚动。
  • 删掉侧边栏和Grid类后,布局变成普通块级元素,#content的h-full能老老实实继承父容器高度,#body的1fr轨道会自动计算出“容器高度-标题高度”的可用空间,内容超出就会触发滚动。
  • 换成h-[2000%]时,内部元素的高度是基于#body的高度计算的,而此时#body被Grid轨道限制了高度,自然就会触发内部滚动。
解决办法

要让#body单独滚动,关键是把#container的高度锁死,不让它被内容撑开,同时让#body的高度被正确限制。有两种简单的修改方式:

方式一:给#container添加overflow-hidden

直接给最外层的#container添上overflow-hidden类,阻止容器本身溢出,这样Grid轨道的高度就会严格遵循--window-height的设置,#body的1fr轨道会自动算出剩余高度,内容超出就会显示滚动条:

<div id="container" class="h-[var(--window-height)] grid grid-cols-[auto,1fr] overflow-hidden">

方式二:修改Grid的对齐方式

给#container设置items-start,让网格项不会被内容拉伸,同时保证#content的h-full生效:

<div id="container" class="h-[var(--window-height)] grid grid-cols-[auto,1fr] items-start">
<div id="content" class="h-full grid grid-rows-[auto,1fr]">

推荐使用方式一

方式一不用改变Grid的默认对齐行为,只需要添加一个类就能解决问题,更简单稳妥。

修改后的完整代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Grid overflow</title>

    <script src="https://cdn.tailwindcss.com"></script>

</head>
<body>

    <div id="container" class="h-[var(--window-height)] grid grid-cols-[auto,1fr] overflow-hidden">
        <div id="sidebar" class="bg-blue-500">
            <div class="w-[300px]"></div>
        </div>
        <div id="content" class="h-full grid grid-rows-[auto,1fr]">
            <div id="title">
                <div class="bg-red-600 h-[50px]"></div>
            </div>
            <div id="body" class="overflow-y-auto">
                <div class="h-[2000px] bg-orange-600"></div>
            </div>
        </div>
    </div>

    <script>

        function setCssVars() {
            document.documentElement.style.setProperty('--window-height', `${window.innerHeight}px`);
            document.documentElement.style.setProperty('--window-width', `${window.innerWidth}px`);
        }

        window.addEventListener('resize', setCssVars);
        setCssVars();

    </script>
    
</body>
</html>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 12:47:07