首页 新闻 会员 周边 捐助

关于Flex布局,相对宽度,但是又要实现子元素超出时出现滚动条而不是撑开,如何解决

0
[已解决问题] 解决于 2025-04-18 18:15

预期效果

视窗不会产生滚动条,页面平分为上下两部分,但是这两部分各自内容如果很多可以滚动

问题简单示例:

CSS:

body{
    margin: 0;
    padding: 0;
}

.container{
   display: flex
   flex-direction: column;
   width: 100vw; /* 就想这个容器始终是视窗大小 */
   height: 100vh; /*  */
}

.part{
    height: 50%;
    width: 100%;
    overflow: scroll;/** 这里肯定达不到想要的效果 */
}

HTML

<html>
<head>
  ...<!-- 省略 -->
</head>
<body>
<div class="container">
    <div class="part top">
    <div class="part bottom">
</div>
</body>
</html>

问题的矛盾点在于Flex相对宽度会被子元素撑开,导致无法保持视窗不出现滚动条,二视窗大小本就是不确定的,不可能写死为固定大小,也不想通过JS 对视窗的resize事件动态去设置大小
该如何解决呢

六根不净的主页 六根不净 | 菜鸟二级 | 园豆:202
提问于:2025-04-16 17:17
< >
分享
最佳答案
0

把你当前的效果贴出来看看,哪个地方有问题.

奖励园豆:5
www378660084 | 小虾三级 |园豆:1561 | 2025-04-18 11:29

不好意思,可能问题描述有误,实际问题产生如下面这个html
问题产生的原因应该是 flex-grow 导致的吧,我也不确定,刚学CSS

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        body {
            margin: 0;
            padding: 0;
        }

        div {
            color: white;
            box-sizing: border-box;
        }

        /** 横向flex */
        .flex, .flex-h {
            display: flex;
            flex-direction: row;
        }

        /** 竖向flex */
        .flex-v {
            display: flex;
            flex-direction: column;
        }

        /** 内容滚动 */
        .scroll {
            overflow: scroll;
        }

        /** 内容横向滚动 */
        .scroll-x {
            overflow-x: scroll;
        }

        /** 内容竖向滚动 */
        .scroll-y {
            overflow-y: scroll;
        }

        .parent {
            width: 100vw; /* 就想这个容器始终是视窗大小 */
            height: 100vh; /*  */
        }

        .child {
            box-sizing: border-box;
        }

        .child.left {
        }

        .child.right {
            flex-grow: 1;
        }

        .grandson {
            width: 100%;
        }

        .grandson.top {
            flex-grow: 1;
        }

        .grandson.bottom {
            height: 200px;
            background: #252525;
            text-align: center;
        }

        .content-box {
            background: #222;
        }

        .content-box.left {
            width: 50%;
        }

        .content-box.right {
            width: 50%;
        }

        .content-box::-webkit-scrollbar {
            width: 8px;
            height: 8px;
            box-sizing: border-box;
        }

        .content-box::-webkit-scrollbar-corner {
            background: transparent;
        }

        .content-box::-webkit-scrollbar-button {
            display: none;
        }

        .content-box::-webkit-scrollbar-track {
            background: transparent;
        }

        .content-box::-webkit-scrollbar-track-piece {
            background: transparent;
        }

        .content-box::-webkit-scrollbar-thumb {
            border-radius: 5px;
            background: #505050;
        }

        .content-box::-webkit-scrollbar-thumb:hover {
            background: #575757;
        }

        .content-box::-webkit-scrollbar-thumb:active {
            background: #606060;
        }

        .settings {
            padding: 10px;
            width: 180px; /**  */
            font-size: 12px;
            background: #353535;

            input { vertical-align: middle; }
        }

        .content {
            height: 100px;
            width: 100px;
            background: #009AE2;
            transition: 0.2s;
        }
    </style>
</head>
<body>
<div class="parent flex-h">
    <div class="child left settings flex-v">
        <div class="flex-v">
            <div>左侧内容:</div>
            <label>宽:
                <input type="range" min="100" max="1000" value="100" onchange="changeContent('left','width',this.value)" id="w-left">
            </label>
            <label>高:
                <input type="range" min="100" max="1000" value="100" onchange="changeContent('left','height',this.value)" id="h-left">
            </label>
        </div>
        <div class="flex-v">
            <div>右侧内容:</div>
            <label>宽:
                <input type="range" min="100" max="1000" value="100" onchange="changeContent('right','width',this.value)" id="w-right">
            </label>
            <label>高:
                <input type="range" min="100" max="1000" value="100" onchange="changeContent('right','height',this.value)" id="h-right">
            </label>
        </div>
    </div>
    <div class="child right flex-v">
        <div class="grandson top flex-h">
            <div class="content-box left scroll">
                <div class="content left"></div>
            </div>
            <div class="content-box right scroll">
                <div class="content right"></div>
            </div>
        </div>
        <div class="grandson bottom">这是底部</div>
    </div>
</div>
<script>
    function changeContent(target, p, v)
    {
        const content = document.querySelector(`.content.${target}`);
        content.style[p] = v + 'px';
    }
</script>
</body>
</html>
六根不净 | 园豆:202 (菜鸟二级) | 2025-04-18 13:07

确定了,就是flex-grow导致的,问题根源在于,flex容器中的子元素一部分是固定大小,一部分要占满剩余空间,而整个flex容器大小又是动态的,该如何实现该效果

六根不净 | 园豆:202 (菜鸟二级) | 2025-04-18 13:21

@六根不净:
既然bottom大小是固定的,上面容器的大小也可以计算出来
.grandson.top {
height: calc(100% - 200px);
display: flex;
}

www378660084 | 园豆:1561 (小虾三级) | 2025-04-18 14:16
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册