滑动元素 100% 向上和所有后续兄弟姐妹相同数量?



请考虑此文档:

<div id="container" class="no-panel">
<div id="panel">
<!-- Can be any DOM with arbitrary, variable height. 
120px is hardcoded only for the demo. -->
<div style="height: 120px">Some Contents</div>
</div>
<div id="contents">
<!-- Can be any DOM with arbitrary, variable height. 
300px is hardcoded only for the demo. -->
<div style="height: 300px">Some Contents</div>
</div>
</div>

#panel#contents都应该和它们的内容一样高,而不是更高(在示例中,我使用任意子div强制它们的高度 - 仅用于演示(。

我想将一个类应用于#container,这将使#panel一直向上滑动(因此它在视口的上边框后面变得不可见(。同时,#contents应该以#panel相同的速度向上滑动。我也喜欢动画(在演示中我使用了:hover而不是类(。

如何在不使用 JS的情况下做到这一点?它必须在Chrome/Firefox中工作,但我不关心其他浏览器。

我尝试设置translateY(-100%),这在#panel上工作正常,但随后#contents会相对于其高度移动100%,而不是#panel的高度,这太多了。

绝对定位不起作用,因为那时我需要固定#panel的高度,而我试图不这样做(它的内容应该会有所不同(。

JSFiddle,用一个关于我希望它如何工作的例子。 - 但带有我不想要的硬编码值。

这里的主要问题是,当您使用transform移动某些内容时,文档流中的元素位置/大小实际上并没有改变,只是元素的视觉位置发生了变化。

这种技术也是AFAIK唯一的技术,您可以在其中移动元素自己的未知高度(或宽度(,但由于其兄弟姐妹不知道它是否移动,因此它们也不会移动。

您这里有 2 个选项(基于 CSS(,您可以在其中将container嵌套在panel中,正如 lee comstock 在他们的答案中建议的那样,或者使用max-height技巧,您将它设置在panel上,其值高于您的预期。

如果你可以嵌套它们,那将是最有效的解决方案,因为它将是完全动态的

#container {
width: 100%;
height: 100%;
}
#panel, #contents {
transition: max-height 0.2s ease-in;   /*  changed from "all" to "max-height"  */
}
#panel {
background-color: tomato;
width: 100%;
height: auto;
max-height: 200px;                     /*  added  */
overflow: hidden;                      /*  added  */
}
#contents {
background-color: crimson;
width: 100%;
}
#container:hover #panel {
max-height: 0;                         /*  changed property  */
}
* {
box-sizing: border-box;
}
html, body {
padding: 0;
margin: 0;
}
<div id="container" class="no-panel">
<div id="panel">
<div style="height: 120px">
Some Panel Contents
</div>
</div>
<div id="contents">
<div style="height: 800px">
Some Contents Contents
</div>
</div>
</div>

诀窍是将 #contents 放在 #panel 内,并使用 position: absolute 将其放置在 #paneldiv 的底部边缘。

<div id="container" class="no-panel">
<div id="panel">
<div>text</div>
<div id="contents">
<div>text</div>
</div>
</div>
</div>
#container {
height: 100vh;
overflow: hidden;
}
#panel:hover {
transform: translateY(-100%);
}
#panel {
background: orange;
transition: 0.25s;
position: relative;
}
#contents {
background: brown;
position: absolute;
top: 100%;
}

工作小提琴

编辑:@kalsowerus评论中发布了类似但可能更好的方法,不需要嵌套元素。

从我们在评论中的对话中,我想出了一个简单的方法(见小提琴(。CSS 使用translate来隐藏#panel,并absolute相对于其父级(#container(移动的#contents的位置。

不幸的是,这种方法会影响父母的身高。

请注意,这只有在#panel#contents#container的唯一孩子的情况下才有效。

#container {
width: 100%;
height: 100%;
position: relative;
}
#panel, #contents {
transition: all 0.2s ease-in;
}
#panel {
background-color: tomato;
width: 100%;
height: auto; /* Has to be sized to fit its contents, and not more. */
}
#contents {
position: absolute;
top: 100%;
background-color: crimson;
width: 100%;
}
#container:hover #panel {
transform: translateY(-100%);
}
#container:hover #contents {
top: 0;
}
* {
box-sizing: border-box;
}
html, body {
padding: 0;
margin: 0;
}
<div id="container" class="no-panel">
<div id="panel">
<!-- Can be any DOM with arbitrary, variable height. 
120px is hardcoded only for the demo. -->
<div style="height: auto">Some Contents<br/>Some more contents</div>
</div>
<div id="contents">
<!-- Can be any DOM with arbitrary, variable height. 
300px is hardcoded only for the demo. -->
<div style="height: auto">Some Contents</div>
</div>
</div>

最新更新