偏移html锚点以调整固定标题

offsetting an html anchor to adjust for fixed header
1430

我正在努力清理锚的工作方式。我有一个固定在页面顶部的标题,因此当您链接到页面中其他位置的锚时,页面会跳转,因此锚位于页面顶部,而内容则位于固定标题(I hope that makes sense)后面。我需要一种方法,将锚从收割台高度偏移25px。我更喜欢HTML或CSS,但JavaScript也可以接受。


2
我认为 stackoverflow.com/questions/1431639/general-offset-for-all-anchors-in-html 中显示的包装 div 很好,不是太激进。
ron

48
有一篇关于此subject: css-tricks.com/hash-tag-links-padding的好文章
J. Bruni


1
@0fnt这实际上是那篇文章的复制品。为什么不关门?
Pacerier

5
将此标记为重复的问题不接受javascript解决方案。这个问题有脚本解决方案。应该重新开放。
Hüseyin Yağlı

20
@J.Bruni有一篇更新得多的CSS-tricks.com文章介绍scroll-padding-top here: css-tricks.com/fixed-headers-on-page-links-and-overlapping-content-oh-my
Flimm

21
我希望这些帖子能更新。。我使用 :target {{ scroll-margin-top: 24px; }}
Dan Wood

回答:


1456

您可以只使用CSS而不使用任何JavaScript。

给你的主播上课:

<a class="anchor" id="top"></a>

然后,通过将锚定元素设置为块元素并对其进行相对定位,可以将其定位在高于或低于其在页面上实际显示位置的偏移量。-250px将把锚定位在250像素以上

a.anchor {{
    display: block;
    position: relative;
    top: -250px;
    visibility: hidden;
}}

16
这是更好的答案,因为它不依赖于位置设置为“相对”的父元素。谢谢你发帖。
Eric Mill

2
我建议其他人使用这个而不是span标签。如果要添加标记,不妨将其作为传统的锚定标记。
Azmisov

90
爱你的解决方案!它似乎不适用于IE7。从现在开始,我打算忽略IE7用户。
user334639

128
如果希望对可见元素执行此操作,还可以使用伪元素,即la.thing-with-anchor:before {{ content: ''; display: block; position: relative; width: 0; height: 5em; margin-top: -5em }}显示块和相对位置是必需的。
harpo

23
我们不再使用带有href属性的标签了。相反,我们应该在heading/section/etc中为锚定文本使用id标记。那么解决办法是什么呢?
Alice Wonder

20
@harpo: 好主意,但行不通。在Chrome 40中试用。
Hannobo

1
是否有一种很好的方法来处理多个固定头大小e.g。反应灵敏的人会改变它的高度吗?
shadowhorst

1
这对我不起作用,最好的是Alexander Savin solution
xchiltonx

3
如果要使用:target,则此操作不起作用。
Etienne Dupuis

1
您也可以使用following: a[id]:not([href]),而不是使用显式选择器
dude

1
我非常喜欢THIS答案better: stackoverflow.com/a/28824157/714733 (in the dupe question)
jazzcat

2
为了保持动态,您可以使用类似top: calc(-<?php echo $fixed_header_height; ?> - 20px);的东西在菜单和锚点之间留出一些空间。
Henning Fischer

1
这对我使用Bootstrap 4:
很有效
qxotk

1
@harpo,这会阻止被不可见元素覆盖的文本和链接,使其不可选择和不可单击。
WoodrowShigeru

3
此(as of 2021)的更新答案是使用scroll-padding css-tricks.com/almanac/properties/s/scroll-padding
Nathan

443

我找到了这个解决方案:

<a name="myanchor">
    <h1 style="padding-top: 40px; margin-top: -40px;">My anchor</h1>
</a>

这不会在内容和锚链接上产生任何差距,效果非常好。


8
效果很好。我创建了一个特殊的CSS锚类,并将其附加到我的anchors: .谢谢。

3
导航中的指示灯仍有刺耳的声音。因此,如果你向下滚动页面,活动导航项不会切换,直到你滚动过锚定目标。
Randy L

43
由于隐藏了填充/边距,因此

上方的元素将不可单击。我最终使用了Ian Clack的jQuery解决方案,该解决方案非常有效。

Matt

2
如何使用使用元素ID i.e的锚点。

文本

。..链接?
Alek Davis

7
我想我弄明白了:h2[id],h3[id],h4[id],a[name] { padding-top: XXpx; padding-bottom: XXpx; }它适用于所有带有ID的h2,h3,h4标记,以及命名锚点。
Alek Davis

2
为了防止上面的元素不可点击,可以在h*元素上设置负z索引。h3[id] {{ z-index: -1; }}
DVK

233

FWIW这对我有用:

[id]::before {{
  content: '';
  display: block;
  height:      75px;
  margin-top: -75px;
  visibility: hidden;
}}

7
我不完全理解这为什么有效,但从我这里+1。其他方法都不如这一方法容易实现或工作得好。:-)
JackWilson

2
我把它包装在一个媒体查询中,所以它只适用于我有固定导航的中大屏幕。
Ron

3
这可能有效,但会与标题前的内容重叠。
dude

2
有人能解释一下为什么会这样吗?
Brady Holt

1
在所有答案中,这是我最喜欢的解决方案,但当links元素本身是链接时,这不是一个好方法。height值会创建一个大的点击板,延伸到用户希望链接的区域之外。为了保持敲击垫较小,我做了this: content: '\00a0'; width: '1px'; margin-left: '-1px';padding-top: 75px; --这将创建一个有效的元素,该元素将向下推滚动条,而不会留下任何意外的可单击区域。
jamesfacts

3
太棒了!但是,如果[id]元素是display: flex容器的子级,则此方法无效:::before元素创建的高度不会影响[id]元素的高度,因为flex ‍♀️
Henry Blyth

1
我有很多ID不是锚的元素。这对他们造成了极大的破坏。
clayRay

1
这个解决方案看起来不错,但如果我添加css,它会破坏我们网站的整体布局。
Black

226

我也在寻找解决办法。就我而言,这很容易。

我有一个包含所有链接的列表菜单:

<ul>
<li><a href="#one">one</a></li>
<li><a href="#two">two</a></li>
<li><a href="#three">three</a></li>
<li><a href="#four">four</a></li>
</ul>

下面是标题。

<h3>one</h3>
<p>text here</p>

<h3>two</h3>
<p>text here</p>

<h3>three</h3>
<p>text here</p>

<h3>four</h3>
<p>text here</p>

现在,因为我的页面顶部有一个固定的菜单,我不能让它直接进入我的标签,因为它会在菜单后面。

取而代之的是,我在标签里放了一个带有正确id的span标签。

<h3><span id="one"></span>one</h3>

现在使用2行CSS来正确定位它们。

h3{{ position:relative; }}
h3 span{{ position:absolute; top:-200px;}}

更改顶部值以匹配固定标题(or more)的高度。现在我假设这也适用于其他元素。


5
span可以替换为a
David Cook

2
这真的很好用,避免了我用其他技术遇到的一些问题,比如当使用h2标记设置填充顶部时。
Jonathan

187

由于这是表示方面的问题,因此纯CSS解决方案是理想的。但是,此问题是在2012,中提出的,尽管已建议了相对定位/负边距解决方案,但这些方法似乎相当笨拙,会产生潜在的流问题,并且无法动态响应DOM /视口中的更改。

考虑到这一点,我相信使用JavaScript是still (February 2017)最好的方法。下面是一个普通的JS解决方案,它将响应锚定单击并在加载(See JSFiddle)时解析页面哈希。如果需要动态计算,请修改.getFixedOffset()方法。如果使用jQuery, here's a modified solution with better event delegation and smooth scrolling

(function(document, history, location) {{
  var HISTORY_SUPPORT = !!(history && history.pushState);

  var anchorScrolls = {{
    ANCHOR_REGEX: /^#[^ ]+$/,
    OFFSET_HEIGHT_PX: 50,

    /**
     * Establish events, and fix initial scroll position if a hash is provided.
     */
    init: function() {{
      this.scrollToCurrent();
      window.addEventListener('hashchange', this.scrollToCurrent.bind(this));
      document.body.addEventListener('click', this.delegateAnchors.bind(this));
    }},

    /**
     * Return the offset amount to deduct from the normal scroll position.
     * Modify as appropriate to allow for dynamic calculations
     */
    getFixedOffset: function() {{
      return this.OFFSET_HEIGHT_PX;
    }},

    /**
     * If the provided href is an anchor which resolves to an element on the
     * page, scroll to it.
     * @param  {{String}} href
     * @return {{Boolean}} - Was the href an anchor.
     */
    scrollIfAnchor: function(href, pushToHistory) {{
      var match, rect, anchorOffset;

      if(!this.ANCHOR_REGEX.test(href)) {{
        return false;
      }}

      match = document.getElementById(href.slice(1));

      if(match) {{
        rect = match.getBoundingClientRect();
        anchorOffset = window.pageYOffset + rect.top - this.getFixedOffset();
        window.scrollTo(window.pageXOffset, anchorOffset);

        // Add the state to history as-per normal anchor links
        if(HISTORY_SUPPORT && pushToHistory) {{
          history.pushState({{}}, document.title, location.pathname + href);
        }}
      }}

      return !!match;
    }},

    /**
     * Attempt to scroll to the current location's hash.
     */
    scrollToCurrent: function() {{
      this.scrollIfAnchor(window.location.hash);
    }},

    /**
     * If the click event's target was an anchor, fix the scroll position.
     */
    delegateAnchors: function(e) {{
      var elem = e.target;

      if(
        elem.nodeName === 'A' &&
        this.scrollIfAnchor(elem.getAttribute('href'), true)
      ) {{
        e.preventDefault();
      }}
    }}
  }};

  window.addEventListener(
    'DOMContentLoaded', anchorScrolls.init.bind(anchorScrolls)
  );
}})(window.document, window.history, window.location);

4
效果很好,但对于jquery 1.7+,使用 $("a").on("click",...而不是 $("a").live("click",...
JasonS

5
很好的评论,我将更新:) - BTW,它也应该是$("body").on("click", "a"...,因为它可能需要为脚本添加到文档中的锚工作(hence why I was using .live)
Ian Clark

3
另外,值得注意的是,这会扰乱其他的href/id对,如折叠,旋转木马等。有什么简单的办法吗?
tom10

3
@tom10 我想您只需要使选择器更加具体,或者使用a:not(.not-anchor) (or something less confusingly named)将锚点列入黑名单,然后确保您的折叠/旋转木马库将这些类添加到它们的锚点。如果您使用jQuery UI或Bootstrap,我想它们会添加一些您可以引用的其他类。
Ian Clark

2
@tom10 我已在href中为#的测试添加了一些条件,以避免崩溃和carousel: if(href.indexOf("#") == 0 && (!$(this).data() || this.self == window))
raddevon

1
非常感谢!我也有指向其他带有锚点的页面的链接, e.g。/page/#anchor.此正则表达式涵盖those: /^[\/a-z0-9-]*#[^\s]+$/
tobiv

5
如果连续(from menu with anchor links)在同一定位点上单击两次,则第二次单击效果不佳。

1
仍在2018中工作。很棒的JQuery解决方案,谢谢。我很想知道现在是否有人有更好的方法,但这是我能找到的最好的方法
rickjerrity


1
这对页面加载不起作用,对吗?只有当我点击页面上的锚时?
Adam

1
我找到了第二次点击锚不起作用的问题的原因。正则表达式只适用于以#开头的链接,而不适用于像/some-url/#anchor这样的链接。它始终在scrollIfAnchor函数中返回false,而scrollToCurrent函数正在工作。
jwinn

94

受亚历山大·萨文启发的纯css解决方案:

a[name] {{
  padding-top: 40px;
  margin-top: -40px;
  display: inline-block; /* required for webkit browsers */
}}

如果目标仍不在屏幕上,您也可以选择添加以下内容:

  vertical-align: top;

7
我刚刚在Chrome上试用过,不需要显示内联块。
Asrail

2
@Asrail 对我来说,没有它就不行
Hameno

1
对我来说, "display: inline-block;"完全破坏了Chrome (all links became unclickable)中的功能。
Alek Davis

2
[name]选择器不应影响链接
Ziav


82

我的解决方案结合了CMS的目标和之前选择器。其他技术无法解释锚中的文本。将高度和负边距调整到所需的偏移量.

:target::before {{
    content: '';
    display: block;
    height:      180px;
    margin-top: -180px;
}}

3
这两个CSS解决方案乍一看不适合我,但最终我发现它 ** 可能与其他CSS属性 ** 不兼容。添加了一个包装器,解决了这个问题。:target:before与display:block的组合最适合我。
John

2
[Solved]此解决方案有效,我将此解决方案用于display: block;。没有特殊类、空标记或javascript。
Amir Astaneh

5
如果您决定使用此方法,那么添加pointer-events: none;可能也是一个好主意。因为与不可见覆盖(above the anchor)相交的链接将无法单击。
Steven

2
这种解决方案通过断开它们的连接,将崩溃的利润率搞得一团糟。编辑:我只是把id放在<h1>上,而不是<section>上,效果很好
Volper

9
如果只支持现代浏览器可以,我建议只支持:target {{ scroll-margin-top: 180px; }} (or any other measurement or calc() you wish)。
Mikko Rantalainen

49

这将从以前的答案中获取许多元素,并组合成一个极小的(194字节(缩小)匿名jQuery函数。根据菜单或块元素的高度调整fixedElementHeight

    (function($, window) {{
        var adjustAnchor = function() {{

            var $anchor = $(':target'),
                    fixedElementHeight = 100;

            if ($anchor.length > 0) {{

                $('html, body')
                    .stop()
                    .animate({{
                        scrollTop: $anchor.offset().top - fixedElementHeight
                    }}, 200);

            }}

        }};

        $(window).on('hashchange load', function() {{
            adjustAnchor();
        }});

    }})(jQuery, window);

如果不喜欢动画,请替换

$('html, body')
     .stop()
     .animate({{
         scrollTop: $anchor.offset().top - fixedElementHeight
     }}, 200);

与:

window.scrollTo(0, $anchor.offset().top - fixedElementHeight);

丑陋的版本:

 !function(o,n){{var t=function(){{var n=o(":target"),t=100;n.length>0&&o("html, body").stop().animate({{scrollTop:n.offset().top-t}},200)}};o(n).on("hashchange load",function(){{t()}})}}(jQuery,window);

1
这个解决方案确实帮了我的忙,但它在IE9-11中并没有始终如一地发挥作用。有时它工作,其他一些点击它不(scroll position stays at the anchor position)。我完全不知道是什么导致了这个问题。
ericstumper

2
@MajesticRa 一个棘手的问题是加载或滚动事件中的操作顺序。如果您的页面在加载或滚动页面(shrinking masthead for example)后调整布局,则:target偏移量的计算可能会出错。
Lance

1
这解决了我的问题。也许值得把这句话放在答案中。
MajesticRa

42

对于现代浏览器,只需将CSS3 :target选择器添加到页面。这将自动应用于所有锚点。

:target {{
    display: block;    
    position: relative;     
    top: -100px;
    visibility: hidden;
}}

14
您甚至可以执行:target:before来创建一个隐藏的伪元素,而不是隐藏整个目标。
Tavian Barnes

1
当您以HTML5方式(and I think 4 too)执行操作时,如果您将node(如节或标题)中的id属性作为目标,则这种方式会导致元素在其上方显示重叠元素。
Alice Wonder

5
在大多数情况下,隐藏:target似乎是个坏主意。您授予任何人谁发送一个链接到您的页面的权力,以挑选任何元素与ID和删除它从页面,观众将看到。在驯服的一面,精通技术的恶作剧者可能会注意到这一点,并决定从中获得一些乐趣,就像他们曾经通过操纵他们的URL在Facebook上制作一些新闻网站的链接并显示愚蠢的标题一样。更严重的是,如果您的页面包含类似"don't share this secret information with anyone"的带有ID的消息,则可能存在安全漏洞。
Mark Amery

1
将此代码添加到样式表对我在当前工作的网站中使用Chrome 60.0.3112.78没有任何帮助-尽管这很可能是由于交互效果.你能寄支笔吗?
Julix

41

你可以不用js,也不用修改html。它只是css。

a[id]::before {{
    content: '';
    display: block;
    height: 50px;
    margin: -30px 0 0;
}}

这将在每个带有id的a标记之前附加一个伪元素。调整值以匹配收割台的高度。


7
有趣的想法,但请注意,如果碰巧有与id的可见链接,则会导致显示出错。
harpo

3
如果你想知道为什么它不适合你,检查一下父元素是否没有边境或 *padding*。
byashimov

2
我修改了它以选择:target[id]:before,因为我锚定链接的id有时是h1-h6。
KFunk

1
高度和负边距应该匹配,对吗?
Facundo Colombier

34

我一直面临着类似的问题,不幸的是,在实施了上述所有解决方案后,我得出了以下结论。

  1. 我的内部元素有一个脆弱的CSS结构,实现一个位置相对/绝对播放,完全打破了页面设计。
  2. CSS不是我的强项。

我写了这个简单的滚动js,它解释了由于标题引起的偏移量,并将div重定位在下面约125像素处。请使用你认为合适的。

HTML

<div id="#anchor"></div> <!-- #anchor here is the anchor tag which is on your URL -->

JavaScript

 $(function() {{
  $('a[href*=#]:not([href=#])').click(function() {{
    if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') 
&& location.hostname == this.hostname) {{

      var target = $(this.hash);
      target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
      if (target.length) {{
        $('html,body').animate({{
          scrollTop: target.offset().top - 125 //offsets for fixed header
        }}, 1000);
        return false;
      }}
    }}
  }});
  //Executed on page load with URL containing an anchor tag.
  if($(location.href.split("#")[1])) {{
      var target = $('#'+location.href.split("#")[1]);
      if (target.length) {{
        $('html,body').animate({{
          scrollTop: target.offset().top - 125 //offset height of header here too.
        }}, 1000);
        return false;
      }}
    }}
}});

请参阅live implementation here


13

按照@moeffju的建议,这可以是achieved with CSS。我遇到的问题(which I'm surprised I haven't seen discussed)是使用填充或透明边框重叠前面的元素的技巧,以防止在这些部分的底部执行悬停和单击操作,因为下面的操作在z顺序中更高。

我发现的最佳修复方法是将节内容放置在z-index: 1:处的div

// Apply to elements that serve as anchors
.offset-anchor {{
  border-top: 75px solid transparent;
  margin: -75px 0 0;
  -webkit-background-clip: padding-box;
  -moz-background-clip: padding;
  background-clip: padding-box;
}}

// Because offset-anchor causes sections to overlap the bottom of previous ones,
// we need to put content higher so links aren't blocked by the transparent border.
.container {{
  position: relative;
  z-index: 1;
}}

13

对于同一个问题,我使用了一个简单的解决方案:在每个锚点上放置一个40px的填充顶部。


2
谢谢,这基本上就是我最后要做的,但我想知道是否有一个解决方案,可以解决添加额外填充可能会很尴尬的情况。
Ben

12

具有更改位置属性的解决方案并不总是可行(it can destroy layout),因此我建议:

HTML:

<a id="top">Anchor</a>

CSS:

#top {{
    margin-top: -250px;
    padding-top: 250px;
}}

使用这个:

<a id="top">&nbsp;</a>

要最小化重叠,请将字体大小设置为1px。空锚在某些浏览器中不起作用。


11

从给定的答案at this link (no author is specified)中借用一些代码,您可以在锚中包含一个漂亮的平滑滚动效果,同时使其在锚上方的-60px处停止,从而很好地适应固定引导程序导航栏(requires jQuery):的下方

$(".dropdown-menu a[href^='#']").on('click', function(e) {{
   // prevent default anchor click behavior
   e.preventDefault();

   // animate
   $('html, body').animate({{
       scrollTop: $(this.hash).offset().top - 60
     }}, 300, function(){{
     }});
}});

1
谢谢,这是twitter引导用户的解决方案
Sebastian Viereck

4

如果您的锚是表元素或在表(row or cell)中,则上述方法无法很好地工作。

我不得不使用JavaScript并绑定到窗口hashchange事件来解决此(demo):问题

function moveUnderNav() {{
    var $el, h = window.location.hash;
    if (h) {{
        $el = $(h);
        if ($el.length && $el.closest('table').length) {{
            $('body').scrollTop( $el.closest('table, tr').position().top - 26 );
        }}
    }}
}}

$(window)
    .load(function () {{
        moveUnderNav();
    }})
    .on('hashchange', function () {{
        moveUnderNav();
    }});

* 注意:hashchange事件并非在所有浏览器中都可用。


3

与其有一个固定位置的导航栏,而该导航栏被页面(with the whole page body being scrollable)的其余内容覆盖,不如考虑使用一个带有静态导航栏的不可滚动正文,然后将页面内容放在下面一个绝对位置的可滚动div中。

也就是说,有HTML这样.

<div class="static-navbar">NAVBAR</div>
<div class="scrollable-content">
  <p>Bla bla bla</p>
  <p>Yadda yadda yadda</p>
  <p>Mary had a little lamb</p>
  <h2 id="stuff-i-want-to-link-to">Stuff</h2>
  <p>More nonsense</p>
</div>

...和CSS如下所示:

.static-navbar {{
  height: 100px;
}}
.scrollable-content {{
  position: absolute;
  top: 100px;
  bottom: 0;
  overflow-y: scroll;
  width: 100%;
}}

但是,此方法有一个明显的缺点,即当页面标题中的元素处于焦点状态时,用户将无法使用键盘(e.g滚动页面。通过向上和向下箭头或Page Up和Page Down键)。

Here's a JSFiddle demonstrating this in action.


3
非黑客, but: (1)在此示例之外完全无用, (2)采用和维护繁琐, (3)反语义和/或滥用CSS, (4)不直观。任何一天我都会用清洁的 a:before {{...}}解决这个问题!
Ярослав Рахматуллин

1
这是ABSOLUTELY最佳解决方案。它不需要黑客或伪类。我还发现它具有100%语义。本质上,页面中有一部分是你想要滚动的,你可以明确地设置它。此外,它完全解决了如何使标题消失在没有背景的导航后面的问题。
abalter

3

您可以使用a[name]:not([href])css选择器在没有ID的情况下实现这一点。这只是查找带有名称且没有hrefe.g的链接。<a name="anc1"></a>

一个示例规则可能是:

a[name]:not([href]){{
    display: block;    
    position: relative;     
    top: -100px;
    visibility: hidden;
}}

2
注意,在HTML5中,a元素没有name属性,因此这不起作用。
Geoff

2

这是受Shouvik回答的启发——与他的概念相同,只是固定标题的大小不是硬编码的。只要您的固定标头位于第一个标头node中,则此应"just work"

/*jslint browser: true, plusplus: true, regexp: true */

function anchorScroll(fragment) {{
    "use strict";
    var amount, ttarget;
    amount = $('header').height();
    ttarget = $('#' + fragment);
    $('html,body').animate({{ scrollTop: ttarget.offset().top - amount }}, 250);
    return false;
}}

function outsideToHash() {{
    "use strict";
    var fragment;
    if (window.location.hash) {{
        fragment = window.location.hash.substring(1);
        anchorScroll(fragment);
    }}
}}

function insideToHash(nnode) {{
    "use strict";
    var fragment;
    fragment = $(nnode).attr('href').substring(1);
    anchorScroll(fragment);
}}

$(document).ready(function () {{
    "use strict";
    $("a[href^='#']").bind('click',  function () {{insideToHash(this); }});
    outsideToHash();
}});

1

我在一个TYPO3网站中遇到了这个问题,其中所有"Content Elements"都用如下内容包装:

<div id="c1234" class="contentElement">...</div>

我更改了渲染,使其呈现如下:

<div id="c1234" class="anchor"></div>
<div class="contentElement">...</div>

这个CSS:

.anchor{{
    position: relative;
    top: -50px;
}}

固定顶杆高度为40px,现在锚再次工作,并在顶杆下方开始10px。

这种技术的唯一缺点是您不能再使用:target


2
实际上,您可以像使用so: .anchor:target+div一样使用:target
lipsumar

0

对来自@Jan的优秀答案的进一步扭曲是将其合并到使用jQuery (or MooTools)的#uberbar固定标头中。(http://davidwalsh.name/persistent-header-opacity)

我已经调整了代码,使内容的顶部始终位于固定标题之下,而不是固定标题之下,并再次添加了来自@Jan的锚,以确保锚始终位于固定标题之下。

CSS:

#uberbar {{ 
    border-bottom:1px solid #0000cc; 
    position:fixed; 
    top:0; 
    left:0; 
    z-index:2000; 
    width:100%;
}}

a.anchor {{
    display: block;
    position: relative;
    visibility: hidden;
}}

jQuery (including tweaks to both the #uberbar and the anchor approaches:

<script type="text/javascript">
$(document).ready(function() {{
    (function() {{
        //settings
        var fadeSpeed = 200, fadeTo = 0.85, topDistance = 30;
        var topbarME = function() {{ $('#uberbar').fadeTo(fadeSpeed,1); }}, topbarML = function() {{ $('#uberbar').fadeTo(fadeSpeed,fadeTo); }};
        var inside = false;
        //do
        $(window).scroll(function() {{
            position = $(window).scrollTop();
            if(position > topDistance && !inside) {{
                //add events
                topbarML();
                $('#uberbar').bind('mouseenter',topbarME);
                $('#uberbar').bind('mouseleave',topbarML);
                inside = true;
            }}
            else if (position < topDistance){{
                topbarME();
                $('#uberbar').unbind('mouseenter',topbarME);
                $('#uberbar').unbind('mouseleave',topbarML);
                inside = false;
            }}
        }});
        $('#content').css({{'margin-top': $('#uberbar').outerHeight(true)}});
        $('a.anchor').css({{'top': - $('#uberbar').outerHeight(true)}});
    }})();
}});
</script>

最后是HTML:

<div id="uberbar">
    <!--CONTENT OF FIXED HEADER-->
</div>
....
<div id="content">
    <!--MAIN CONTENT-->
    ....
    <a class="anchor" id="anchor1"></a>
    ....
    <a class="anchor" id="anchor2"></a>
    ....
</div>

也许这对喜欢#uberbar dixed header的人有用!


0

还可以使用以下属性添加锚点:

(text-indent:-99999px;)
visibility: hidden;
position:absolute;
top:-80px;    

并给父容器一个相对位置。

非常适合我。


0

如何使用可链接ID的隐藏跨距标记来提供导航栏的高度:

#head1 {{
  padding-top: 60px;
  height: 0px;
  visibility: hidden;
}}


<span class="head1">somecontent</span>
<h5 id="headline1">This Headline is not obscured</h5>

这里是fiddle: http://jsfiddle.net/N6f2f/7


0

我在每个h1元素之前添加了40px高度.vspace元素来固定锚点。

<div class="vspace" id="gherkin"></div>
<div class="page-header">
  <h1>Gherkin</h1>
</div>

在CSS中:

.vspace {{ height: 40px;}}

它工作得很好,空间也不拥挤。


0

除了Ziav的答案(with thanks to Alexander Savin)之外,我还需要使用旧的<a name="...">...</a>,因为我们在代码中使用<div id="...">...</div>是为了另一个目的。我在使用display: inline-block时遇到了一些显示问题--每个<p>元素的第一行都略微右缩进(on both Webkit and Firefox browsers)。我最终尝试了其他display值,display: table-caption对我来说非常适合。

.anchor {{
  padding-top: 60px;
  margin-top: -60px;
  display: table-caption;
}}

-1

以下是我们在网站上使用的解决方案。将headerHeight变量调整为您的页眉高度。将js-scroll类添加到应在单击时滚动的锚点。

// SCROLL ON CLICK
// ---------------------------------------------------------------------
$('.js-scroll').click(function(){{
    var headerHeight = 60;

    $('html, body').animate({{
        scrollTop: $( $.attr(this, 'href') ).offset().top - headerHeight;
    }}, 500);
    return false;
}});

-1

@AlexanderSavin's解决方案在我的WebKit浏览器中运行良好。

此外,我还必须使用:target伪类,该伪类将样式应用于选定的锚,以调整FF, Opera & IE9:中的填充

a:target {{
  padding-top: 40px
}}

Note that this style is not for Chrome / Safari so you'll probably have to use css-hacks, conditional comments etc.

另外,我想指出的是,亚历山大的解决方案之所以有效,是因为目标元素是inline。如果不需要链接,只需更改display属性即可:

<div id="myanchor" style="display: inline">
   <h1 style="padding-top: 40px; margin-top: -40px;">My anchor</h1>
</div>

-2

我遇到了同样的问题,最终手动处理了点击事件,比如:

$('#mynav a').click(() ->
  $('html, body').animate({{
      scrollTop: $($(this).attr('href')).offset().top - 40
  }}, 200
  return false
)

当然,滚动动画是可选的。


3
这个JavaScript甚至是无效的,我理解你试图传达的信息。但AT LEAST应具有有效的大括号和语法才能作为合法的答案。
gzimmers