简体   繁体   English

使锚链接在链接到的位置上方一些像素

[英]Make anchor link go some pixels above where it's linked to

I'm not sure the best way to ask/search for this question:我不确定询问/搜索这个问题的最佳方式:

When you click on an anchor link, it brings you to that section of the page with the linked-to area now at the VERY TOP of the page.当您单击锚链接时,它会将您带到页面的该部分,链接区域现在位于页面的顶部。 I would like the anchor link to send me to that part of the page, but I would like some space at the top.我希望锚链接将我发送到页面的那部分,但我希望顶部有一些空间。 As in, I don't want it to send me to the linked-to part with it at the VERY TOP, I would like 100 or so pixels of space there.就像,我不希望它把我发送到顶部的链接到部分,我希望那里有 100 个左右像素的空间。

Does this make sense?这有意义吗? Is this possible?这可能吗?

Edited to show code - it's just an anchor tag:编辑以显示代码 - 它只是一个锚标签:

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

This will allow the browser to do the work of jumping to the anchor for us and then we will use that position to offset from.这将允许浏览器为我们完成跳转到锚点的工作,然后我们将使用该位置进行偏移。

EDIT 1:编辑 1:

As was pointed out by @erb, this only works if you are on the page while the hash is changed.正如@erb 所指出的,这仅在更改哈希时您在页面上时才有效。 Entering the page with a #something already in the URL does not work with the above code.使用 URL 中已有的#something进入页面不适用于上述代码。 Here is another version to handle that:这是处理该问题的另一个版本:

// 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).

NOTE: To use jQuery, you could just replace window.addEventListener with $(window).on in the examples.注意:要使用 jQuery,您可以在示例$(window).on window.addEventListener替换为$(window).on Thanks @Neon.谢谢@霓虹灯。

EDIT 2:编辑2:

As pointed out by a few, the above will fail if you click on the same anchor link two or more times in a row because there is no hashchange event to force the offset.正如一些人指出的那样,如果您连续两次或多次单击同一个锚链接,上述操作将失败,因为没有hashchange事件来强制偏移。

This solution is very slightly modified version of the suggestion from @Mave and uses jQuery selectors for simplicity此解决方案是@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 for this example is here此示例的 JSFiddle在这里

Working only with css you can add a padding to the anchored element (as in a solution above) To avoid unnecessary whitespace you can add a negative margin of the same height:仅使用 css 您可以向锚定元素添加填充(如上面的解决方案)为了避免不必要的空白,您可以添加相同高度的负边距:

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

I am not sure if this is the best solution in any case, but it works fine for me.我不确定这是否是任何情况下的最佳解决方案,但对我来说效果很好。

Even better solution:更好的解决方案:

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

Just position the <a> tag with absolute positioning inside of a relatively positioned object.只需将<a>标签定位在相对定位对象内的绝对定位中。

Works when entering the page or through a hash change within page.在进入页面或通过页面内的哈希更改时有效。

Here's the 2020 answer for this:这是 2020 年的答案:

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

Because it's widely supported !因为它得到了广泛的支持

Best Solution最佳解决方案

<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>

This will work without jQuery and on page load.这将在没有 jQuery 和页面加载的情况下工作。

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

This should work:这应该有效:

    $(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;
    });
});

Just change the .top-49 to what fits with your anchor link.只需将 .top-49 更改为适合您的锚链接的内容即可。

To link to an element, and then 'position' that element an arbitrary distance from the top of the page, using pure CSS, you'd have to use padding-top , that way the element is still positioned at the top of the window, but it appears , visibly, to be positioned some distance from the top of the view-port, for example:要链接到一个元素,然后使用纯 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: 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 Fiddle demo . JS小提琴演示

To use a plain JavaScript approach:要使用纯 JavaScript 方法:

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

window.addEventListener('hashchange', addMargin);

JS Fiddle demo . JS小提琴演示

try this code, it has already a smooth animation when clicked the link.试试这个代码,点击链接时它已经有了流畅的动画。

$(document).on('click', 'a[href^="#"]', function (event) {
    event.preventDefault();

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

If you use explicit anchor names such as,如果您使用显式锚点名称,例如,

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

then in css you can simply set然后在 css 中你可以简单地设置

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

This will work as long as your HREF anchor tags don't also specify a NAME attribute只要您的 HREF 锚标记不指定 NAME 属性,这就会起作用

Eric's answer is great, but you really don't need that timeout.埃里克的回答很好,但你真的不需要超时。 If you're using jQuery, you can just wait for the page to load.如果您使用的是 jQuery,则只需等待页面加载即可。 So I'd suggest changing the code to:所以我建议将代码更改为:

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

This also gets us rid of that arbitrary factor.这也让我们摆脱了那个随意的因素。

I just found an easy solution for myself.我刚刚为自己找到了一个简单的解决方案。 Had an margin-top of 15px顶部边距为 15px

HTML HTML

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

CSS CSS

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

The easiest solution:最简单的解决方案:

CSS CSS

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

HTML 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>

A variant of Thomas' solution: CSS element>element selectors can be handy here: Thomas 解决方案的一个变体:CSS element>element selectors在这里很方便:

CSS CSS

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

HTML HTML

<a href="#myAnchor">Click Me!</a>

<span class="paddedAnchor"><a name="myAnchor"></a></span>

A click on the link will move the scroll position to 100px above wherever the element with a class of paddedAnchor is positioned.单击该链接会将滚动位置移动到 100 像素上方的 100 像素,该位置具有paddedAnchor类的元素。

Supported in non-IE browsers, and in IE from version 9. For support on IE 7 and 8, a <!DOCTYPE> must be declared.在非 IE 浏览器和 IE 版本 9 中支持。为了支持 IE 7 和 8,必须声明<!DOCTYPE>

Using only css and having no problems with covered and unclickable content before (the point of this is the pointer-events:none):仅使用 css 并且之前没有覆盖和不可点击的内容的问题(重点是指针事件:无):

CSS CSS

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

HTML 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>

Put this in style :把它放在样式中:

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

and use this class in separate div tag before the links, example:并在链接之前在单独的div标签中使用此类,例如:

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

or use this php code for echo link tag:或使用此 php 代码作为 echo 链接标签:

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

This pure CSS solution works for me.这个纯 CSS 解决方案对我有用。

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

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

I know this is a bit late, but I found something very important to put in your code if you are using Bootstrap's Scrollspy.我知道这有点晚了,但是如果您使用 Bootstrap 的 Scrollspy,我发现一些非常重要的东西要放入您的代码中。 ( http://getbootstrap.com/javascript/#scrollspy ) ( http://getbootstrap.com/javascript/#scrollspy )

This was driving me nuts for hours.这让我疯狂了好几个小时。

The offset for scroll spy MUST match the window.scrollY or else you'll run the risk of:滚动间谍的偏移量必须与 window.scrollY 匹配,否则您将面临以下风险:

  1. Getting a weird flicker effect when scrolling滚动时出现奇怪的闪烁效果
  2. Youll find that when you click on anchors, youll land in that section, but scroll spy will assume you are a section above it.你会发现当你点击锚点时,你会进入那个部分,但滚动间谍会假设你在它上面的一个部分。

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

Based on @Eric Olson solution just modify a little to include the anchor element that I want to go specifically基于@Eric Olson解决方案,只需稍微修改一下,就可以包含我想要特别去的锚元素

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

I just have the same problem.我只是有同样的问题。 I have a nav posited pixed and i want the angkor to start under the nav.我有一个像素化的导航,我希望吴哥从导航下开始。 The solution of window.addEventListener... not work for me because i set my page to be scroll-behavior:smooth so it set the offset instead scroll to the angkor. window.addEventListener...的解决方案对我不起作用,因为我将页面设置为scroll-behavior:smooth所以它设置偏移量而不是滚动到吴哥。 the setTimeout() work if the time is anough for scroll to the end but it still not looking good.如果时间足够滚动到最后,则setTimeout()工作,但它仍然看起来不太好。 so my solution was to add a posited absolute div in the angkor, with height:[the height of the nav] and bottom:100% .所以我的解决方案是在 angkor 中添加一个假定的绝对 div,其中height:[the height of the nav]bottom:100% in this case this div ended in the top of the angkor element, and start at the position where you what the angkor to scroll to.在这种情况下,这个 div 在 angkor 元素的顶部结束,并从你要滚动到的 angkor 位置开始。 now all what i do is set the angkor link to this absolute div and the wor done :)现在我所做的就是将 angkor 链接设置为这个绝对 div 并完成工作:)

 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>

i was facing the similar issue and i resolved by using following code我遇到了类似的问题,我使用以下代码解决了

$(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();
    });

I had this same issue, and there's a really quick and simple solution without CSS of JS.我有同样的问题,并且有一个非常快速和简单的解决方案,没有 JS 的 CSS。 Just create a separate unstyled div with an ID like " aboutMeAnchor and just place it well above the section you actually want to land on.只需创建一个单独的无样式 div,其 ID 类似于“ aboutMeAnchor ,并将其放置在您实际想要登陆的部分上方。

This is also a good solution.这也是一个很好的解决方案。 Make a div above the destination div like this and link the a to this div;使目标上方一个div div像这样和一个链接到这个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*/
}

I was trying to do something similar and what finally worked for me is to add the pseudo element ::before to the div you want to scroll to.我试图做一些类似的事情,最终对我有用的是将伪元素::before添加到要滚动到的 div 中。 This will add a blank space before the element and the anchor link will scroll to the top of this blank space.这将在元素之前添加一个空白区域,并且锚链接将滚动到该空白区域的顶部。 For example:例如:

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

I found a surprising solution to what I think is basically the same issue about the scroll-position of the target of anchor-links.对于我认为与锚链接目标的滚动位置基本相同的问题,我找到了一个令人惊讶的解决方案。

I have a page which displays a long document with sub-sections whose headers I mark by putting a bookmark dom-element right above them like this:我有一个页面,它显示一个带有子部分的长文档,我通过在它们正上方放置一个书签 dom 元素来标记其标题,如下所示:

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

The idea is that user can navigate into the document's sub-sections by clicking on links in a side-pane.这个想法是用户可以通过单击侧窗格中的链接导航到文档的子部分。 The first such link should scroll the window to the start of the page.第一个这样的链接应该将窗口滚动到页面的开头。 Note that the content of the bookmark-div above is empty meaning it should take no space from the page, and thus navigating to the first link should navigate to the beginning of the page.请注意,上面 bookmark-div 的内容是空的,这意味着它不应该占用页面空间,因此导航到第一个链接应该导航到页面的开头。

The problem was that clicking the first link scrolled the page so that the first section-header was immediately at the top of visible area with no whitespace above it.问题是单击第一个链接会滚动页面,因此第一个节标题立即位于可见区域的顶部,上方没有空格。 In other words the page was scrolled down a little from the top.换句话说,页面从顶部向下滚动了一点。 Whereas when the page was loaded or reloaded there is (and should be) a visible white-space margin above the first section-header.而当页面加载或重新加载时,第一个节标题上方有(并且应该)可见的空白边距。

I believe this is the same issue that the original question describes.我相信这与原始问题描述的问题相同。 It seemed there was no way to get the first link to scroll to the very beginning of the page.似乎没有办法让第一个链接滚动到页面的最开头。

Problem is that what you see when you load the page is different from what you see when you click the first link.问题是您加载页面时看到的内容与您单击第一个链接时看到的内容不同。 It doesn't look good when there is no longer a whitespace-margin above the first header, or alternately there would be too big a margin when you load or reload the page.当第一个标题上方不再有空白边距时,它看起来不太好,或者加载或重新加载页面时边距太大。

The way I got it to work is this CSS:我让它工作的方式是这个 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;
}

All of the above was needed to get it to work except the first border-definition which I left as an example of what does NOT work.除了第一个边界定义之外,我将其作为不起作用的示例留下了上述所有内容才能使其正常工作。 The 2nd border-definition of course overrides the first and thus takes effect.第二个边界定义当然会覆盖第一个并因此生效。

Why "border:solid 0.01px;"为什么“边框:实心 0.01px;” works but "border:solid 0px;"有效,但“边框:实心 0px;” does not I don't understand.我不明白。 There should not be a big difference between 0 an 0.01 should there? 0 和 0.01 之间不应该有很大的区别吗? This solution works both on Chrome and Firefox and stops working on both if I use "border:solid 0px;".此解决方案适用于 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM