没有固定高度的滚动条/带有滚动条的动态高度

81

我有以下HTML结构:

<div id="body">
    <div id="head">
        <p>Dynamic height without scrollbar</p>
    </div>
    <div id="content">
        <p>Dynamic height with scrollbar</p>
    </div>
    <div id="foot">
        <p>Fixed height without scrollbar</p>
    </div>  
</div>

我希望在主体部分(#body)内有三个子部分,且不出现溢出情况。因此,我需要在中间部分添加滚动条。

我尝试了以下CSS:

#content{
    border: red solid 1px;
    overflow-y: auto;
}

还有这个:

#content{
    border: red solid 1px;
    overflow-y: auto;
    height: 100%;
}

但两种方法都没用。

我在JSFiddle上提供了一个示例。

我能否只使用CSS和HTML来实现这个效果?我更喜欢避免使用Javascript。

10个回答

97

Flexbox是一种现代的替代方案,可以在没有固定高度或JavaScript的情况下实现此功能。

在容器上设置display: flex; flex-direction: column;,在标题和页脚的div上设置flex-shrink: 0;就可以做到这一点:

HTML:

<div id="body">
    <div id="head">
        <p>Dynamic size without scrollbar</p>
        <p>Dynamic size without scrollbar</p>
        <p>Dynamic size without scrollbar</p>  
    </div>
    <div id="content">
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
        <p>Dynamic size with scrollbar</p>
    </div>
    <div id="foot">
        <p>Fixed size without scrollbar</p>
        <p>Fixed size without scrollbar</p>
    </div>  
</div>

CSS:
#body {
    position: absolute;
    top: 150px;
    left: 150px;
    height: 300px;
    width: 500px;
    border: black dashed 2px;
    display: flex;
    flex-direction: column;
}
    
#head {
    border: green solid 1px;
    flex-shrink: 0;
}

#content{
    border: red solid 1px;
    overflow-y: auto;
    /*height: 100%;*/
}

#foot {
    border: blue solid 1px;
    height: 50px;
    flex-shrink: 0;
}

代码片段:

#body {
  position: absolute;
  top: 150px;
  left: 150px;
  height: 300px;
  width: 500px;
  border: black dashed 2px;
  display: flex;
  flex-direction: column;
}

#head {
  border: green solid 1px;
  flex-shrink: 0;
}

#content {
  border: red solid 1px;
  overflow-y: auto;
  /*height: 100%;*/
}

#foot {
  border: blue solid 1px;
  height: 50px;
  flex-shrink: 0;
}
<div id="body">
  <div id="head">
    <p>Dynamic size without scrollbar</p>
    <p>Dynamic size without scrollbar</p>
    <p>Dynamic size without scrollbar</p>
  </div>
  <div id="content">
    <p>Dynamic size with scrollbar</p>
    <p>Dynamic size with scrollbar</p>
    <p>Dynamic size with scrollbar</p>
    <p>Dynamic size with scrollbar</p>
    <p>Dynamic size with scrollbar</p>
    <p>Dynamic size with scrollbar</p>
    <p>Dynamic size with scrollbar</p>
    <p>Dynamic size with scrollbar</p>
    <p>Dynamic size with scrollbar</p>
    <p>Dynamic size with scrollbar</p>
    <p>Dynamic size with scrollbar</p>
    <p>Dynamic size with scrollbar</p>
    <p>Dynamic size with scrollbar</p>
    <p>Dynamic size with scrollbar</p>
    <p>Dynamic size with scrollbar</p>
    <p>Dynamic size with scrollbar</p>
    <p>Dynamic size with scrollbar</p>
    <p>Dynamic size with scrollbar</p>
    <p>Dynamic size with scrollbar</p>
    <p>Dynamic size with scrollbar</p>
    <p>Dynamic size with scrollbar</p>
    <p>Dynamic size with scrollbar</p>
    <p>Dynamic size with scrollbar</p>
  </div>
  <div id="foot">
    <p>Fixed size without scrollbar</p>
    <p>Fixed size without scrollbar</p>
  </div>
</div>


2
我认为这个回复应该被接受为CSS3的答案。 - hjchin
63
我认为这不是正确的答案。如果没有为body元素设置固定高度,它将无法正常工作。 - Equanox
2
@Equanox有限公司,容器的高度是关键点,否则所有三个部分都会垂直扩展,就不需要滚动条了。请注意,它可以是max-height而不是固定的height - mtyaka
22
你仍在网页主体上使用固定高度。 - chovy
4
这里的重点是#content元素没有固定的高度。在#body元素上设置的固定高度仅是为了演示当高度受限时,#contentdiv会自动收缩,但您也可以将#body的固定高度删除,或将其替换为类似于max-height: 100%的内容。 - mtyaka
显示剩余2条评论

24

我有一个与PrimeNG p_Dialog内容相似的问题,并且我通过以下contentStyle样式进行了修复

height: 'calc(100vh - 127px)'

我最喜欢的方法,但只有在移动浏览器上不会出现可移动地址栏的情况下才能使用。你需要使用JS并执行 window.innerHeight - 127px 来进行补偿 :/ - Juliano

11

使用这个:

style="height: 150px; max-height: 300px; overflow: auto;" 

固定一个高度,它将成为默认的高度,然后滚动条出现以访问整个高度。


4
只有在设置正确的高度时,滚动才能起作用。单独使用 max-height 是不起作用的。 - Bazley
1
当您已经设置了固定的height时,设置max-height的目的是什么?除非在其他地方被覆盖,否则该元素永远不会低于150像素高,因此将其高度限制为300像素有什么好处?此外,这个答案使用了一个固定的高度,而问题明确表示不想要这样。 - OOPS Studio

10
 <div id="scroll">
    <p>Try to add more text</p>
 </div>

以下是 CSS 代码:

#scroll {
   overflow-y:auto;
   height:auto;
   max-height:200px;
   border:1px solid black;
   width:300px;
 }

here's the demo JSFIDDLE


5

您需要指定一个固定的高度,不能使用100%,因为没有可以进行比较的对象,例如height = 100%相对于什么?

编辑后的代码片段:

http://jsfiddle.net/6WAnd/4/


你的身体或头部有固定的高度吗? - Philip Bevan
只有主体部分有固定的高度。头部必须全部显示,在这种情况下 http://jsfiddle.net/6WAnd/11/,头部会溢出到 #content 部分。 - GuillaumeS
2
没有JS,你会发现在一个固定的主体中让两个动态高度的部分相互叠放很困难!! - Philip Bevan
3
另一个 div 的高度设置为 100%,有什么问题吗?如果不这样做,这个插件就没用了。我们需要响应式设计。 - Toolkit
@Toolkit 这个问题已经在3年前得到了回答,现在情况很可能已经有所改变了... - Philip Bevan
显示剩余4条评论

5

在 @mtyaka 提供的 flexbox 方法之上,如果你的可滚动区域深入嵌套在 DOM 中,需要对所有父元素使用 overflow: auto/hidden 直到我们得到一个固定高度。

jsfiddle https://jsfiddle.net/rohilaharsh/cuazdnkh/1/

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dynamic Container</title>
</head>
<body>
    <div class="one">
    One
        <div class="two">
    Two
            <div class="three">
      Three
                <div class="table">
          Table
                    <div class="header">Table Header</div>
                    <div class="body">Lorem ipsum dolor sit amet consectetur adipisicing elit. Iure maiores corporis quisquam enim at nam earum non atque dolorum nulla quidem perferendis, porro eveniet! Quisquam, fugit ex aspernatur, aliquid necessitatibus amet aperiam pariatur facilis suscipit ea dolorum qui ratione assumenda eum minima. At a ullam magnam eveniet, hic sit quis dicta perferendis excepturi nemo voluptate ipsum doloremque expedita illo dolor voluptates culpa consequuntur quaerat porro reprehenderit ab alias! Maxime reprehenderit nihil doloribus exercitationem, cupiditate quasi dolorum voluptas repellendus vel fugit incidunt praesentium molestias modi numquam! Quo porro laudantium aperiam suscipit, molestiae quibusdam veniam cum nam fuga facere fugit quisquam distinctio!</div>
                </div>
            </div>
        </div>
    </div>
</body>
</html>

CSS(层叠样式表):
html {
  height: 100%;
}

html, body, .one,.two,.three,.table {
  display: flex;
  flex-direction: column;
  
  /* important */
  overflow: hidden;
  
  flex: 1;
  margin: 0;
}

.body {
  width: 200px;
  overflow: auto;
}

感谢您对此澄清。将 * 设置为您的设置有助于清理我的样式表并简化深层次的 overflow: auto 调试问题。从设计角度来看,我确实对个别元素设置了 flex: 1,因为这样更具控制性。 - OXiGEN
非常感谢您的澄清。将 * 设置为您的样式表有助于清理并简化深层次的 overflow: auto 调试问题。从设计角度来看,我确实会在个别元素上设置 flex: 1,因为这样更具控制性。 - undefined

2

一种快速、简洁的方法,仅使用极少量的JS和CSS padding:http://jsfiddle.net/benjamincharity/ZcTsT/14/

var headerHeight = $('#header').height(),
    footerHeight = $('#footer').height();

$('#content').css({
  'padding-top': headerHeight,
  'padding-bottom': footerHeight
});

1
使用网格布局,您可以动态调整每个部分的高度。
#body{
  display:grid;
  grid-template-rows:1fr 1fr 1fr;
}

添加以上代码即可获得所需结果。

有时当涉及到许多级网格时,CSS无法将您的#content限制为1fr。在这种情况下,请使用:

#content{
  max-height:100%;
}

0

我不确定我是否理解正确,但是this能解决你的问题吗?

我刚刚修改了overflow-y: scroll;

#content{
    border: red solid 1px;
    overflow-y: scroll;
    height: 100px;
}

编辑

然后尝试使用百分比值,像这样:http://jsfiddle.net/6WAnd/19/

CSS 标记:

#body {
    position: absolute;
    top; 150px;
    left: 150px;
    height: 98%;
    width: 500px;
    border: black dashed 2px;
}    
#head {
    border: green solid 1px;
    height: 15%;
}
#content{
    border: red solid 1px;
    overflow-y: scroll;
    height: 70%;
}
#foot {
    border: blue solid 1px;
    height: 15%;
}

但是我无法为#head和#content设置大小。 我希望#content和#head填充所有主div(#body)。 我只是制作了一张图片来说明它:http://img15.hostingpics.net/pics/986131examplepanel.png - GuillaumeS
这个解决方案不允许有两个具有动态高度的块。如果我在第一部分放很多文本,它就无法工作:http://jsfiddle.net/6WAnd/21/。我认为@philip-bevan已经发现了没有JS是不可能的。请看他下面的回答。 - GuillaumeS

0
使用这个:
#head {
    border: green solid 1px;
    height:auto;
}    
#content{
            border: red solid 1px;
            overflow-y: scroll;
            height:150px;       
        }

只要我更改第一部分,它就可以工作。 试着用很多 "<p>动态大小而没有滚动条</p>" http://jsfiddle.net/EKvCw/ - GuillaumeS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接