将块级元素拉伸到填满其父元素垂直滚动高度的100%。

11

我有一个带有垂直滚动的布局。可滚动的div中有一个绝对定位的子元素,它具有大的top值,在父级上引起了垂直滚动条。

可滚动的父div还有一些子div元素(我们称之为柱子),通过position: absolute和一些left值水平相邻地定位在一起。

以下是HTML标记:

<div id="root" style="height: 250px; position: relative;">
<div class="stretch">
    <div id="container" class="container">  
         <div id="pillar1" style="left: 0.0%; width:33.25%;" class="pillar" ></div>
         <div id="pillar2" style="left: 33.05%; width:33.25%;" class="pillar" ></div>
         <div id="pillar3" style="left: 66.05%; width:33.25%;" class="pillar" ></div>     
         <div id="fixed-and-not-movable" style="background: blue; width: 25px; height: 25px; top:350px; left: 150px; position: absolute;">
    </div>          
</div>

以及 CSS:

.stretch {
    bottom: 0; 
    left: 0; 
    right: 0; 
    top: 0; 
    position: absolute; 
    height: auto; 
    width: auto;    
}

.container {
    border: 2px solid;
    bottom: 0;
    left: 0;
    right: 0;
    top: 0;
    overflow-x: hidden;
    overflow-y: scroll;
    position: absolute;
}

.pillar {
    border: 1px dotted red;
    bottom: 0;
    height: 100%;
    position: absolute;
    top: 0;    
}

我希望柱形div可以捕获父元素“container”的整个滚动高度。目前它们的高度是父元素的客户端高度(而不是滚动高度)。因此,当您向下滚动时,您会注意到柱体没有填充溢出:滚动内所有可用的高度。

有人能建议更改CSS类(.container和/或.pillar)以使其生效吗?

这里有一个链接到js fiddle演示相同问题: http://jsfiddle.net/AshwinPrabhuB/2o5whkmq

谢谢!


我真的怀疑是否有纯CSS解决方案(定位的疯狂)。嗯,如果你能解释使用方法,可能还有另一种方法可以做到。否则,我想你只能等待并开始悬赏看看了。 - Stickers
@sdcr 我可以编写脚本来解决这个问题(就像这样:http://jsfiddle.net/AshwinPrabhuB/2o5whkmq/9/),但只有在没有非hacky的CSS解决方案的情况下才会采用这种方法。 - Ashwin Prabhu
类似问题:http://stackoverflow.com/questions/14498518/css-absolute-positioned-dialog-and-100-heighted-div?rq=1 - Ashwin Prabhu
4个回答

7
经过多次实验和头发拔光,我终于明白了这个问题没有完美的CSS解决方案。如果有人能证明我错了,我会非常高兴。
据我所知,这个问题是:如果父元素的高度没有明确定义,那么在纯跨浏览器兼容的CSS中,子元素无法垂直地拉伸到100%以填充其父元素的scrollHeight。
因此,根据上述结论,我通过在滚动容器下放置一个具有明确定义大小的div并在柱子上设置一个明确定义的min-height来解决了这个问题。我可以通过JavaScript计算出这个新的中间div的高度。
以下是修改后的HTML标记(只有fixedMinHeight div是新的):
<div id="root" style="height: 250px; position: relative;">
<div class="stretch">
    <div id="container" class="container">  
        <div id="fixedMinHeight" class="stretchFixed">
             <div id="pillar1" style="left: 0.0%; width:33.25%;" class="pillar" ></div>
             <div id="pillar2" style="left: 33.05%; width:33.25%;" class="pillar" ></div>
             <div id="pillar3" style="left: 66.05%; width:33.25%;" class="pillar" ></div>     
             <div id="fixed-and-not-movable" style="background: blue; width: 25px; height: 25px; top:350px; left: 150px; position: absolute;">
        </div>
    </div>          
</div>

而且CSS(.stretchFixed是之前添加的内容)

.stretch {
    bottom: 0; 
    left: 0; 
    right: 0; 
    top: 0; 
    position: absolute; 
    height: auto; 
    width: auto;    
}

.container {
    border: 2px solid;
    bottom: 0;
    left: 0;
    right: 0;
    top: 0;
    overflow-x: hidden;
    overflow-y: scroll;
    position: absolute;
}

.pillar {
    border: 1px dotted red;
    bottom: 0;
    height: 100%;
    position: absolute;
    top: 0;    
}

.stretchFixed {
  min-height: 375px;
  position: relative;
  height: 100%;
}

这是带有更改的fiddle链接:https://jsfiddle.net/AshwinPrabhuB/2o5whkmq/10/。或者,可以将相同的方案应用于每个单独的支柱,从而不需要DOM插入。我很愿意被证明是错误的,但在此期间,我可以使用这个解决方法。

3
div .pillar 给定了 position:absolute,因此它不会根据其父元素 .container 的高度进行调整。
只需从 .pillar 的 css 中删除 position:absolute 即可。
这里是FIDDLE
CSS 中的更改:
.pillar {
        border: 1px dotted red;
        bottom: 0;
        height: 100%;
        float:left;
        /*position: absolute;*/
        top: 0;  
        left:0 !important;
        width:32% !important;
    }

我将宽度设为32%,因为当前使用的边框不允许其适合给定的宽度。此外,现在没有必要显式地为每个支柱指定左值。所以我只是覆盖了这些值。
编辑: 我理解错了。现在这是更正过的内容。
将支柱的高度设为100vmax。 这个单位将使它占据视口的100/100大小,就我所知。虽然日志仍显示高度的不匹配值。但我想这已经足够接近了。此外,蓝色方框挡住了它的路。
请查看FIDDLE
.pillar {
    border: 1px dotted red;
    bottom: 0;
    height: 100vmax;
    float:left;
    /*position: absolute;*/
    top: 0;  
    left:0;
    width:32%;
}

我还看到高度没有占用吗?只有我一个人吗? - m4n0
我尝试了您建议的删除柱子中的绝对定位。没有发现任何区别,并且控制台日志也表明了这一点(柱子高度为246,通过CSS将它们设置为375)。 - Ashwin Prabhu
只是提醒一下,//position: absolute; 在 SCSS 中只是一个注释。正确的写法是 /*position: absolute;*/ - Jacob G
@KunjanThadani 感谢您的提示,但是100vmax会拉伸到视口高度,并且还会增加div的滚动高度以匹配视口高度。虽然这似乎有效,但这不是理想的解决方案,因为它会改变容器的滚动高度。 - Ashwin Prabhu
好的,我明白了。我会寻找一些解决方案。 - Kunjan Thadani

2

这是我想到的几个解决方案。 我认为你需要在容器内添加一个包装 div,如下所示:

<div id="container" class="container">  
    <div style="height:400px;">
         <div id="pillar1" class="pillar" ></div>
         <div id="pillar2" class="pillar" ></div>
         <div id="pillar3" class="pillar" ></div>     
         <div id="fixed-and-not-movable">
    </div>   
</div>

或者你需要给所有的支柱添加特定的高度。 这是因为你在支柱上使用了height:100%。所以它会匹配最近指定了高度的元素。 此外,我不知道是否由于你的场景要求,你必须添加那个.stretch div。对于这种情况,你根本不需要那个div。下面的代码与你的代码实现的功能相同。

<div id="root">
    <div id="container" class="container">  
        <div style="height:400px;">
            <div id="pillar1" class="pillar" ></div>
            <div id="pillar2" class="pillar" ></div>
            <div id="pillar3" class="pillar" ></div>     
            <div id="fixed-and-not-movable"></div> 
        </div>
    </div>
</div>

这就是我最终做的事情。请看我的答案。因此,我正在寻找一些不需要硬编码高度并引入JavaScript的东西。谢谢尝试! - Ashwin Prabhu

1

获取父元素最大高度的最佳方法是将其位置设置为固定或绝对,并且不提供高度值,而是将顶部属性设置为零,底部属性设置为零。

.parent {
  position: relative;

  .child {
    position: fixed; // or absolute
    top: 0; // anchors element to the top
    bottom: 0; // anchors element to the bottom
  }
 }

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