使锚链接比其链接到的位置高出一些像素



我不确定询问/搜索此问题的最佳方式:

当您单击锚链接时,它会将您带到页面的该部分,链接区域现在位于页面的最顶部。我希望锚链接将我带到页面的该部分,但我希望在顶部留出一些空间。就像在,我不希望它把我送到最顶部的链接部分,我想要那里有 100 像素左右的空间。

这有意义吗?这可能吗?

编辑以显示代码 - 它只是一个锚标签:

<a href="#anchor">Click me!</a>
<p id="anchor">I should be 100px below where I currently am!</p>
window.addEventListener("hashchange", function () {
    window.scrollTo(window.scrollX, window.scrollY - 100);
});

这将允许浏览器为我们完成跳转到锚点的工作,然后我们将使用该位置进行偏移。

编辑 1:

正如@erb所指出的,这仅在更改哈希时您在页面上时才有效。使用URL中已有#something进入页面不适用于上述代码。这是处理该问题的另一个版本:

// The function actually applying the offset
function offsetAnchor() {
    if(location.hash.length !== 0) {
        window.scrollTo(window.scrollX, window.scrollY - 100);
    }
}
// This will capture hash changes while on the page
window.addEventListener("hashchange", offsetAnchor);
// This is here so that when you enter the page with a hash,
// it can provide the offset in that case too. Having a timeout
// seems necessary to allow the browser to jump to the anchor first.
window.setTimeout(offsetAnchor, 1); // The delay of 1 is arbitrary and may not always work right (although it did in my testing).

注意:要使用jQuery,您可以在示例中将window.addEventListener替换为$(window).on。谢谢@Neon。

编辑2:

正如一些人所指出的,如果您连续两次或多次单击同一锚链接,上述操作将失败,因为没有hashchange事件来强制偏移。

此解决方案是对@Mave建议的略微修改版本,并且使用jQuery选择器以简化

// The function actually applying the offset
function offsetAnchor() {
  if (location.hash.length !== 0) {
    window.scrollTo(window.scrollX, window.scrollY - 100);
  }
}
// Captures click events of all <a> elements with href starting with #
$(document).on('click', 'a[href^="#"]', function(event) {
  // Click events are captured before hashchanges. Timeout
  // causes offsetAnchor to be called after the page jump.
  window.setTimeout(function() {
    offsetAnchor();
  }, 0);
});
// Set the offset when entering page with hash present in the url
window.setTimeout(offsetAnchor, 0);

此示例的 JSFiddle 在这里

这是 2020 年的答案:

#anchor {
  scroll-margin-top: 100px;
}

因为它得到了广泛的支持!

仅使用 css,您可以向锚定元素添加填充(如上面的解决方案(为避免不必要的空格,您可以添加相同高度的负边距:

#anchor {
    padding-top: 50px;
    margin-top: -50px;
}

我不确定这是否是最好的解决方案,但它对我来说效果很好。

更好的解决方案:

<p style="position:relative;">
    <a name="anchor" style="position:absolute; top:-100px;"></a>
    I should be 100px below where I currently am!
</p>

只需将具有绝对定位的<a>标签放置在相对定位的对象内即可。

在进入页面或通过页面内的哈希更改时工作。

这将在没有jQuery和页面加载的情况下工作。

(function() {
    if (document.location.hash) {
        setTimeout(function() {
            window.scrollTo(window.scrollX, window.scrollY - 100);
        }, 10);
    }
})();

最佳解决方案

<span class="anchor" id="section1"></span>
<div class="section"></div>
<span class="anchor" id="section2"></span>
<div class="section"></div>
<span class="anchor" id="section3"></span>
<div class="section"></div>
<style>
.anchor{
  display: block;
  height: 115px; /*same height as header*/
  margin-top: -115px; /*same height as header*/
  visibility: hidden;
}
</style>

这个纯粹的CSS解决方案对我有用。

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

我在这里找到了它 -> https://www.wikitechy.com/tutorials/javascript/offsetting-an-html-anchor-to-adjust-for-fixed-header

这是一个小提琴:https://jsfiddle.net/e8o2p3az/

试试这段代码,点击链接时它已经有流畅的动画了。

$(document).on('click', 'a[href^="#"]', function (event) {
    event.preventDefault();
    $('html, body').animate({
        scrollTop: $($.attr(this, 'href')).offset().top - 100
    }, 500);
});

要链接到一个元素,然后使用纯CSS将该元素"定位"到页面顶部的任意距离,您必须使用padding-top ,这样元素仍然位于窗口顶部,但它似乎明显地位于距视口顶部一定距离的位置, 例如:

<a href="#link1">Link one</a>
<a href="#link2">Link two</a>
<div id="link1">
    The first.
</div>
<div id="link2">
    The second.
</div>

.CSS:

div {
    /* just to force height, and window-scrolling to get to the elements.
       Irrelevant to the demo, really */
    margin-top: 1000px;
    height: 1000px;
}
#link2 {
    /* places the contents of the element 100px from the top of the view-port */
    padding-top: 100px;
}

JS小提琴演示。

要使用普通的 JavaScript 方法:

function addMargin() {
    window.scrollTo(0, window.pageYOffset - 100);
}
window.addEventListener('hashchange', addMargin);

JS小提琴演示。

这应该有效:

    $(document).ready(function () {
    $('a').on('click', function (e) {
        // e.preventDefault();
        var target = this.hash,
            $target = $(target);
       $('html, body').stop().animate({
        'scrollTop': $target.offset().top-49
    }, 900, 'swing', function () {
    });
        console.log(window.location);
        return false;
    });
});

只需将 .top-49 更改为适合您的锚链接即可。

如果使用显式定位点名称,例如,

<a name="sectionLink"></a>
<h1>Section<h1>

然后在 CSS 中您可以简单地设置

A[name] {
    padding-top:100px;
}

只要 HREF 锚标记未同时指定 NAME 属性,这将起作用

Eric 的回答很棒,但你真的不需要那个超时。如果你使用的是jQuery,你可以等待页面加载。所以我建议将代码更改为:

// The function actually applying the offset
function offsetAnchor() {
    if (location.hash.length !== 0) {
        window.scrollTo(window.scrollX, window.scrollY - 100);
    }
}
// This will capture hash changes while on the page
$(window).on("hashchange", function () {
    offsetAnchor();
});
// Let the page finish loading.
$(document).ready(function() {
    offsetAnchor();
});

这也让我们摆脱了这种任意因素。

我只是为自己找到了一个简单的解决方案。边距顶部为 15px

.HTML

<h2 id="Anchor">Anchor</h2>

.CSS

h2{margin-top:-60px; padding-top:75px;}

最简单的解决方案:

.CSS

#link {
    top:-120px; /* -(some pixels above) */
    position:relative;
    z-index:5;
}

.HTML

<body>
    <a href="#link">Link</a>
    <div>
        <div id="link"></div> /*this div should placed inside a target div in the page*/
        text
        text
        text
    <div>
</body>

Thomas解决方案的一个变体:CSS元素>元素选择器在这里很方便:

.CSS

.paddedAnchor{
  position: relative;
}
.paddedAnchor > a{
  position: absolute;
  top: -100px;
}

.HTML

<a href="#myAnchor">Click Me!</a>
<span class="paddedAnchor"><a name="myAnchor"></a></span>

单击链接会将滚动位置移动到上方 100px,无论具有 paddedAnchor 类的元素所在的位置。

在非 IE 浏览器和版本 9 的 IE 中受支持。要获得对 IE 7 和 8 的支持,必须声明<!DOCTYPE>

仅使用 css,并且之前对覆盖和不可点击的内容没有问题(重点是指针事件:无(:

.CSS

.anchored::before {
    content: '';
    display: block;
    position: relative;
    width: 0;
    height: 100px;
    margin-top: -100px;
}

.HTML

<a href="#anchor">Click me!</a>
<div style="pointer-events:none;">
<p id="anchor" class="anchored">I should be 100px below where I currently am!</p>
</div>

把它放在风格上:

.hash_link_tag{margin-top: -50px; position: absolute;}

并在链接前的单独div标记中使用此类,例如:

<div class="hash_link_tag" id="link1"></div> 
<a href="#link1">Link1</a>

或使用此 PHP 代码作为回显链接标签:

function HashLinkTag($id)
{
    echo "<div id='$id' class='hash_link_tag'></div>";
}
我知道

这有点晚了,但是如果您使用的是Bootstrap的Scrollspy,我发现一些非常重要的东西可以放入您的代码中。(http://getbootstrap.com/javascript/#scrollspy(

这让我发疯了几个小时。

滚动间谍的偏移量必须与 window.scrollY 匹配,否则您将面临以下风险:

  1. 滚动时出现奇怪的闪烁效果
  2. 你会发现,当你点击锚点时,你会登陆该部分,但滚动间谍会假设你是它上面的一个部分。

 var body = $('body');
    body.scrollspy({
        'target': '#nav',
        'offset': 100 //this must match the window.scrollY below or you'll have a bad time mmkay
});
$(window).on("hashchange", function () {
        window.scrollTo(window.scrollX, window.scrollY - 100);
});

基于@Eric奥尔森解决方案,只需稍作修改即可包含我想专门使用的锚元素

// Function that actually set offset
function offsetAnchor(e) {
    // location.hash.length different to 0 to ignore empty anchor (domain.me/page#)
    if (location.hash.length !== 0) {
        // Get the Y position of the element you want to go and place an offset
        window.scrollTo(0, $(e.target.hash).position().top - 150);
    }
}
// Catch the event with a time out to perform the offset function properly
$(document).on('click', 'a[href^="#"]', function (e) {
    window.setTimeout(function () {
        // Send event to get the target id later
        offsetAnchor(e);
    }, 10);
});

我只是有同样的问题。我有一个像素化的导航,我希望吴哥在导航下开始。window.addEventListener...的解决方案对我不起作用,因为我将页面设置为scroll-behavior:smooth,因此它会设置偏移量而不是滚动到吴哥。如果时间是滚动到最后的时间,setTimeout()工作,但它仍然看起来不好。所以我的解决方案是在吴哥中添加一个假定的绝对div,带有 height:[the height of the nav]bottom:100% .在这种情况下,此div在吴哥元素的顶部结束,并从吴哥要滚动到的位置开始。现在我所做的只是将吴哥链接设置为这个绝对div 和 wor 完成:)

html,body{
    margin:0;
    padding:0;
    scroll-behavior:smooth;
}
nav {
    height:30px;
    width:100%;
    font-size:20pt;
    text-align:center;
    color:white;
    background-color:black;
    position:relative;
}
#my_nav{
    position:fixed;
    z-index:3;
}
#fixer_nav{
    position:static;
}
#angkor{
    position:absolute;
    bottom:100%;
    height:30px;
}
<nav id="my_nav"><a href="#angkor">fixed position nav<a/></nav>
<nav id="fixer_nav"></nav>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque nec lacus vel eros rutrum volutpat. Cras ultrices enim sit amet odio dictum, eget consectetur mi pellentesque. Sed mollis gravida nulla, eu euismod turpis efficitur id. Integer pretium posuere fringilla. Aenean laoreet, augue non pharetra elementum, lectus massa congue orci, a imperdiet neque enim ut dui. Praesent commodo orci bibendum leo suscipit viverra. Nunc fermentum semper eleifend. Pellentesque suscipit nulla aliquet, egestas lectus sed, egestas dui. Vivamus scelerisque maximus nibh, ac dignissim nunc tempor a. Praesent facilisis non lacus et aliquam. Proin ultricies lacus vitae nibh ullamcorper gravida. Proin elit arcu, convallis eget posuere quis, placerat id augue. Fusce ex risus, tempus nec orci vitae, feugiat faucibus quam. Integer risus metus, ornare et rhoncus vitae, accumsan a urna.
</p>
<nav><div id="angkor"></div>The angkor</nav>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque nec lacus vel eros rutrum volutpat. Cras ultrices enim sit amet odio dictum, eget consectetur mi pellentesque. Sed mollis gravida nulla, eu euismod turpis efficitur id. Integer pretium posuere fringilla. Aenean laoreet, augue non pharetra elementum, lectus massa congue orci, a imperdiet neque enim ut dui. Praesent commodo orci bibendum leo suscipit viverra. Nunc fermentum semper eleifend. Pellentesque suscipit nulla aliquet, egestas lectus sed, egestas dui. Vivamus scelerisque maximus nibh, ac dignissim nunc tempor a. Praesent facilisis non lacus et aliquam. Proin ultricies lacus vitae nibh ullamcorper gravida. Proin elit arcu, convallis eget posuere quis, placerat id augue. Fusce ex risus, tempus nec orci vitae, feugiat faucibus quam. Integer risus metus, ornare et rhoncus vitae, accumsan a urna.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque nec lacus vel eros rutrum volutpat. Cras ultrices enim sit amet odio dictum, eget consectetur mi pellentesque. Sed mollis gravida nulla, eu euismod turpis efficitur id. Integer pretium posuere fringilla. Aenean laoreet, augue non pharetra elementum, lectus massa congue orci, a imperdiet neque enim ut dui. Praesent commodo orci bibendum leo suscipit viverra. Nunc fermentum semper eleifend. Pellentesque suscipit nulla aliquet, egestas lectus sed, egestas dui. Vivamus scelerisque maximus nibh, ac dignissim nunc tempor a. Praesent facilisis non lacus et aliquam. Proin ultricies lacus vitae nibh ullamcorper gravida. Proin elit arcu, convallis eget posuere quis, placerat id augue. Fusce ex risus, tempus nec orci vitae, feugiat faucibus quam. Integer risus metus, ornare et rhoncus vitae, accumsan a urna.
</p>

我遇到了类似的问题,我使用以下代码解决了

$(document).on('click', 'a.page-scroll', function(event) {
        var $anchor = $(this);
        var desiredHeight = $(window).height() - 577;
        $('html, body').stop().animate({
            scrollTop: $($anchor.attr('href')).offset().top - desiredHeight
        }, 1500, 'easeInOutExpo');
        event.preventDefault();
    });

我遇到了同样的问题,并且有一个非常快速简单的解决方案,没有 CSS 的 JS。只需创建一个单独的无样式div,ID为" aboutMeAnchor,并将其放置在您实际想要登陆的部分上方。

这也是一个很好的解决方案。像这样在目标div上方创建一个div,并将 a 链接到这个div;

<div class="destination" id="link"></div> /**Needs to be above the destination**/
.destination {
    position:absolute;
    z-index:-1;
    left:0;
    margin-top:-100px;/* height of nav*/
}

试图做类似的事情,最终对我有用的是将伪元素::before添加到您要滚动到的div 中。这将在元素之前添加一个空格,锚链接将滚动到此空白区域的顶部。例如:

#anchor::before {
  content: "";
  display: block;
  height: 60px;
}

我找到了一个令人惊讶的解决方案,我认为基本上与锚链接目标的滚动位置问题相同。

有一个页面显示一个带有子部分的长文档,我通过在它们上方放置一个书签 dom-element 来标记其标题,如下所示:

<div class = "TB_BookMark"
        id = "someId"  
></div>
<h3 class="TB">Section 1</h3>

这个想法是用户可以通过单击侧窗格中的链接导航到文档的子部分。第一个这样的链接应将窗口滚动到页面的开头。请注意,上面的书签div 的内容是空的,这意味着它不应该占用页面的空间,因此导航到第一个链接应该导航到页面的开头。

问题是单击第一个链接会滚动页面,以便第一个部分标题立即位于可见区域的顶部,上面没有空格。换句话说,页面从顶部向下滚动了一点。而当页面被加载或重新加载时,第一个部分标题上方有(并且应该(一个可见的空白边距。

我相信这与原始问题描述的问题相同。似乎没有办法让第一个链接滚动到页面的开头。

问题是加载页面时看到的内容与单击第一个链接时看到的内容不同。当第一个标题上方不再有空格边距时,或者当您加载或重新加载页面时,它看起来不太好。

我让它工作的方式是这个 CSS:

.TB_Bookmark
{ border:solid 0px    Transparent;  /* Does NOT do what I want. */
  border:solid 0.01px Transparent;  /* Does what I want. */
}
h3.TB
{ margin-top:12px;
  margin-bottom:12px;
}
body
{ margin-top: 0px;
}
以上

所有内容都需要让它工作,除了第一个边界定义,我留下了它作为不起作用的示例。当然,第二个边界定义覆盖第一个边界定义,因此生效。

为什么"border:solid 0.01px;"有效,但"border:solid 0px;"不是我不明白。0 和 0.01 之间应该没有太大区别吗?此解决方案适用于Chrome和Firefox,如果我使用"border:solid 0px;",则在两者上都停止工作。

<a href="#anchor">Click me!</a>
<div style="margin-top: -100px; padding-top: 100px;" id="anchor"></div>
<p>I should be 100px below where I currently am!</p>

最新更新