如何使内容出现在固定的DIV元素下方?

91
我的意图是在页面顶部创建一个菜单,即使用户滚动页面,它也会保持在页面的顶部(就像 Gmail 的最新功能一样,常用按钮会随着用户向下滚动而滚动,从而使他们能够在不必滚动到页面顶部的情况下执行消息操作)。
我还想设置菜单下方的内容出现在菜单下方 - 目前,它出现在菜单后面。
我希望实现类似于以下的效果:
+________________________+
|          MENU          | <--- Fixed menu - stays at top even when scrolling.
+¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬+
|     CONTENT BEGINS     |
|          HERE          |
|                        |
|                        |
|                        |
|                        |
|                        |
|                        |
+¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬+   <--- Bottom of page.

我希望在页面顶部有一个固定位置的菜单,无论用户滚动多少次页面都能保持在顶部。当用户在页面顶部时,主要内容必须出现在菜单下方,但是当用户向下滚动时,菜单可以覆盖内容。

总结:

  • 我希望在页面顶部有一个固定位置的菜单,它会随着用户的滚动而移动。
  • 仅当用户位于页面顶部时,内容才会出现在菜单下方。
    • 当用户向下滚动时,菜单可能会覆盖内容。

请问有人可以解释如何实现这个功能吗?

谢谢。

更新:

CSS代码:

#floatingMenu{
clear: both;
position: fixed;
width: 85%;
background-color: #78AB46;
top: 5px;
}

HTML代码:

<div id="floatingMenu">
    <a href="http://www.google.com">Test 1</a>
    <a href="http://www.google.com">Test 2</a>
    <a href="http://www.google.com">Test 3</a>
</div>  

目前,我可以通过将菜单放置在我的containerdiv中,在页面顶部居中显示菜单。 但是,内容会出现在菜单后面。 我已经设置了clear:both;,但这没有帮助。


1
我可以建议您查看这个链接,以获取您所寻找的良好实现?http://twitter.github.com/bootstrap/对于一般的良好CSS实践来说,这是一个很好的起点。 - Finnnn
5
2020 年,您现在可以使用 position: sticky; 了。如果您像我一样看到了这篇帖子,可以参考https://caniuse.com/#feat=css-sticky。 - Shaun Moore
13个回答

81

根据我理解,您需要一个额外的空白div。

这个div将放置在菜单和内容之间,并且与菜单div的高度相同,包括填充。

HTML

<div id="fixed-menu">
    Navigation options or whatever.
</div>
<div class="spacer">
    &nbsp;
</div>
<div id="content">
    Content.
</div>

CSS

#fixed-menu
{
    position: fixed;
    width: 100%;
    height: 75px;
    background-color: #f00;
    padding: 10px;
}

.spacer
{
    width: 100%;
    height: 95px;
}

请看我的例子这里

这个方法的原理是通过抵消导航栏所占用的空间,但是由于它具有 position: fixed; 属性,因此已经从文档流中移除了。


实现此效果的首选方法是在内容包装器上使用 margin-top: 95px;/*your nav height*/


4
今天这个额外的无用div还有必要吗? - MEM
1
不,你可以使用顶部边距将内容向下推到固定菜单下方。 - Kyle
15
在响应式设计的时代,我们仍然需要通过黑科技来实现固定大小的边距,这真的是令人非常失望。 - Phil Lello
9
如果您的“position:fixed”标题具有可变高度(例如,当您缩小浏览器窗口的宽度并使标题选项换行时,其高度会增加),则除了JavaScript之外,没有其他方法可以使这样的间隔div或边距与该可变高度以同步方式增加。 - Triynko
2
@Triynko,如果您的标题高度更改是由媒体查询(屏幕宽度断点)驱动的,例如使用Material Design框架(例如layout-sm="column")或Twitter Bootstrap(例如col-md-6),则可以根据相同的断点调整内容元素的填充。这样说通吗? - ctb
显示剩余4条评论

53

我刚刚也遇到了这个问题,不喜欢某些“hack”解决方案,但我发现这个方法既有用又干净:

#floatingMenu{
  position: sticky;
  top: 0;
}

3
太棒了!我不知道 position: sticky 这个属性!等一下,我的菜单能够保持粘性一段时间,然后随着滚动而离开页面。需要进一步尝试实验。 - Nick Timmer
1
这是一个很好的解决方案,但目前并不支持所有浏览器:https://caniuse.com/#feat=css-sticky :-( - Rich
1
小心粘性菜单!如果页眉中有长嵌套菜单(通常如此),这可能会导致某些项目无法访问,因为它们超出了屏幕。不过对于较小的紧凑型菜单等非常有效。 - dev101
为了让sticky生效,您的父元素不能有任何溢出属性,否则它将无法工作。https://dev59.com/o1cP5IYBdhLWcg3wvMdF#44929597 - T0plomj3r
1
看起来今天大多数浏览器都支持它,只是表头不支持 https://caniuse.com/#feat=css-sticky - Shaun Moore
这是正确的答案,其他做法都需要复制一些内容或逻辑,以确保间距始终与固定标头具有相同的高度,谢谢:D - Vincent

22
如果您的菜单高度是可变的(用于响应式设计或因为它是动态加载的),您可以将顶部边距设置为固定div结束的位置。例如:
CSS
.fixed-header {
    width: 100%;
    margin: 0 auto;
    position: fixed;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    -ms-box-sizing: border-box;
    box-sizing: border-box;
    z-index: 999;
}

Javascript

$(document).ready(function() {
    var contentPlacement = $('#header').position().top + $('#header').height();
    $('#content').css('margin-top',contentPlacement);
});

HTML

...
<div id="header" class="fixed-header"></div>
<div id="content">...</div>
...
这是一个小示例(https://jsfiddle.net/632k9xkv/5/),它不仅有一个固定的导航菜单和标题,而且试图使其成为一个有用的样本。

4
我更喜欢这个答案,因为它解决了当页眉高度发生变化时该怎么做的问题。在这方面,我觉得你的页眉通常会在布局框架(如Material Design或Bootstrap等)达到某个媒体断点时改变高度。如果是这样的话,你可以添加自己的CSS选择器来匹配媒体查询断点,以调整边距/填充以适应该屏幕尺寸。 - ctb
我认为这是一个很好的解决方案,因为你不需要指定像素高度,这使得这种方法非常适合在各种不同设备上的网站(PC、笔记本电脑、平板电脑、移动设备)。 - JeremyCanfield
完全同意,这是更好的方法。 - Kyle

6
我刚刚遇到了这个问题,这是我的解决方案:
#floatingMenu + * {
    margin-top: 35px;
}

调整您的floatingMenu的高度。如果您不确定它是否是一个跟随div,则可以使用*而不是div。这是所有有效CSS2。


想得很好 :) - Davi Lima

6

至少有一种方法可以在没有 JavaScript 的情况下实现真正的动态高度:将菜单插入两次

  • 一次在流中用于定位后续元素,
  • 一次固定以实现所需的视觉效果。

<div id="the-menu-container">
    <nav class="position-static">...</nav>
    <nav class="position-fixed">...</nav>
</div>

根据您网站的其他部分,您可能需要调整<nav>元素的z-index样式。


4
除了 position: sticky,这是唯一一种纯 CSS 解决方案并支持动态高度。如果使用像 React、Vue 等框架,你可以创建一个可重用组件来删除大部分重复代码。 - Raine Revere
1
确实,position: sticky 是首选的方式。记得要与它一起设置 top 属性...;-) - DerMike

5

我最喜欢grdevphl的Javascript答案,但在我的使用情况中,我发现在计算中仍然存在一些重叠,因为它没有考虑padding。如果你遇到同样的问题,请尝试使用outerHeight()来弥补padding和border。

$(document).ready(function() {
    var contentPlacement = $('#header').position().top + $('#header').outerHeight();
    $('#content').css('margin-top',contentPlacement);
});

3
用另一个div包装菜单内容:
<div id="floatingMenu">
    <div>
        <a href="http://www.google.com">Test 1</a>
        <a href="http://www.google.com">Test 2</a>
        <a href="http://www.google.com">Test 3</a>
    </div>
</div>

还有 CSS:

#floatingMenu {
    clear: both;
    position: fixed;
    width: 100%;
    height: 30px;
    background-color: #78AB46;
    top: 5px;
}

#floatingMenu > div {
    margin: auto;
    text-align: center;
}

关于菜单下面的页面,您也可以给它添加一个padding-top:

#content {
    padding-top: 35px; /* top 5px plus height 30px */
}

谢谢,这很棒 —— 在你发表回答之前我已经做了那个,但感谢你的帮助。 - Mus
1
@Mick,你修改后我更新了答案。看看它是否适用于你。 - Erick Petrucelli

3
#nav{
    position: -webkit-sticky; /* Safari */
    position: sticky;
    top: 0;
    margin: 0 auto;
    z-index: 9999;
    background-color: white;
}

请添加一个描述,说明这是对问题的答案。 - Poul Bak
这是非常非常棒的答案!非常感谢,你让我的一天变得美好。根据上述请求,是什么让你的解决方案起作用? - mwangaben

2

我刚刚在导航栏下面的 div 中添加了一个 padding-top。希望这有所帮助。我是新手。C:

#nav {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    margin: 0 auto;
    padding: 0;
    background: url(../css/patterns/black_denim.png);
    z-index: 9999;
}

#container {
    display: block;
    padding: 6em 0 3em;
}

无关紧要,但 z-index: 9999 可能没有帮助,并且会让你在像 bootstrap、material design 等框架中遇到真正的麻烦。一般来说,z-index 很容易失去追踪,并成为真正烦人的故障排除问题。 - ctb

2
对于那些建议使用margin-top或padding-top将主分区移动到固定菜单下方的人们 - 你们似乎没有完全测试它。
如果设置了边距或填充,它将随页面滚动,并且您将失去行数 - 前往this page试一下。
看起来不错,是吗?在可见底部行上突出显示一个单词,然后按Page Down键 - 带有突出显示单词和其他几行的行将滚动到固定分区下面。
Margin-top或padding-top会将主分区定位在固定分区下方,但是当您按Page Down键或单击滚动条以滚动页面的一个视口高度时,所有内容都会失败。
如果您向上翻页,同样的问题也会发生,“掉落”视口底部的行。
有人有这个问题的实际解决方法吗?
我知道如何定位东西 - 如果您了解有关边距,填充等基础知识,这相当容易 - 但是如何防止滚动时丢失行?
我已经查看了许多声称具有顶部固定分区的正确功能页面的示例,但它们无法正常工作!他们在滚动时都存在问题。
我遇到了一些页面似乎可以工作,但如果固定的部分高度增加,就会丢失一些行。我相信我知道它们为什么能够工作。
从一个完全正常(没有花哨的格式)的页面滚动文本的角度来思考。当你向上滚动时,你看到底部的行还是看到下一行——底部的行已经滚动到视口的顶部之外了吗?
答案是:你看到底部的行滚动到成为顶部的行。
那些似乎可以工作的固定菜单页面实际上并不是这样。滚动它们,底部的行被滚动到视口之外,但由于下一行可见,所以看起来固定的部分是有效的——但我们知道更好的,不是吗?
如果固定的部分高度超过一行文本的高度,它们就会失败,行就会丢失。
我见过的唯一真正有效的页面是在雅虎等网站上,但我没有时间也没有兴趣深入研究那些页面上大量的CSS、HTML和JavaScript,以便找到问题的核心。
因此,请前往该页面,看看是否可以进行更改("检查"元素并更改CSS规则),以解决滚动问题。
如果可以,回来并与世界分享你的发现。
我的页面是一个很好的地方,可以看到如何修复顶部分区、使其居中(以及主分区)并将其限制在最大宽度内。这可能会对一些人有所帮助,但很抱歉我没有解决滚动问题的方法。
尝试调整固定分区的高度 - 使其足够短,只显示一行,然后尝试滚动。然后将其调整为足够长,以便显示两行或三行,并尝试滚动。你会看到问题所在。 这里有一个页面,应该可以工作,但它没有 - 请阅读最后一条评论 - 他们用不同的方式描述了问题,但是问题是相同的。
我刚刚在Chrome中再次测试了该页面,似乎工作得相当令人满意。在FF中存在问题。还没有再次尝试IE。
那么 - FF有什么不同? 这里有一个cNet页面,在Chrome和FF中都能正常工作 - 那么他们做了什么?
通过对Chrome进行更多测试,发现在滚动时它无法完全显示底部行。当您滚动时,只有底部的一部分行是可见的,因此仍需要修复。

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