使用具有最大高度的 Calc

Posted

技术标签:

【中文标题】使用具有最大高度的 Calc【英文标题】:Use Calc with Max Height 【发布时间】:2018-02-06 21:03:58 【问题描述】:

我需要一个绝对定位的容器,它只与它的内容一样大(以便尽可能地与容器后面的东西交互),但永远不会超过最大高度(窗口的高度)。

内容有三个子 DIV,前两个是静态高度,如果超出父级的最大高度,则底部会使用滚动条占用剩余空间,内容会隐藏或显示。如果容器具有静态高度,这可以正常工作,但如果容器只有最大高度,则似乎孩子的 calc 不起作用并且内容只是被裁剪。

编辑:需要支持 IE 9+。

小提琴:https://jsfiddle.net/z87cnmr2/1/

#container 
  position: absolute;
  top: 0;
  left: 0;
  max-height: 100%;
  /* uncomment this static height to see it work */
  /* height: 100%; */
  width: 100px;
  overflow: hidden;

#tip 
  background: #ff0;
  height:20px;

#top 
  background: #f00;
  height:20px;

#btm 
  background: #0f0;
  max-height: calc(100% - 40px);
  overflow-y: auto;

html, body 
  padding: 0;
  margin: 0;
  height:100%;
  width:100%;
<div id="container">
  <div id="tip">Tips</div>
  <div id="top">Tops</div>
  <div id="btm">
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br> 
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
  </div>
</div>

【问题讨论】:

【参考方案1】:

这里的问题是您的孩子 (#btm) 设置了百分比高度,而父母没有明确设置高度。

由于 CSS 中的某些原因,当子级设置了百分比高度但父级只有 max-heightmin-height 时,子级百分比高度不能以此为基础。 It needs an explicit height to base itself off of.

在这种情况下,如果您可以使用 flexbox(似乎可以,因为您正在使用 calc,并且 flexbox 有更大的支持),那么我建议您这样做:

<div id="container">
  <div id="tip">Tip</div>
  <div id="top">Top</div>
  <div id="btm">
    Btm1<br>
    Btm2<br>
    Btm3<br>
  </div>
</div>

CSS:

#container 
  display: flex;
  flex-direction: column;
  max-height: 100%;


#tip  height:20px; 
#top  height:20px; 
#btm  overflow-y: auto; 

I've forked your jsfiddle and implemented the full answer here too.


编辑:

对于 IE9 支持,您可以使用 viewport units:

#btm 
  max-height: calc(100vh - 40px);

See IE9 updated fiddle.

请注意,如果放弃 IE9 支持,最好使用 flex 选项,因为它不依赖任何可以正常工作的“幻数”(例如,此处硬编码的 40px)。幻数使您的代码易受更改破坏,但如果需要 IE9 支持,我会选择此选项。

【讨论】:

我很想使用 flex,但不能,因为我们需要支持 IE 9+,这似乎适用于 calc。 @scader 如果肯定需要 IE9 支持,那么结合使用视口单元和 calc 应该可以解决问题。它有点hacky和脆弱,但应该可以工作。已更新我的答案以反映这一点。【参考方案2】:

您可以使用display:flex 来完成此操作,只要您不必支持旧版浏览器(

#container 
  position: absolute;
  top: 0;
  left: 0;
  max-height: 100%;
  /* uncomment this static height to see it work */
  /* height: 100%; */
  width: 100px;
  overflow: hidden;
  display: flex;
  flex-direction: column;

#tip 
  background: #ff0;
  height:20px;

#top 
  background: #f00;
  height:20px;

#btm 
  background: #0f0;
  max-height: calc(100% - 40px);
  overflow-y: auto;

html, body 
  padding: 0;
  margin: 0;
  height:100%;
  width:100%;
<div id="container">
  <div id="tip">Tip</div>
  <div id="top">Top</div>
  <div id="btm">
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br> 
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
    Btm<br>
  </div>
</div>

https://jsfiddle.net/z87cnmr2/4/

如果你想支持旧版本的 IE (>= IE 9),你可以使用 vh,因为你是基于窗口的高度:

#container 
  position: absolute;
  top: 0px;
  left: 0px;
  width: 100px;
  max-height: 100%;
  overflow: hidden;

#tip 
  background: #ff0;
  height:20px;

#top 
  background: #f00;
  height:20px;

#btm 
  background: #0f0;
  overflow-y: auto;
  max-height: calc(100vh - 40px);


html, body 
  padding: 0;
  margin: 0;
  height:100%;
  width:100%;
<div id="container">
    <div id="tip">Tip</div>
    <div id="top">Top</div>
    <div id="btm">
      Btm<br>
      Btm<br>
      Btm<br>
      Btm<br>
      Btm<br>
      Btm<br>
      Btm<br>
      Btm<br>
      Btm<br>
      Btm<br>
      Btm<br>
      Btm<br>
      Btm<br>
      Btm<br>
      Btm<br>
      Btm<br>
      Btm<br>
      Btm<br>
      Btm<br>
      Btm<br>
    </div>
</div>

小提琴:https://jsfiddle.net/z87cnmr2/6/

【讨论】:

以上是关于使用具有最大高度的 Calc的主要内容,如果未能解决你的问题,请参考以下文章

父级具有最小/最大高度时的 CSS 百分比高度

CSS 获取当前可视屏幕高度--使用calc()方法动态计算宽度或者高度

vhvw 与 calc

具有固定列宽和最大高度的 CSS 表格

是否可以使用 CSS calc() 来计算宽度/高度比?

CSS 使用calc()获取当前可视屏幕高度