固定页眉与页内锚点重叠

Tom*_*lak 305 html url anchor fragment

如果我在HTML页面中有一个非滚动标题,则固定在顶部,具有已定义的高度:

有没有办法使用URL锚点(#fragment部分)让浏览器滚动到页面中的某个点,但是在没有JavaScript帮助的情况下仍然尊重固定元素的高度?

http://foo.com/#bar
Run Code Online (Sandbox Code Playgroud)
WRONG (but the common behavior):         CORRECT:
+---------------------------------+      +---------------------------------+
| BAR///////////////////// header |      | //////////////////////// header |
+---------------------------------+      +---------------------------------+
| Here is the rest of the Text    |      | BAR                             |
| ...                             |      |                                 |
| ...                             |      | Here is the rest of the Text    |
| ...                             |      | ...                             |
+---------------------------------+      +---------------------------------+

Adr*_*ner 234

如果您不能或不想设置新类,请在CSS中::before:target伪类中添加一个fixed-height 伪元素:

:target::before {
  content: "";
  display: block;
  height: 60px; /* fixed header height*/
  margin: -60px 0 0; /* negative fixed header height */
}
Run Code Online (Sandbox Code Playgroud)

或者:target使用jQuery 滚动页面:

var offset = $(':target').offset();
var scrollto = offset.top - 60; // minus fixed header height
$('html, body').animate({scrollTop:scrollto}, 0);
Run Code Online (Sandbox Code Playgroud)

  • 我非常喜欢你的解决方案.这是我发现的最干净的解决方案. (25认同)
  • 如果目标有顶部填充或边界,它将无法工作,因为它依赖于边缘崩溃. (10认同)
  • `:target`真棒! (7认同)
  • 这个解决方案对我来说非常有效,而且不会在我的页面布局中填充任何其他内容. (4认同)
  • 当目标位于弹性盒内时,这对我来说不起作用。 (4认同)
  • 与WebKit中的列表一起使用时,CSS解决方案存在问题.看:http://stackoverflow.com/questions/39547773/why-alignment-mark-list-is-different-on-webkit-when-using-before-height (2认同)
  • 仅供参考:如果目标锚元素的样式为“ display:table;”,则它将不起作用。 (2认同)

Mut*_*nXd 142

我有同样的问题.我通过向anchor元素添加一个类来解决它,topbar height作为padding-top值.

<h1><a class="anchor" name="barlink">Bar</a></h1>
Run Code Online (Sandbox Code Playgroud)

然后简单地说css:

.anchor { padding-top: 90px; }
Run Code Online (Sandbox Code Playgroud)

  • 我使用`.anchor:target {padding-top:90px;}`以便它们在使用锚标记时只添加填充.这样,如果页面加载在顶部,并不总是有一堆填充.仅当它在页面上加载较低的特定点时. (27认同)
  • @Tomalak请注意,此解决方案使填充区域内的链接不可单击.要解决此问题,您必须使用z-index,并将链接值设置为高于锚点.请记住,顶部栏应该具有最高的z-index值,因此滚动时页面的内容不会浮动到顶部栏的顶部. (17认同)
  • 正如Roy Shoa的回答所建议的那样,添加`margin-top:-90px;`来抵消填充所造成的差距. (7认同)
  • MuttenXd ..你是我的英雄.我在我的网站上遇到了奇怪的非功能链接问题(与主播无关)让我发疯.您的不可点击的评论确实有帮助.我欠你的大! (2认同)

小智 121

我用这种方法:

/* add class="jumptarget" to all targets. */

.jumptarget::before {
  content:"";
  display:block;
  height:50px; /* fixed header height*/
  margin:-50px 0 0; /* negative fixed header height */
}
Run Code Online (Sandbox Code Playgroud)

它在每个目标之前添加一个不可见元素.它适用于IE8 +.

以下是更多解决方案:http: //nicolasgallagher.com/jump-links-and-viewport-positioning/


dak*_*kur 45

从 2021 年 4 月开始,有一个非黑客且完全跨浏览器的解决方案:

h1 {
  scroll-margin-top: 50px
}
Run Code Online (Sandbox Code Playgroud)

它是CSS Scroll Snap 规范的一部分。在所有现代浏览器上运行。

  • `scroll-padding-top` 和 `scroll-margin-top` 有什么区别? (3认同)
  • 我建议使用选择器 `:target` 而不是给定的元素名称。 (3认同)

bln*_*lnc 41

官方自举通过答案:

*[id]:before { 
  display: block; 
  content: " "; 
  margin-top: -75px; // Set the Appropriate Height
  height: 75px; // Set the Appropriate Height
  visibility: hidden; 
}
Run Code Online (Sandbox Code Playgroud)

积分

合并

  • `*`暗示,`[id]:before`也适用 (4认同)
  • 此解决方案在与 WebKit 中的列表一起使用时会出现问题。看:http://stackoverflow.com/questions/39547773/why-alignment-mark-list-is-different-on-webkit-when-using-before-height (2认同)

Roy*_*hoa 27

我发现处理此问题的最佳方法是(用固定元素高度替换65px):

div:target {
  padding-top: 65px; 
  margin-top: -65px;
}
Run Code Online (Sandbox Code Playgroud)

如果您不想使用目标选择器,也可以这样做:

.my-target {
    padding-top: 65px;
    margin-top: -65px;
}
Run Code Online (Sandbox Code Playgroud)

注意:如果目标元素的背景颜色与其父元素不同,则此示例将不起作用.例如:

<div style="background-color:red;height:100px;"></div>
<div class="my-target" style="background-color:green;height:100px;"></div>
Run Code Online (Sandbox Code Playgroud)

在这种情况下,my-target元素的绿色将覆盖65px中的父红色元素.我没有找到任何纯CSS解决方案来处理这个问题,但如果你没有其他背景颜色,这个解决方案是最好的.

  • 在所有答案中,这是唯一一个对我有用的答案! (2认同)

Jps*_*psy 16

虽然一些建议的解决方案适用同一页面的片段链接(=哈希链接)(如向下滚动的菜单链接),但我发现当您想要使用来自其他网站的片段链接时,它们都不适用于当前的Chrome 页面.

因此,从头开始调用www.mydomain.com/page.html#foo 不会使用任何给定的CSS解决方案或JS解决方案来抵消当前Chrome中的目标.

还有一个jQuery错误报告描述了问题的一些细节.

到目前为止,我发现的唯一可以在Chrome中运行的选项是JavaScript,它不会被称为onDomReady但会有延迟.

// set timeout onDomReady
$(function() {
    setTimeout(delayedFragmentTargetOffset, 500);
});

// add scroll offset to fragment target (if there is one)
function delayedFragmentTargetOffset(){
    var offset = $(':target').offset();
    if(offset){
        var scrollto = offset.top - 95; // minus fixed header height
        $('html, body').animate({scrollTop:scrollto}, 0);
    }
}
Run Code Online (Sandbox Code Playgroud)

摘要

没有JS延迟解决方案可能适用于Firefox,IE,Safari,但不适用于Chrome.

  • 我得出了相同的结论和解决方案.似乎每个人都忘记了使用主题标签的外部链接. (3认同)
  • @kwiat1990:是的,这可能是可能的——但前提是你的 JS 放在 HTML 代码的最后。否则,您的滚动目标可能尚未位于 DOM 中。实际上,这就是使用 onDomReady 的全部意义。所以我想超时版本是稳定的选择。 (2认同)

dut*_*tzi 14

您现在可以使用已经被广泛采用的scroll-margin-top

只需将以下 CSS 添加到要滚动到的元素:

.element {
  scroll-margin-top: 2em;
}
Run Code Online (Sandbox Code Playgroud)

  • [本线程前面]已建议使用“scroll-margin-top”(/sf/answers/3897877651/) (3认同)
  • 这是我最喜欢的角色:`:target {scroll-margin-top: 2em; }` (2认同)

Fra*_*ain 11

html {
  scroll-padding-top: 70px; /* height of sticky header */
}
Run Code Online (Sandbox Code Playgroud)

来自:https : //css-tricks.com/fixed-headers-on-page-links-and-overlapping-content-oh-my/

  • 这应该是现在公认的答案。市场已经迎头赶上。 (6认同)
  • 浏览器支持:https://caniuse.com/#feat=mdn-css_properties_scroll-padding-top (5认同)
  • 这不适用于在 Edge 和 Safari 中滚动整个页面 (https://bugs.webkit.org/show_bug.cgi?id=179379)。 (3认同)
  • 救主!简单,说到点子上。其他解决方案都不适合我,因为我正在使用 display:flex。非常感谢,尝试所有解决方案真是令人沮丧。 (3认同)
  • 可能是我见过的最好的解决方案。 (2认同)

MrS*_*wed 8

对于Chrome/Safari/Firefox,您可以添加display: block并使用负边距来补偿偏移量,例如:

a[name] {
    display: block;
    padding-top: 90px;
    margin-top: -90px;
}
Run Code Online (Sandbox Code Playgroud)

请参见示例http://codepen.io/swed/pen/RrZBJo


jam*_*awe 8

刚刚发现了另一个纯 CSS 解决方案,它对我来说就像一个魅力!

html {
  scroll-padding-top: 80px; /* height of your sticky header */
}
Run Code Online (Sandbox Code Playgroud)

本站找到!

  • 其他一些人已经在您之前发现了此解决方案,请参阅第 1 页上的答案,例如 /sf/answers/3952759821/ (4认同)

小智 8

我没有看到简单使用:target列为选项的选项。我发现

:target { margin-top: -100px; padding-top: 100px; }

似乎在提供的场景中工作。:target还与所有现代浏览器兼容。https://caniuse.com/?search=%3Atarget


Eri*_*ood 7

我已经使用上面提到的“anchor:before”方法轻松地使用 CSS 和 HTML 工作。我认为它效果最好,因为它不会在您的 div 之间创建大量填充。

.anchor:before {
  content:"";
  display:block;
  height:60px; /* fixed header height*/
  margin:-60px 0 0; /* negative fixed header height */
}
Run Code Online (Sandbox Code Playgroud)

它似乎不适用于页面上的第一个 div,但您可以通过向第一个 div 添加填充来解决这个问题。

#anchor-one{padding-top: 60px;}
Run Code Online (Sandbox Code Playgroud)

这是一个工作小提琴:http : //jsfiddle.net/FRpHE/24/


ygo*_*goe 6

你可以试试这个:

<style>
h1:target { padding-top: 50px; }
</style>

<a href="#bar">Go to bar</a>

<h1 id="bar">Bar</h1>
Run Code Online (Sandbox Code Playgroud)

将顶部填充值设置为标题的实际高度。这将在您的标题顶部引入一个轻微的额外间隙,但只有当用户跳转到锚点然后向上滚动时它才会可见。我现在已经为我的网站制定了这个解决方案,但它只在页面顶部显示一个小的固定栏,没有太高。


web*_*aly 6

你可以用jQuery做到这一点:

var offset = $('.target').offset();
var scrollto = offset.top - 50; // fixed_top_bar_height = 50px
$('html, body').animate({scrollTop:scrollto}, 0);
Run Code Online (Sandbox Code Playgroud)


小智 6

我对上面列出的答案没有任何运气,最终使用了这个完美的解决方案......

在要设置锚点的位置创建一个空白跨度。

<span class="anchor" id="section1"></span>
<div class="section"></div>
Run Code Online (Sandbox Code Playgroud)

并应用以下类:

.anchor {
  display: block;
  height: 115px;       /* same height as header */
  margin-top: -115px;  /* same height as header */
  visibility: hidden;
}
Run Code Online (Sandbox Code Playgroud)

即使这些部分具有不同的颜色背景,此解决方案也将起作用!我在此链接中找到了解决方案

  • 这与 [Guillaume Le Mière](/sf/answers/3487853421/) 和其他一些人在此线程中展示的方法不完全相同吗? (2认同)

Luk*_*nii 6

我使用锚元素的滚动边距顶部属性解决了我的问题

scroll-margin-top: 100px;
Run Code Online (Sandbox Code Playgroud)

https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-margin-top


小智 5

这个对我有用:

HTML LINK to Anchor:

<a href="#security">SECURITY</a>
Run Code Online (Sandbox Code Playgroud)

HTML主播:

<a name="security" class="anchor"></a>
Run Code Online (Sandbox Code Playgroud)

CSS:

.anchor::before {
    content: "";
    display: block;
    margin-top: -50px;
    position: absolute;
}
Run Code Online (Sandbox Code Playgroud)


Ste*_*inq 5

我在这里和其他地方的许多答案都遇到了很多麻烦,因为我的书签锚点是常见问题页面中的部分标题,因此偏移标题没有帮助,因为其余内容只会留在原处。所以我想我会发帖。

我最终做的是几个解决方案的组合:

  1. CSS:

    .bookmark {
        margin-top:-120px;
        padding-bottom:120px; 
        display:block;
    }
    
    Run Code Online (Sandbox Code Playgroud)

其中“120px”是您的固定标题高度(可能加上一些边距)。

  1. 书签链接 HTML:

    <a href="#01">What is your FAQ question again?</a>
    
    Run Code Online (Sandbox Code Playgroud)
  2. 书签内容 HTML:

    <span class="bookmark" id="01"></span>
    <h3>What is your FAQ question again?</h3>
    <p>Some FAQ text, followed by ...</p>
    <p>... some more FAQ text, etc ...</p>
    
    Run Code Online (Sandbox Code Playgroud)

这个解决方案的好处是span元素不仅被隐藏,它本质上是折叠的,不会填充你的内容。

我不能对这个解决方案给予太多信任,因为它来自大量不同的资源,但在我的情况下它最适合我。

您可以在此处查看实际结果。