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

是否有一种方法可以使用URL锚(#fragment部分)让浏览器滚动到页面中的某一点,但仍然尊重固定元素的高度,而不需要JavaScript的帮助?

http://example.com/#bar
WRONG (but the common behavior):         CORRECT:
+---------------------------------+      +---------------------------------+
| BAR///////////////////// header |      | //////////////////////// header |
+---------------------------------+      +---------------------------------+
| Here is the rest of the Text    |      | BAR                             |
| ...                             |      |                                 |
| ...                             |      | Here is the rest of the Text    |
| ...                             |      | ...                             |
+---------------------------------+      +---------------------------------+

当前回答

我发现我必须同时使用muttenxd和Badabam的CSS解决方案,因为第一个在Chrome中不起作用,第二个在Firefox中不起作用:

a.anchor { 
  padding-top: 90px;
}

a.anchor:before { 
  display: block;
  content: "";
  height: 90px;
  margin-top: -90px;
}

<a class="anchor" name="shipping"></a><h2>Shipping (United States)</h2>
...

其他回答

我使用@Jpsy的答案,但出于性能原因,我只在URL中存在散列时设置计时器。

$(function() {
      // Only set the timer if you have a hash
      if(window.location.hash) {
        setTimeout(delayedFragmentTargetOffset, 500);
      }
  });

function delayedFragmentTargetOffset(){
      var offset = $(':target').offset();
      if(offset){
          var scrollto = offset.top - 80; // minus fixed header height
          $('html, body').animate({scrollTop:scrollto}, 0);
          $(':target').highlight();
      }
  };
<div style="position:relative; top:-45px;">
    <a name="fragment"> </a>
</div>

这段代码应该可以达到目的。将标题栏的高度替换为45px。

编辑:如果使用jQuery是一个选项,我也成功地使用jQuery。带有偏移值设置的localScroll。偏移量选项是jQuery的一部分。scrollTo, jQuery。localScroll是在此基础上构建的。这里有一个演示:http://demos.flesler.com/jquery/scrollTo/(第二个窗口,在'offset'下)

虽然一些建议的解决方案适用于同一页面内的片段链接(=散列链接)(比如向下滚动的菜单链接),但我发现当你想使用来自其他页面的片段链接时,它们都不适用于当前的Chrome。

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

还有一个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);
    }
}

总结

没有JS的延迟解决方案可能在Firefox, IE, Safari中工作,但在Chrome中行不通。

如果你不能或不想设置一个新类,在CSS的:target伪类中添加一个固定高度的::

:target::before {
  content: "";
  display: block;
  height: 60px; /* fixed header height*/
  margin: -60px 0 0; /* negative fixed header height */
}

或者使用jQuery相对于:target滚动页面:

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

我也有同样的问题。 我通过向锚元素添加一个类来解决这个问题,并将topbar高度作为padding-top值。

<h1><a class="anchor" name="barlink">Bar</a></h1>

我使用这样的CSS:

.anchor { padding-top: 90px; }