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

有没有办法使用URL锚( #fragment 部分)将浏览器滚动到页面中的某个点,但仍然尊重固定元素的高度 没有JavaScript的帮助?

http://foo.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    |
| ...                             |      | ...                             |
+---------------------------------+      +---------------------------------+
有帮助吗?

解决方案

我有同样的问题。我通过将类添加到锚点高度为填充值的锚元件中来解决它。

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

然后只是CSS:

.anchor { padding-top: 90px; }

其他提示

如果您不能或不想设置新课程,请添加固定高度 ::before 伪元素 :target CSS中的伪级:

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

或滚动页面相对于 :target 与jQuery:

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

我使用这种方法:

/* 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-position/

官方引导通过了答案:

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

学分

合并

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

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

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

.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解决方案来处理此问题,但是如果您没有其他背景颜色,则该解决方案是最好的。

虽然一些提出的解决方案可用于片段链接(=哈希链接) 之内 同一页面(例如向下滚动的菜单链接),我发现当您要使用片段链接时,它们都没有在当前的chrome中起作用 来自其他页面.

因此,请致电www.mydomain.com/page.html#foo从头开始 不是 用任何给定的CSS解决方案或JS解决方案中的任何一个在当前的铬中抵消目标。

还有一个 jQuery错误报告 描述问题的一些细节。

解决方案

到目前为止,我发现真正在Chrome中真正起作用的唯一选择是JavaScript,该JavaScript并未在Domready上被称为延迟。

// 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(即Safari)中起作用,但不能在Chrome中使用。

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

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

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

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

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

您可以尝试一下:

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

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

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

将顶部填充值设置为标题的实际高度。这将在标题顶部引入一些额外的差距,但是只有当用户跳到锚点然后滚动时,才能看到它。我现在已经为我的网站弥补了该解决方案,但是它仅在页面顶部显示一个小的固定条,没有什么太高。

这个对我有用:

HTML链接到锚:

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

HTML锚:

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

CSS:

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

我可以使用上面提到的“锚点:”方法与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/

我正在使用 @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();
      }
  };
html {
  scroll-padding-top: 70px; /* height of sticky header */
}

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

对我的纯粹思想感觉有些骇人,但是作为仅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>

我发现我必须使用 两个都 mutttenxd'沙 BadabamCSS解决方案在一起,因为第一个没有在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>
...

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

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

我在这里和其他地方的许多答案都遇到了很多麻烦,因为我的书签锚是常见问题解答页面中的部分标题,因此抵消标题没有帮助,因为其余内容将留在原处。所以我以为我会发布。

我最终做的是一些解决方案的组合:

  1. CSS:

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

其中“ 120px”是您的固定标头高度(也许还有一些边距)。

  1. 书签链接html:

    <a href="#01">What is your FAQ question again?</a>
    
  2. 书签内容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>
    

这个解决方案的好处是 span 元素不仅被隐藏,而且本质上是崩溃的,并且不会消除您的内容。

我不能为此解决方案赢得太多功劳,因为它来自不同的资源,但在我的情况下它对我来说最有效。

您可以看到实际结果 这里.

作为 CSS滚动快照规格 进入游戏,很容易 scroll-margin-top 财产。目前在Chrome和Opera上运行(2019年4月)。另外,Safari 11+应该支持这一点,但是我无法在Safari 11上运行它。也许我们必须等待人们对其进行修复。

Codepen示例

body {
  padding: 0;
  margin: 0;
}

h1,
p {
  max-width: 40rem;
  margin-left: auto;
  margin-right: auto;
}
h1 {
  scroll-margin-top: 6rem; /* One line solution. :-) */
}
.header {
  position: sticky;
  top: 0;
  background-color: red;
  text-align: center;
  padding: 1rem;
}
.header .scroll {
  display: block;
  color: white;
  margin-bottom: 0.5rem;
}
.header .browsers {
  color: black;
  font-size: 0.8em;
}
<header class="header">
  <a class="scroll" href="#heading">Scroll to heading</a>
  <span class="browsers" >Chrome 69+, Opera 56+ and Safari 11+ only</span>
</header>
<p>
  Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
</p>
<h1 id="heading">What is Lorem Ipsum?</h1>
<p>
  Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
</p>
<p>
  

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent pulvinar eleifend dolor, in cursus augue interdum quis. Morbi volutpat pulvinar nisl et condimentum. Quisque elit lacus, egestas non ante sit amet, hendrerit commodo dui. Nunc ac sagittis dolor. Proin iaculis ante non est pharetra, et ullamcorper nisl accumsan. Aenean quis leo vel sapien eleifend aliquam. Pellentesque finibus dui ex, blandit tristique risus vestibulum vitae. Nam a quam ac turpis porta eleifend. Sed at hendrerit risus, ac efficitur ante. Aenean pretium justo feugiat condimentum consectetur. Etiam mattis urna id porta hendrerit.
</p>
<p>
Mauris venenatis quam sed egestas auctor. Fusce lacus eros, condimentum nec quam vel, malesuada gravida libero. Praesent vel sollicitudin justo. Donec mattis nisl id mauris scelerisque, quis placerat lectus scelerisque. Ut id justo a magna mattis luctus. Suspendisse massa est, pretium vel suscipit sit amet, iaculis at mi. Aenean vulputate ipsum non consectetur sodales. Proin aliquet erat nec mi eleifend, eu dapibus enim ultrices. Sed fringilla tortor ac rhoncus consectetur. Aliquam aliquam orci ultrices tortor bibendum facilisis.
</p>
<p>
Donec ultrices diam quam, non tincidunt purus scelerisque aliquam. Nam pretium interdum lacinia. Donec sit amet diam odio. Donec eleifend nibh ut arcu dictum, in vulputate magna malesuada. Nam id dignissim tortor. Suspendisse commodo, nunc sit amet blandit laoreet, turpis nibh rhoncus mi, et finibus nisi diam sed erat. Vivamus diam arcu, placerat in ultrices eu, porta ut tellus. Aliquam vel nisi nisi.
</p>
<p>
Integer ornare finibus sem, eget vulputate lacus ultrices ac. Vivamus aliquam arcu sit amet urna facilisis consectetur. Sed molestie dolor et tortor elementum, nec bibendum tortor cursus. Nulla ipsum nulla, luctus nec fringilla id, sagittis et sem. Etiam at dolor in libero pharetra consequat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Suspendisse quis turpis non diam mattis varius. Praesent at gravida mi. Etiam suscipit blandit dolor, nec convallis lectus mattis vitae. Mauris placerat erat ipsum, vitae interdum mauris consequat quis. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</p>
<p>
Nunc efficitur scelerisque elit. Integer ac massa ipsum. Cras volutpat nulla purus, quis molestie dolor iaculis eget. Maecenas ut ex nulla. Pellentesque sem augue, ornare ut arcu eu, porttitor consectetur orci. Aenean iaculis blandit quam, in efficitur justo sodales auctor. Vivamus dignissim pellentesque risus eget consequat. Pellentesque sit amet nisi in urna convallis egestas vitae nec mauris. 
</p>

使用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,但是 另一个更受欢迎的问题 由于这个而关闭,我无法在那里回答。

我需要一些适用于入站链接的东西,页面上的链接,并且可以由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+中找到问题

我对上面列出的答案没有任何运气,最终使用了此解决方案,该解决方案效果很好。

创建一个空白跨度,要设置锚点。

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

即使部分具有不同的彩色背景,该解决方案也可以工作!我在 这个链接。

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

此代码应该解决问题。将45px换成标头栏的高度。

编辑:如果是一个选项,则我也成功使用了jquery.localscroll带有偏移值集。偏移选项是jQuery.scrollto的一部分,jQuery.localscroll构建了。这里有演示: http://demos.flesler.com/jquery/scrollto/ (第二个窗口,在“偏移”下)

这是一个完整的jQuery解决方案,它将在IE中起作用:

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

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

    });
}

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

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

抵消锚而没有阻止指针事件

.section-marker {

    position: absolute;
    top: -300px;
}

这样的价值是,我们没有阻止任何可能落入这300px之内的元素。不利的一面是,从JavaScript中抓住该元素的位置需要考虑到该偏移,因此必须调整任何逻辑。

当您单击导航时,这就是我最终去适当的地方的方式。我为导航点击添加了一个事件处理程序。然后,您可以使用“ scrollby”来向上移动。

var offset = 90;

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

我创建了一个有几个线路的DIV,并给出了ID,然后将我想显示的代码放在下面。然后,链接将带您进入图像上方的空间,并且标头将不再妨碍您:

<a href="#image">Image</a>
<div id="image"><br><br></div>
<img src="Image.png">

当然,您可以更改线路断路的数量以满足您的需求。这对我来说非常有用,不确定是否有任何问题,我仍在学习HTML。

使用了此脚本

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

    $('html, body').animate({
        scrollTop: $($.attr(this, 'href')).offset().top -140
    }, 1000);
});
// handle hashes when page loads
// <http://stackoverflow.com/a/29853395>
function adjustAnchor() {
  const $anchor = $(':target');
  const fixedElementHeight = $('.navbar-fixed-top').outerHeight();
  if ($anchor.length > 0)
    window.scrollTo(0, $anchor.offset().top - fixedElementHeight);
}
$(window).on('hashchange load', adjustAnchor);
$('body').on('click', "a[href^='#']", function (ev) {
  if (window.location.hash === $(this).attr('href')) {
    ev.preventDefault();
    adjustAnchor();
  }
});

我之所以使用这种方法,是因为出于某种原因,提出的其他解决方案实际上对我有用。我保证我尝试了。

section {
   position: relative;
   border-top: 52px solid transparent; /* navbar height +2 */
   margin: -30px 0 0;
   -webkit-background-clip: padding-box;
   -moz-background-clip: padding;
   background-clip: padding-box;
}

section:before {
   content: "";
   position: absolute;
   top: -2px;
   left: 0;
   right: 0;
   border-top: 2px solid transparent;
}

代替 部分 如果您愿意,可以在课程中。

来源: 跳跃链接和视口定位

  • 在Firefox 45和Chrome 52上测试。
  • Bootstrap版本:3.3.7

对于那些不相信我的人,我友好地准备了一个解决方案的JSFIDDLE: 解决方案

CSS技巧将是解决方法。在所有情况下都可以使用JQuery实现的适当解决方案。

参考 https://codepen.io/pikeshmn/pen/mmxedz

方法: 我们使用固定导航的高度 document.getElementById('header')。并抵消滚动为此值。

var jump=function(e){  

e.preventDefault();                        //prevent "hard" jump
  var target = $(this).attr("href");       //get the target

      //perform animated scrolling
      $('html,body').animate(
        {
          scrollTop: $(target).offset().top - document.getElementById('header').offsetHeight - 5  //get top-position of target-element and set it as scroll target
        },1000,function()                  //scrolldelay: 1 seconds
        {
          location.hash = target;          //attach the hash (#jumptarget) to the pageurl
        });
      }

  $(document).ready(function()
  {
    $('a[href*="#"]').bind("click", jump); //get all hrefs
    return false;
  });

PS:

  • 它包括标题和目标之间的5个像素差
  • 滚动效果并不难,相当光滑;光滑的滚动
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top