修复了页眉与页内锚点重叠的问题

发布于 2024-09-30 02:31:09 字数 922 浏览 4 评论 0原文

如果我在 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    |
| ...                             |      | ...                             |
+---------------------------------+      +---------------------------------+

If I have a non-scrolling header in an HTML page, fixed to the top, having a defined height:

Is there a way to use the URL anchor (the #fragment part) to have the browser scroll to a certain point in the page, but still respect the height of the fixed element without the help of 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    |
| ...                             |      | ...                             |
+---------------------------------+      +---------------------------------+

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

自演自醉 2024-10-07 02:31:09

如果您不能或不想设置新类,请添加固定高度 ::before 伪元素到 :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);

If you can’t or don’t want to set a new class, add a fixed-height ::before pseudo-element to the :target pseudo-class in CSS:

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

Or scroll the page relative to :target with jQuery:

var offset = $(':target').offset();
var scrollto = offset.top - 60; // minus fixed header height
$('html, body').animate({scrollTop:scrollto}, 0);
终难遇 2024-10-07 02:31:09
html {
  scroll-padding-top: 70px; /* height of sticky header */
}

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

html {
  scroll-padding-top: 70px; /* height of sticky header */
}

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

猫性小仙女 2024-10-07 02:31:09

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

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

我使用了这个CSS:

.anchor { padding-top: 90px; }

I had the same problem.
I solved it by adding a class to the anchor element with the topbar height as the padding-top value.

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

I used this CSS:

.anchor { padding-top: 90px; }
烟酒忠诚 2024-10-07 02:31:09

我使用这种方法:

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

.jumptarget::before {
  content:"";
  display:block;
  height:50px; /* fixed header height*/
  margin:-50px 0 0; /* negative fixed header height */
}

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

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

I use this approach:

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

.jumptarget::before {
  content:"";
  display:block;
  height:50px; /* fixed header height*/
  margin:-50px 0 0; /* negative fixed header height */
}

It adds an invisible element before each target. It works IE8+.

Here are more solutions:
http://nicolasgallagher.com/jump-links-and-viewport-positioning/

孤星 2024-10-07 02:31:09

从 4/2021 开始,有一个非 hacky 且完全跨浏览器的解决方案:

h1 {
  scroll-margin-top: 50px
}

它是 CSS 滚动捕捉规范。在所有现代浏览器上运行。 (有关更多上下文,请参阅有关 的 MDN 页面滚动边距顶部滚动填充顶部

From 4/2021 there is single non-hacky and fully cross-browser solution:

h1 {
  scroll-margin-top: 50px
}

It is part of CSS Scroll Snap spec. Runs on all modern browsers. (For more context, see the MDN pages about scroll-margin-top, scroll-padding-top)

清欢 2024-10-07 02:31:09

官方 Bootstrap 采用的答案:

*[id]:before { 
  display: block; 
  content: " "; 
  margin-top: -75px; // Set the Appropriate Height
  height: 75px; // Set the Appropriate Height
  visibility: hidden; 
}

积分

合并

Official Bootstrap Adopted Answer:

*[id]:before { 
  display: block; 
  content: " "; 
  margin-top: -75px; // Set the Appropriate Height
  height: 75px; // Set the Appropriate Height
  visibility: hidden; 
}

Credits

Merge

耳根太软 2024-10-07 02:31:09

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

div:target {
  padding-top: 65px; 
  margin-top: -65px;
}

如果您不喜欢使用 target 选择器,您也可以这样做:

.my-target {
    padding-top: 65px;
    margin-top: -65px;
}

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

<div style="background-color:red;height:100px;"></div>
<div class="my-target" style="background-color:green;height:100px;"></div>

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

The best way that I found to handle this issue is (replace 65px with your fixed element height):

div:target {
  padding-top: 65px; 
  margin-top: -65px;
}

If you do not like to use the target selector you can also do it in this way:

.my-target {
    padding-top: 65px;
    margin-top: -65px;
}

Note: this example will not work if the target element have a backgound color that differant from his parent.
for example:

<div style="background-color:red;height:100px;"></div>
<div class="my-target" style="background-color:green;height:100px;"></div>

in this case the green color of my-target element will overwrite his parent red element in 65px.
I did not find any pure CSS solution to handle this issue but if you do not have another background color this solution is the best.

黎夕旧梦 2024-10-07 02:31:09

虽然一些建议的解决方案适用于同一页面内的片段链接(=哈希链接)(例如向下滚动的菜单链接),但我发现当您想要时,它们都无法在当前的 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);
    }
}

摘要

如果没有 JS 延迟解决方案,可能可以在 Firefox、IE、Safari 中运行,但不能在 Chrome 中运行。

While some of the proposed solutions work for fragment links (= hash links) within the same page (like a menu link that scrolls down), I found that none of them worked in current Chrome when you want to use fragment links coming in from other pages.

So calling www.mydomain.com/page.html#foo from scratch will NOT offset your target in current Chrome with any of the given CSS solutions or JS solutions.

There is also a jQuery bug report describing some details of the problem.

SOLUTION

The only option I found so far that really works in Chrome is JavaScript that is not called onDomReady but with a delay.

// 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);
    }
}

SUMMARY

Without a JS delay solutions will probably work in Firefox, IE, Safari, but not in Chrome.

我乃一代侩神 2024-10-07 02:31:09

您现在可以使用 scroll-margin-top相当广泛采用

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

.element {
  scroll-margin-top: 2em;
}

You can now use scroll-margin-top, which is pretty widely adopted.

Simply add the following CSS to the element you want to scroll to:

.element {
  scroll-margin-top: 2em;
}
书信已泛黄 2024-10-07 02:31:09

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

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

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

#anchor-one{padding-top: 60px;}

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

I've got it working easily with CSS and HTML, using the "anchor:before" method mentioned above. I think it works the best, because it doesn't create massive padding between your divs.

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

It doesn't seem to work for the first div on the page, but you can counter that by adding padding to that first div.

#anchor-one{padding-top: 60px;}

Here's a working fiddle: http://jsfiddle.net/FRpHE/24/

你对谁都笑 2024-10-07 02:31:09

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

a[name] {
    display: block;
    padding-top: 90px;
    margin-top: -90px;
}

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

For Chrome/Safari/Firefox you could add a display: block and use a negative margin to compensate the offset, like:

a[name] {
    display: block;
    padding-top: 90px;
    margin-top: -90px;
}

See example http://codepen.io/swed/pen/RrZBJo

墨洒年华 2024-10-07 02:31:09

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

:target { margin-top: -100px;顶部内边距:100px; }

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

I didn't see the option to simply use :target listed as an option. I've found that

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

appears to work in the provided scenario. :target is also compatible with all modern browsers. https://caniuse.com/?search=%3Atarget

捂风挽笑 2024-10-07 02:31:09

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

html {
  scroll-padding-top: 80px; /* height of your sticky header */
}

发现于此网站

Just discovered another pure CSS solution that worked like a charme for me!

html {
  scroll-padding-top: 80px; /* height of your sticky header */
}

Found on this site!

江湖正好 2024-10-07 02:31:09

您可以尝试以下操作:

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

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

<h1 id="bar">Bar</h1>

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

You could try this:

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

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

<h1 id="bar">Bar</h1>

Set the top padding value to the actual height of your header. This will introduce a slight extra gap at the top of your header, but it will only be visible when the user jumps to the anchor and then scrolls up. I've made up that solution for my site right now, but it only shows a small fixed bar at the top of the page, nothing too high.

墟烟 2024-10-07 02:31:09

您可以使用 jQuery 来做到这一点:

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

You can do this with jQuery:

var offset = $('.target').offset();
var scrollto = offset.top - 50; // fixed_top_bar_height = 50px
$('html, body').animate({scrollTop:scrollto}, 0);
烟花肆意 2024-10-07 02:31:09

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

在您想要设置锚点的地方创建一个空白区域。

<span class="anchor" id="section1"></span>
<div class="section"></div>

并应用以下类:

.anchor {
  display: block;
  height: 115px;       /* same height as header */
  margin-top: -115px;  /* same height as header */
  visibility: hidden;
}

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

I wasn't having any luck with the answer listed above and ended up using this solution which worked perfectly...

Create a blank span where you want to set your anchor.

<span class="anchor" id="section1"></span>
<div class="section"></div>

And apply the following class:

.anchor {
  display: block;
  height: 115px;       /* same height as header */
  margin-top: -115px;  /* same height as header */
  visibility: hidden;
}

This solution will work even if the sections have different colored backgrounds! I found the solution at this link.

剧终人散尽 2024-10-07 02:31:09

它对我有用:

HTML 链接到锚点:

<a href="#security">SECURITY</a>

HTML 锚点:

<a name="security" class="anchor"></a>

CSS :

.anchor::before {
    content: "";
    display: block;
    margin-top: -50px;
    position: absolute;
}

It works for me:

HTML LINK to Anchor:

<a href="#security">SECURITY</a>

HTML Anchor:

<a name="security" class="anchor"></a>

CSS :

.anchor::before {
    content: "";
    display: block;
    margin-top: -50px;
    position: absolute;
}
所谓喜欢 2024-10-07 02:31:09

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

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

  1. CSS:

    <前><代码>.书签{
    顶部边距:-120px;
    底部填充:120px;
    显示:块;
    }

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

  1. 书签链接 HTML:

    您的常见问题解答是什么?
    
  2. 添加书签的内容 HTML:

    ;
    

    您的常见问题解答是什么?

    一些常见问题解答文本,后跟...

    ...更多常见问题解答文本等...

此解决方案的好处是 span 元素不仅是隐藏的,而且本质上是折叠的,不会填充您的内容。

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

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

I had a lot of trouble with many of the answers here and elsewhere as my bookmarked anchors were section headers in an FAQ page, so offsetting the header didn't help as the rest of the content would just stay where it was. So I thought I'd post.

What I ended up doing was a composite of a few solutions:

  1. The CSS:

    .bookmark {
        margin-top:-120px;
        padding-bottom:120px; 
        display:block;
    }
    

Where "120px" is your fixed header height (maybe plus some margin).

  1. The bookmark link HTML:

    <a href="#01">What is your FAQ question again?</a>
    
  2. The bookmarked content 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>
    

The good thing about this solution is that the span element is not only hidden, it is essentially collapsed and doesn't pad out your content.

I can't take much credit for this solution as it comes from a swag of different resources, but it worked best for me in my situation.

You can see the actual result here.

摘星┃星的人 2024-10-07 02:31:09

我使用锚元素的scroll-margin-top属性解决了我的问题

scroll-margin-top: 100px;

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

I solve my issue with scroll-margin-top property for the anchor element

scroll-margin-top: 100px;

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

凡间太子 2024-10-07 02:31:09

对于我的纯粹主义者来说,这感觉有点老套,但作为纯 css 解决方案,您可以使用 :target 选择器向活动锚定元素添加填充:

html, body {height:100%; min-height:100%; margin:0;}
body {min-height:200%;}
header {display:inline-block; position:fixed; font-size:1.5em; height:100px; top:0; left:0; right:0; line-height:100px; background:black; text-align:center;}
header a {color:#fff;}
section {padding:30px; margin:20px;}
section:first-of-type, section:target {padding-top:130px;}
<header><a href="#one">#One</a> <a href="#two">#two</a> <a href="#three">#three</a></header>
<section id="one"><h1>One</h1>Aenean lacinia bibendum nulla sed consectetur. Nullam id dolor id nibh ultricies vehicula ut id elit. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.</section>
<section id="two"><h1>Two</h1>Aenean lacinia bibendum nulla sed consectetur. Nullam id dolor id nibh ultricies vehicula ut id elit. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.</section>
<section id="three"><h1>Three</h1>Aenean lacinia bibendum nulla sed consectetur. Nullam id dolor id nibh ultricies vehicula ut id elit. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.</section>

It feels somewhat hacky to my purist mind but as a css-only solution you can add padding to the active anchored element using the :target selector:

html, body {height:100%; min-height:100%; margin:0;}
body {min-height:200%;}
header {display:inline-block; position:fixed; font-size:1.5em; height:100px; top:0; left:0; right:0; line-height:100px; background:black; text-align:center;}
header a {color:#fff;}
section {padding:30px; margin:20px;}
section:first-of-type, section:target {padding-top:130px;}
<header><a href="#one">#One</a> <a href="#two">#two</a> <a href="#three">#three</a></header>
<section id="one"><h1>One</h1>Aenean lacinia bibendum nulla sed consectetur. Nullam id dolor id nibh ultricies vehicula ut id elit. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.</section>
<section id="two"><h1>Two</h1>Aenean lacinia bibendum nulla sed consectetur. Nullam id dolor id nibh ultricies vehicula ut id elit. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.</section>
<section id="three"><h1>Three</h1>Aenean lacinia bibendum nulla sed consectetur. Nullam id dolor id nibh ultricies vehicula ut id elit. Integer posuere erat a ante venenatis dapibus posuere velit aliquet.</section>

z祗昰~ 2024-10-07 02:31:09

我正在使用 @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();
      }
  };

I'm using @Jpsy's answer, but for performance reasons I'm only setting the timer if the hash is present in the 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();
      }
  };
白龙吟 2024-10-07 02:31:09

通过添加 scroll-padding-top 属性来解决这个问题的简单方法,只需将此代码添加到您的 CSS 文件中即可看到神奇效果。

对于动态高度和间隙变量

html {   
    --headerHeight:79px;   
    --gap:40px;   
    scroll-padding-top: calc(var(--headerHeight) + var(--gap)); 
}

对于固定间隙值

html { 
    scroll-padding-top: 120px; 
}

Simple and easy way by adding scroll-padding-top property to solve this problem, just add this code into your CSS file and see the magic.

for dynamic height and gap variables

html {   
    --headerHeight:79px;   
    --gap:40px;   
    scroll-padding-top: calc(var(--headerHeight) + var(--gap)); 
}

for fixed gap value

html { 
    scroll-padding-top: 120px; 
}
娇柔作态 2024-10-07 02:31:09

我发现我必须同时使用 两者 MutttenXdBadabam 的 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>
...

I found I had to use both MutttenXd's and Badabam's CSS solutions together, as the first did not work in Chrome and the second did not work in 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>
...
欢你一世 2024-10-07 02:31:09

我发现最干净的方式是以下一种:

  #bar::before {
    display: block;
    content: " ";
    margin-top: -150px;
    height: 150px;
    visibility: hidden;
    pointer-events: none;
  }

The way that I find being the cleanest is the following one :

  #bar::before {
    display: block;
    content: " ";
    margin-top: -150px;
    height: 150px;
    visibility: hidden;
    pointer-events: none;
  }
揪着可爱 2024-10-07 02:31:09

使用 jQuery 的侵入性最小的方法:

链接:

<a href="#my-anchor-1" class="anchor-link">Go To Anchor 1</a>

内容:

<h3 id="my-anchor-1">Here is Anchor 1</a>

脚本:

$(".anchor-link").click(function() {
    var headerHeight = 120;
    $('html, body').stop(true, true).animate({
        scrollTop: $(this.hash).offset().top - headerHeight
    }, 750);
    return false;
});

通过将锚链接类分配给链接,其他链接(如折叠式或选项卡控件)的行为不会受到影响。

这个问题不需要javascript,但另一个更受欢迎的问题 由于这个问题而关闭,我无法在那里回答。

A minimally intrusive approach using jQuery:

Link:

<a href="#my-anchor-1" class="anchor-link">Go To Anchor 1</a>

Content:

<h3 id="my-anchor-1">Here is Anchor 1</a>

Script:

$(".anchor-link").click(function() {
    var headerHeight = 120;
    $('html, body').stop(true, true).animate({
        scrollTop: $(this.hash).offset().top - headerHeight
    }, 750);
    return false;
});

By assigning the anchor-link class to the links, the behaviour of other links (like accordion or tab controls) are not affected.

The question doesn't want javascript but the other more popular question is closed because of this one and I couldn't answer there.

万水千山粽是情ミ 2024-10-07 02:31:09

我需要一些适用于入站链接、页面上的链接的东西,并且可以通过 JS 定位,以便页面可以响应标题高度的变化

HTML

<ul>
  <li><a href="#ft_who">Who?</a></li>
  <li><a href="#ft_what">What?</a></li>
  <li><a href="#ft_when">When?</a></li>
</ul>
...
<h2 id="ft_who" class="fragment-target">Who?</h2> 
...
<a href="#">Can I be clicked?</a>
<h2 id="ft_what" class="fragment-target">What?</h2>
...
<h2 id="ft_when" class="fragment-target">When?</h2> 

CSS

.fragment-target {
    display: block;
    margin-top: -HEADER_HEIGHTpx;
    padding-top: HEADER_HEIGHTpx;
    z-index: -1;
}

z-index: -1 允许链接片段目标上方的“填充区域”仍然可点击,正如 @MuttenXd 在他的回答中评论的那样,

我还没有在 IE 11、Edge 15+、Chrome 38+、FF 52+ 或 Safari 9.1 中发现问题+

I needed something that works for inbound links, links on page, AND that can be targeted by JS so the page can respond to changes in the header height

HTML

<ul>
  <li><a href="#ft_who">Who?</a></li>
  <li><a href="#ft_what">What?</a></li>
  <li><a href="#ft_when">When?</a></li>
</ul>
...
<h2 id="ft_who" class="fragment-target">Who?</h2> 
...
<a href="#">Can I be clicked?</a>
<h2 id="ft_what" class="fragment-target">What?</h2>
...
<h2 id="ft_when" class="fragment-target">When?</h2> 

CSS

.fragment-target {
    display: block;
    margin-top: -HEADER_HEIGHTpx;
    padding-top: HEADER_HEIGHTpx;
    z-index: -1;
}

The z-index: -1 allows links in the 'padding area' above a fragment-target to still be clickable, as commented by @MuttenXd on his answer

I haven't found an issue yet in IE 11, Edge 15+, Chrome 38+, FF 52+, or Safari 9.1+

自控 2024-10-07 02:31:09
<div style="position:relative; top:-45px;">
    <a name="fragment"> </a>
</div>

这段代码应该可以解决问题。将 45px 替换为标题栏的高度。

编辑:如果使用 jQuery 是一个选项,我也成功使用 jQuery.localScroll 并设置了偏移值。 offset 选项是 jQuery.scrollTo 的一部分,jQuery.localScroll 是基于它构建的。此处提供演示:http://demos.flesler.com/jquery/scrollTo/ (第二个窗口,在“偏移”下)

<div style="position:relative; top:-45px;">
    <a name="fragment"> </a>
</div>

This code should do the trick. Swap out 45px for the height of your header bar.

EDIT: If using jQuery is an option, I've also been successful using jQuery.localScroll with an offset value set. The offset option is a part of jQuery.scrollTo, which jQuery.localScroll is built upon. A demo is available here: http://demos.flesler.com/jquery/scrollTo/ (second window, under 'offset')

塔塔猫 2024-10-07 02:31:09

这是一个适用于 IE 的完整 jquery 解决方案:

假设导航栏元素是这样的:

<ul>
    <li><a class="navigation" href="/#contact-us">Contact us</a></li>
    <li><a class="navigation" href="/#about-us">About us</a></li>
</ul>

您可以使用以下 jquery 片段来偏移滚动:

$(function() {
    $("a.navigation").click(function(event) {
        event.preventDefault();
        offSetScroll($(this));
    });
    offSetScrollFromLocation(window.location.href.toLowerCase());
});

function offSetScroll(anchor) {
    var href = anchor.attr("href");
    offSetScrollFromLocation(href);
}

function offSetScrollFromLocation(href) {
    //Change this according to the height of the navigation bar
    var fromTop = 250;
    if(href.indexOf("#")<=0)
        return;
    var hash=href.substring(href.indexOf("#"));
    var targetOffset = $(hash).offset().top-fromTop;
    $('html, body').animate({scrollTop: targetOffset}, 400, function(e) {

    });
}

Here is a complete jquery solution that will work in IE:

Suppose the navigation bar elements are something like this:

<ul>
    <li><a class="navigation" href="/#contact-us">Contact us</a></li>
    <li><a class="navigation" href="/#about-us">About us</a></li>
</ul>

You can use the following jquery snippet to offset the scroll:

$(function() {
    $("a.navigation").click(function(event) {
        event.preventDefault();
        offSetScroll($(this));
    });
    offSetScrollFromLocation(window.location.href.toLowerCase());
});

function offSetScroll(anchor) {
    var href = anchor.attr("href");
    offSetScrollFromLocation(href);
}

function offSetScrollFromLocation(href) {
    //Change this according to the height of the navigation bar
    var fromTop = 250;
    if(href.indexOf("#")<=0)
        return;
    var hash=href.substring(href.indexOf("#"));
    var targetOffset = $(hash).offset().top-fromTop;
    $('html, body').animate({scrollTop: targetOffset}, 400, function(e) {

    });
}
江城子 2024-10-07 02:31:09

使用 :before 实现效果很好,直到我们意识到伪元素实际上覆盖并阻止了位于伪元素区域内的指针事件。在 :before 上使用诸如 pointer-events: none 之类的东西,甚至直接在锚点上使用也没有任何影响。

我们最终做的是使锚点的定位绝对,然后将其位置调整为固定区域的偏移/高度。

在不阻止指针事件的情况下进行偏移锚点

.section-marker {

    position: absolute;
    top: -300px;
}

这样做的价值在于,我们不会阻止任何可能落入这 300 像素范围内的元素。缺点是从 Javascript 获取该元素的位置需要考虑该偏移量,因此必须调整其中的任何逻辑。

Implemented using :before worked great until we realized that the pseudo element was actually covering and blocking pointer events that sat within the pseudo element's area. Using something like pointer-events: none on the :before or even directly on the anchor had no affect.

What we ended up doing was making the anchor's positioning absolute and then adjusting it's position to be the offset/height of the fixed area.

Offset Anchor without Blocking Pointer Events

.section-marker {

    position: absolute;
    top: -300px;
}

The value with this is that we're not blocking any elements that might fall within those 300px. The downside is that grabbing that element's position from Javascript needs to take into account that offset so any logic there had to be adjusted.

錯遇了你 2024-10-07 02:31:09

这就是当您单击导航时我最终到达正确位置的方法。我添加了一个用于导航点击的事件处理程序。然后你可以使用“scrollBy”来向上移动偏移量。

var offset = 90;

 $('.navbar li a').click(function(event) {
    event.preventDefault();
    $($(this).attr('href'))[0].scrollIntoView();
    scrollBy(0, -offset);
 });

This is how I got it to finally go to the proper place when you click on the navigation. I added an event handler for the navigation clicks. Then you can just use "scrollBy" to move up on the offset.

var offset = 90;

 $('.navbar li a').click(function(event) {
    event.preventDefault();
    $($(this).attr('href'))[0].scrollIntoView();
    scrollBy(0, -offset);
 });
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文