CSS:max-height:剩余空间

24

这个问题可以用下面的图片来描述:

编辑:
第一个包含的div应该始终可见。当主要的div被完全填满时,第二个div隐藏其剩余内容。

<div style="height:100%">
    <div>Dynamic ajax content</div>
    <div style="max-height:[remaining space]">Dynamic ajax content</div>
</div>

这里有一个fiddle,是我目前为止所拥有的。


1
我不认为我会称其为“问题”。 - BoltClock
1
如果没有看到您的代码,几乎不可能回答这个问题。请在此处包含您的代码或创建一个fiddle并添加您想要布局看起来像什么的说明。 - steveax
@sparky672:你为什么删除了编辑内容?很明显它说描述和代码来自评论。Evgeniy在评论中发布了它,并表示他无法编辑他的帖子。显然,当他看到我已经把信息放到问题中时,他就删除了评论。 - tw16
1
抱歉@tw16,由于原帖的评论已经消失,我只是假设你从图片中自己编写了代码。 - Sparky
1
抱歉添加和删除评论造成的不便 :( 感谢您将其添加到帖子中 :) 那么我该如何解决这个“问题”呢? - mu3
显示剩余2条评论
7个回答

20

现在是2019年,我们可以利用flexbox来实现这一点。由于灵活的内容可以扩展,因此使用position: absolute来固定内部内容的高度和宽度,以便支持溢出。

HTML

<div class="wrapper">
    <div class="content">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</div>
    <div class="flexi-content-wrapper">
        <div class="flexi-content">
            <!-- some long contents here -->
        </div>
    </div>
</div>

CSS

.wrapper {
  display: flex;
  flex-direction: column;
  height: 90vh;
  padding: 15px;
}

.header {
  font-size: 1.5em;
  font-weight: 700;
  margin: 10px 0;

}

.content {
 margin-bottom: 10px;
}

.flexi-content-wrapper {
  margin-top: 10px;
  flex: 1;
  position: relative;
}

.flexi-content {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  border: 1px solid rgb(253, 140, 140);
  overflow: auto;
}

以下是完整的示例。 如果您喜欢使用stackblitz: https://stackblitz.com/edit/angular-chvhsk

或者,您可以使用代码片段运行以下代码:

.wrapper {
  display: flex;
  flex-direction: column;
  height: 90vh;
  padding: 15px;
}

.header {
  font-size: 1.5em;
  font-weight: 700;
  margin: 10px 0;

}

.content {
 margin-bottom: 10px;
}

.flexi-content-wrapper {
  margin-top: 10px;
  flex: 1;
  position: relative;
}

.flexi-content {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  border: 1px solid rgb(253, 140, 140);
  overflow: auto;
}

.paragraph {
  padding: 20px 15px;
}
<div class="wrapper">
    <div class="header">Lorem Ipsum</div>
    <div class="content">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been
        the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and
        scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into
        electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of
        Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus
        PageMaker including versions of Lorem Ipsum.</div>
    <div class="flexi-content-wrapper">
        <div class="flexi-content">
            <div class="paragraph">
                Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla eu lectus eget metus faucibus luctus
                vitae et felis. Curabitur a vestibulum ex. Morbi ut tincidunt risus. Morbi luctus commodo gravida.
                Curabitur vitae rutrum nulla. Cras metus lacus, feugiat nec fermentum vel, suscipit et mauris. Ut
                consequat gravida dolor ut varius. Mauris vestibulum lorem vel egestas laoreet. Aliquam laoreet lacus
                ante, vel porttitor magna luctus quis. Nullam diam est, sodales in risus quis, fringilla venenatis nunc.
                Suspendisse eu vehicula risus, eu tempus risus. Morbi id urna consequat, malesuada ligula vitae,
                dignissim enim. Donec eros diam, feugiat et posuere a, rhoncus a eros. Aenean quis gravida purus, non
                elementum diam.
            </div>
            <div class="paragraph">
                Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Mauris
                orci felis, dignissim vitae ullamcorper ac, interdum vel mauris. Suspendisse semper elit ipsum, id
                pretium mi viverra ut. Morbi fermentum eleifend metus ac dictum. Curabitur lectus quam, varius id dui
                at, imperdiet fermentum ipsum. Phasellus id eleifend felis. Etiam scelerisque porta auctor.
            </div>
            <div class="paragraph">
                Maecenas maximus purus a urna volutpat, quis congue nulla blandit. Donec ac ex massa. Vivamus euismod
                quam sit amet maximus commodo. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed accumsan,
                enim in consequat vehicula, nunc justo finibus nibh, quis tincidunt massa eros eu risus. Nulla
                scelerisque rutrum rutrum. Suspendisse venenatis, dolor eu finibus maximus, arcu massa varius velit,
                eget maximus lacus ex ut tellus. Cras a tortor iaculis, volutpat risus quis, congue lectus. Curabitur id
                mi in massa rutrum luctus. Donec ornare dolor ut massa congue, ac pretium lacus viverra. Morbi vulputate
                sapien et nibh pharetra cursus. Phasellus ac lobortis orci, eu laoreet tortor. Cras ac purus ligula. Sed
                in cursus ipsum. Etiam interdum neque vitae euismod facilisis.
            </div>
            <div class="paragraph">
                Integer placerat feugiat metus, a egestas mi porta lacinia. Nam interdum pretium ligula feugiat
                elementum. Phasellus quis urna tincidunt, rhoncus ligula et, commodo tortor. Pellentesque tristique
                ipsum eu odio sodales finibus. Vestibulum ut enim malesuada, ullamcorper est pretium, pulvinar elit. Ut
                gravida luctus elit. Ut vehicula sodales convallis. Mauris at velit eget nisi tincidunt tempus. Aenean
                non est scelerisque nunc porta volutpat. Nam urna justo, fermentum vitae neque et, tristique porttitor
                ipsum. Praesent orci quam, fermentum id ultricies id, varius et lorem. Vivamus quis viverra eros, vitae
                rutrum sapien.
            </div>
            <div class="paragraph">
                Sed odio leo, imperdiet vitae feugiat et, volutpat id massa. Proin gravida feugiat vehicula. Nulla
                lobortis risus nec cursus congue. Praesent euismod fringilla ante, aliquam semper arcu malesuada sed.
                Nulla ac nisl velit. Aliquam porta dui sit amet arcu tempor vehicula. Integer tincidunt nisl vitae diam
                venenatis dictum. Integer ut placerat leo. Ut eu ultrices magna. Nam eget leo gravida, semper urna
                mollis, bibendum ante. Proin accumsan massa nec hendrerit gravida. Suspendisse interdum ipsum in justo
                ullamcorper, eu hendrerit turpis iaculis. Nunc id rhoncus urna. Integer elementum nibh ut turpis gravida
                accumsan. Quisque vulputate imperdiet ligula sed imperdiet. Nullam auctor ante nunc, vel pretium tortor
                tempor quis.
            </div>
            <div class="paragraph">
                Morbi id tellus vehicula, dapibus ante eget, malesuada arcu. Vivamus aliquam vitae sem eu tincidunt.
                Nullam laoreet consequat congue. Pellentesque id vestibulum metus. Nullam elementum tincidunt dignissim.
                Mauris et erat id ipsum elementum ullamcorper eget non metus. Phasellus elementum lorem non lacinia
                pretium. Fusce vel placerat sapien. Sed condimentum bibendum lectus at rhoncus. Phasellus eu auctor
                velit.
            </div>
        </div>
    </div>
</div>


1
你是我的救星,我从没想到将绝对定位元素放入相对定位容器中会导致一个隐式的最大高度容器。这个技巧真的很实用,让我感到非常惊喜。 - Niton
这是我在过去两周中发现的迄今为止最有用的东西。谢谢! - Dirindon
它对我也起作用,但是有人能解释一下这里发生了什么吗?即什么机制会触发它的工作,就像“max-height: remaining-space”一样(仅依靠flexbox并没有给我预期的结果)。 - greenoldman

4
我认为您正在寻找这样的内容,请查看 演示篮子。缩小或扩大结果窗格以查看它的实际效果。
最小CSS:
#wrapper {
    overflow: hidden;
}
#upper {
    max-height: 100%;
    overflow-y: auto;
}
#downer {
    height: 100%;
}

HTML:

<div id="wrapper">
    <div id="upper"></div>
    <div id="downer"></div>
</div>

不幸的是,那不是我需要的准确内容。 我需要这两个 div 在还有空间时可见。 当超过空间时,第二个 div 应该仍然可见,但会出现滚动条。 - mu3
我不会按照你的要求随便做。只要有空间,两个都应该是不可见的???而当没有空间时,只有第二个应该有可滚动条的可见性??我完全迷失了,抱歉。 - NGLN
抱歉解释不够清楚,我再试一次 :) 第一个div始终可见且具有完整的高度大小(没有滚动条或溢出隐藏)。 当两个div中的内容大小总和大于主div的高度时,第二个div不会被隐藏,而是完全可见于剩余的主div空间,并带有滚动条。可能有些混乱,但我希望你能理解。 - mu3

1

解决方案 2022

HTML:

<div class='parent'>
    <div class='child-one'/>
    <div class='child-two'/>
</div>

CSS:

.parent {
  display: flex;
  flex: 1;
  flex-direction: column;
}

.child-one {
   ...
}

.child-two {
   flex: 1
}

1
解决方案:
HTML
<div id="outer">
    <div id="inner_fixed">
        I have a fixed height
    </div>

    <div id="inner_remaining">
        I take up the remaining height
    </div>
</div>

CSS(层叠样式表)
#outer {
   display: flex;
   flex-flow: column;
   height: 100%;
}
 
#inner_fixed {
   height: 100px;
   background-color: grey;
}
 
#inner_remaining {
   background-color: #DDDDDD;
   flex-grow : 1;
}

本文提供了其他解决方案:https://www.whitebyte.info/programming/css/how-to-make-a-div-take-the-remaining-height

0

不行,百分比并不能帮助很多,因为它是动态内容,第一个 div 在获取更多内容时会移动第二个 div。 - mu3

0

我只能猜测你想根据你的发帖和 Fiddle 使用基于 JavaScript 样式的 CSS calc()

//<![CDATA[
/* js/external.js */
var doc, html, bod, nav, mobile, M, I, S, Q, special, unspecial; // for use on other loads
addEventListener('load', function(){
doc = document; html = doc.documentElement; bod = doc.body;  nav = navigator;
mobile = nav.userAgent.match(/Mobi/i) ? true : false;
M = function(tag){
  return doc.createElement(tag);
}
I = function(id){
  return doc.getElementById(id);
}
S = function(selector, within){
  var w = within || doc;
  return w.querySelector(selector);
}
Q = function(selector, within){
  var w = within || doc;
  return w.querySelectorAll(selector);
}
special = function(str){
  return str.replace(/&/g, '&amp;').replace(/'/g, '&apos;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}
unspecial = function(str){
  return str.replace(/&amp;/g, '&').replace(/&apos;/g, "'").replace(/&quot;/g, '"').replace(/&lt;/g, '<').replace(/&gt;/g, '>');
}
var testText = special("This is just a bunch of text to show you if it works. You can see why characters like < and > should be escaped in HTML & .innerHTML, but not in .value. You'll want to use Element.getBoundingClientRect() if the height is dynamic.");
var pageTop = I('page_top'), fd = I('first_dynamic'), dyn = I('dynamic'), dynS = dyn.style;
I('test_button').onclick = function(){
  if(fd.innerHTML === ''){
    fd.innerHTML = testText;
  }
  else{
    dyn.innerHTML += testText;
    dynS.height = 'calc(100% - '+pageTop.getBoundingClientRect().height+'px)';
  }
}
}); // end load
//]]>
/* css/external.css */
*{
  box-sizing:border-box; padding:0; margin:0;
}
html,body{
  height:100%; overflow:hidden; padding:0; 
}
h1{
  text-align:center; padding:3px 0;
}
input{
  width:100%; font-size:28px;
}

#first_dynamic,#dynamic{
  overflow-y:scroll;
}
<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
  <head>
    <meta charset='UTF-8' /><meta name='viewport' content='width=device-width, height=device-height, initial-scale:1' />
    <title>Test Template</title>
    <link type='text/css' rel='stylesheet' href='css/external.css' />
    <script type='text/javascript' src='js/external.js'></script>
  </head>
<body>
  <div id='page_top'>
    <h1>TOP OF PAGE HERE</h1>
    <input id='test_button' type='button' value='Click to Test' />
    <div id='first_dynamic'></div>
  </div>
  <div id='dynamic'>
  </div>
</body>
</html>

你应该知道 Element.getBoudingClientRect() 不计算边距。你还应该知道,如果你的 #first_dynamic 太大,会出现问题。

0

这是你想要的吗?尝试将#main :first-child的内容替换为非常长的lorem ipsum,以查看第一个子元素过长时的行为

#main{
    height: 300px;
    border: 1px solid;
    display: grid;
    grid-template-rows: minmax(50%, auto) 1fr;
    overflow-y: hidden;
}
#main :last-child{
    border: 1px solid red;
    overflow-y: auto;
}
<div id=main>
    <div>Dynamic ajax cLor</div>
    <div>Dynamic ajax content<br>Dynamic ajax content</div>
</div>


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