绝对定位 + 滚动

179

使用以下 HTMLCSS

.container {
  position: relative;
  border: solid 1px red;
  height: 256px;
  width: 256px;
  overflow: auto;
}
.full-height {
  position: absolute;
  top: 0;
  left: 0;
  right: 128px;
  bottom: 0;
  background: blue;
}
<div class="container">
  <div class="full-height">
  </div>
</div>

内部的div按预期占据了容器的整个头部。如果我现在添加一些其他的流内容到容器中,例如:

.container {
  position: relative;
  border: solid 1px red;
  height: 256px;
  width: 256px;
  overflow: auto;
}
.full-height {
  position: absolute;
  top: 0;
  left: 0;
  right: 128px;
  bottom: 0;
  background: blue;
}
<div class="container">
  <div class="full-height">
</div>

  Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur mollitia maxime facere quae cumque perferendis cum atque quia repellendus rerum eaque quod quibusdam incidunt blanditiis possimus temporibus reiciendis deserunt sequi eveniet necessitatibus
  maiores quas assumenda voluptate qui odio laboriosam totam repudiandae? Doloremque dignissimos voluptatibus eveniet rem quasi minus ex cumque esse culpa cupiditate cum architecto! Facilis deleniti unde suscipit minima obcaecati vero ea soluta odio cupiditate
  placeat vitae nesciunt quis alias dolorum nemo sint facere. Deleniti itaque incidunt eligendi qui nemo corporis ducimus beatae consequatur est iusto dolorum consequuntur vero debitis saepe voluptatem impedit sint ea numquam quia voluptate quidem.
</div>

然后容器按预期滚动,但是绝对定位的元素不再锚定在容器底部,而是停止在容器可见底部的初始位置。我的问题是:有没有办法让绝对定位的元素成为其容器的完整滚动高度,而不使用JS?

我可以问一下为什么你在那里也加了 top:0; 吗? - Patsy Issa
没有特定的原因,我有过度规范事物的习惯。 - Chris Meek
如果您删除 top: 0;,它就不再起作用了。 - Brewal
没有JS计算innerHeight会很困难。不幸的是,position:fixed在容器内部不起作用,因为它超出了流程,所以这个“解决方法”也不起作用。 - RaphaelDDL
我的所有内容都在绝对定位的 div 内部,因此它们可以相互叠加。有没有办法只使用 CSS 来使主滚动条(控制 body)作为一个整体来控制所有绝对定位的 div,这样最高的 div 会生成溢出,而不需要另一个垂直滚动条? - David Spector
7个回答

141
你需要将文本放在一个 div 元素中,并在其中包含绝对定位的元素。
<div class="container">
    <div class="inner">
        <div class="full-height"></div>
        [Your text here]
    </div>
</div>

CSS:

.inner: { position: relative; height: auto; }
.full-height: { height: 100%; }

将内部div的位置设置为relative,使其内置的绝对定位元素的位置和高度基于它而不是具有固定高度的.container div来计算。没有内部的相对定位div.full-height div将始终根据.container计算其尺寸和位置。

* {
  box-sizing: border-box;
}

.container {
  position: relative;
  border: solid 1px red;
  height: 256px;
  width: 256px;
  overflow: auto;
  float: left;
  margin-right: 16px;
}

.inner {
  position: relative;
  height: auto;
}

.full-height {
  position: absolute;
  top: 0;
  left: 0;
  right: 128px;
  bottom: 0;
  height: 100%;
  background: blue;
}
<div class="container">
  <div class="full-height">
  </div>
</div>

<div class="container">
  <div class="inner">
    <div class="full-height">
    </div>

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur mollitia maxime facere quae cumque perferendis cum atque quia repellendus rerum eaque quod quibusdam incidunt blanditiis possimus temporibus reiciendis deserunt sequi eveniet necessitatibus
    maiores quas assumenda voluptate qui odio laboriosam totam repudiandae? Doloremque dignissimos voluptatibus eveniet rem quasi minus ex cumque esse culpa cupiditate cum architecto! Facilis deleniti unde suscipit minima obcaecati vero ea soluta odio
    cupiditate placeat vitae nesciunt quis alias dolorum nemo sint facere. Deleniti itaque incidunt eligendi qui nemo corporis ducimus beatae consequatur est iusto dolorum consequuntur vero debitis saepe voluptatem impedit sint ea numquam quia voluptate
    quidem.
  </div>
</div>

http://jsfiddle.net/M5cTN/


1
当然,这也有某种意义(以任何CSS的方式都是如此;)) - Chris Meek
18
“fill-height”元素显然随内容滚动,但是OP不是想将其锚定吗?(通过将蓝色背景更改为背景图像,您可以看到我所说的它没有被锚定的意思。http://jsfiddle.net/M5cTN/82/) - paulvs
只有当我在现有的div内部放置一个新的div,并设置overflow-y和max-height属性时,这才对我起作用。 - David Spector

55

position: fixed;可以解决您的问题。例如,您可以查看我编写的固定消息区域覆盖实现(通过程序填充):

#mess {
    position: fixed;
    background-color: black;
    top: 20px;
    right: 50px;
    height: 10px;
    width: 600px;
    z-index: 1000;
}

而在HTML中

<body>
    <div id="mess"></div>
    <div id="data">
        Much content goes here.
    </div>
</body>

#data的长度超过屏幕时,#mess在屏幕上保持位置不变,而#data在其下滚动。


122
固定定位将使元素相对于浏览器进行定位,这可能不是期望的结果。 - Avand Amiri
1
如果您不指定固定元素的顶部、左侧、右侧和底部位置,则它将不会相对于窗口定位。但这当然有限制使用,仅适用于默认的左上位置,否则它将相对于窗口定位,还有另一个缺点,width:100%或height:100%将与窗口尺寸相同。 - Herbi Shtini
6
在父元素上使用transform: translate3d(0,0,0);会使得position: fixed相对于父元素定位。来源 https://coderwall.com/p/2wzj-a/break-out-of-overflow-hidden-with-relative-positioned-fixed-elements - lkraav
但是这并不能解决当您需要固定元素和其父元素具有溢出隐藏时的情况。现在它的行为就像绝对定位。 - Adri HM
@AdriHM - 没错。这正是我的回答所说的。很抱歉它对你的情况没有帮助。giaour的回答可能更适合你的需求。 - flaschbier

20
所以gaiour是正确的,但如果你想要一个完整高度的项目,它不会随着内容滚动,而是容器的高度,这里有一个解决方法。有一个父元素,具有导致溢出的高度,一个内容容器,具有100%的高度和overflow:scroll,还有一个兄弟元素,可以根据父元素大小定位,而不是滚动元素大小。这是fiddle链接:http://jsfiddle.net/M5cTN/196/
相关代码:
html:
<div class="container">
  <div class="inner">
    Lorem ipsum ...
  </div>
  <div class="full-height"></div>
</div>

层叠样式表:

.container{
  height: 256px;
  position: relative;
}
.inner{
  height: 100%;
  overflow: scroll;
}
.full-height{
  position: absolute;
  left: 0;
  width: 20%;
  top: 0;
  height: 100%;
}

1
不幸的是,如果蓝色 div 位于其容器的右侧,则会隐藏其滚动条。 - papillon
1
如果有人正在寻找如何使用可变高度容器(例如height:100%)实现相同的结果,请阅读SO上的这篇帖子:https://dev59.com/t1cP5IYBdhLWcg3w-Otz - Marnix.hoh

2

.container {
  position: relative;
  border: solid 1px red;
  height: 256px;
  width: 256px;
  overflow: auto;
}
.full-height {
  position: absolute;
  top: 0;
  left: 0;
  right: 128px;
  bottom: 0;
  background: blue;
}
<div class="container">
  <div class="full-height">
  </div>
</div>


0

我遇到了这种情况,创建一个额外的div是不切实际的。 最终我只是将full-height div设置为height: 10000%; overflow: hidden;

显然这不是最干净的解决方案,但它非常快速有效。


0

并不是其他答案有什么问题,只是为了好玩,我复制了原始片段,唯一改变的是将height改成了min-height,而且我也不需要在任何地方添加另一个<div>

.container {
  position: relative;
  border: solid 1px red;
  min-height: 256px;
  width: 256px;
  overflow: auto;
}
.full-height {
  position: absolute;
  top: 0;
  left: 0;
  right: 128px;
  bottom: 0;
  background: blue;
}
<div class="container">
  <div class="full-height">
</div>

  Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur mollitia maxime facere quae cumque perferendis cum atque quia repellendus rerum eaque quod quibusdam incidunt blanditiis possimus temporibus reiciendis deserunt sequi eveniet necessitatibus
  maiores quas assumenda voluptate qui odio laboriosam totam repudiandae? Doloremque dignissimos voluptatibus eveniet rem quasi minus ex cumque esse culpa cupiditate cum architecto! Facilis deleniti unde suscipit minima obcaecati vero ea soluta odio cupiditate
  placeat vitae nesciunt quis alias dolorum nemo sint facere. Deleniti itaque incidunt eligendi qui nemo corporis ducimus beatae consequatur est iusto dolorum consequuntur vero debitis saepe voluptatem impedit sint ea numquam quia voluptate quidem.
</div>


0
.bottomDiv {
    position: relative;
    bottom: 0;
}

.parentDiv {
    display: flex;
    flex-direction: column;
}

.theDivPlacedOnTopofBottomDiv {
    flex-grow: 1 !important;
}

3
你的回答可以通过添加更多关于代码的信息以及它如何帮助提问者来改进。 - Tyler2P

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