CSS - 在能够滚动时定位绝对溢出父级
CSS - Position absolute overflow parent while being able to scroll
我正在尝试加载水平滚动的 divs。每个 div 都是绝对定位的(我的示例中的红色框),因此它在滚动容器外可见。我有一个效果很好的例子,但似乎我已经失去了滚动的能力。滚动条出现但滚动它不会移动 divs.
通过添加相对于整个容器的位置,我可以让 div 滚动,但它们不会显示在容器之外。
请帮助我能够在容器外显示内容并保持可滚动性。
<div style="overflow-x:scroll; height:40px; white-space: nowrap; background:black;">
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
</div>
我稍微编辑了您的代码片段并向黑色容器添加了一个 class,以便轻松地为其直接子级设置样式:
.container > div {
border: 1px solid green;
}
.container > div {
border: 1px solid green;
}
<div class="container" style="overflow-x:scroll; height:40px; white-space: nowrap; background:black;">
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
</div>
现在您应该能够看到滚动确实有效,但仅针对绿色 div。其他元素(黑色边框 div 和红色 div)没有滚动,因为它们有 position: absolute;
。这意味着它们被从文档流中取出,并且由于没有其他元素具有 position: relative
,它们相对于正文是绝对的。这就是为什么,如果您使用主滚动条滚动,它们实际上会滚动。
您可以将 position: relative;
添加到容器中,但如您所说,这样做不会使元素溢出容器。
据我所知,仅 css 无法解决此问题,您可能必须让它们滚动一些 Javascript。
一个非常基本的例子:
const container = document.querySelector('.container');
const boxes = document.querySelectorAll('.box');
container.addEventListener('scroll', (e) => {
let offset = e.target.scrollLeft;
for(let box of boxes) {
box.style.transform = `translateX(${offset}px)`;
}
});
.container > div {
border: 1px solid green;
}
.fake-width {
width: 2000px;
}
.boxes {
display: flex;
}
.box {
background: blue;
}
.box + .box {
margin-left: 50px;
}
<div class="container" style="overflow-x:scroll; height:40px; white-space: nowrap; background:black;">
<div class="fake-width"></div>
</div>
<div class="boxes">
<div class="box box-1" style="display:inline-block; margin-left:50px; width:500px; height:40px">
</div>
<div class="box box-2" style="display:inline-block; margin-left:50px; width:500px; height:40px">
</div>
<div class="box box-3" style="display:inline-block; margin-left:50px; width:500px; height:40px">
</div>
</div>
</div>
如您所见,如果采用这种方式,您甚至不需要将 div 保留在滚动容器中。您可以,具体取决于您要构建的内容,但您不需要。
我正在尝试加载水平滚动的 divs。每个 div 都是绝对定位的(我的示例中的红色框),因此它在滚动容器外可见。我有一个效果很好的例子,但似乎我已经失去了滚动的能力。滚动条出现但滚动它不会移动 divs.
通过添加相对于整个容器的位置,我可以让 div 滚动,但它们不会显示在容器之外。
请帮助我能够在容器外显示内容并保持可滚动性。
<div style="overflow-x:scroll; height:40px; white-space: nowrap; background:black;">
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
</div>
我稍微编辑了您的代码片段并向黑色容器添加了一个 class,以便轻松地为其直接子级设置样式:
.container > div {
border: 1px solid green;
}
.container > div {
border: 1px solid green;
}
<div class="container" style="overflow-x:scroll; height:40px; white-space: nowrap; background:black;">
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
<div style="display:inline-block; margin-left:50px; width:500px; height:40px">
<div style="border:1px solid black; height:40px; width:500px; position:absolute">
<div style="position:absolute; height:100px;width:500px; background:Red; top:5px; left:5px"></div>
</div>
</div>
</div>
现在您应该能够看到滚动确实有效,但仅针对绿色 div。其他元素(黑色边框 div 和红色 div)没有滚动,因为它们有 position: absolute;
。这意味着它们被从文档流中取出,并且由于没有其他元素具有 position: relative
,它们相对于正文是绝对的。这就是为什么,如果您使用主滚动条滚动,它们实际上会滚动。
您可以将 position: relative;
添加到容器中,但如您所说,这样做不会使元素溢出容器。
据我所知,仅 css 无法解决此问题,您可能必须让它们滚动一些 Javascript。
一个非常基本的例子:
const container = document.querySelector('.container');
const boxes = document.querySelectorAll('.box');
container.addEventListener('scroll', (e) => {
let offset = e.target.scrollLeft;
for(let box of boxes) {
box.style.transform = `translateX(${offset}px)`;
}
});
.container > div {
border: 1px solid green;
}
.fake-width {
width: 2000px;
}
.boxes {
display: flex;
}
.box {
background: blue;
}
.box + .box {
margin-left: 50px;
}
<div class="container" style="overflow-x:scroll; height:40px; white-space: nowrap; background:black;">
<div class="fake-width"></div>
</div>
<div class="boxes">
<div class="box box-1" style="display:inline-block; margin-left:50px; width:500px; height:40px">
</div>
<div class="box box-2" style="display:inline-block; margin-left:50px; width:500px; height:40px">
</div>
<div class="box box-3" style="display:inline-block; margin-left:50px; width:500px; height:40px">
</div>
</div>
</div>
如您所见,如果采用这种方式,您甚至不需要将 div 保留在滚动容器中。您可以,具体取决于您要构建的内容,但您不需要。