HTML位置:固定页面页眉和页内锚点

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

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

 http://foo.com/#bar 
错误(但共同的行为):正确:
 + --------------------------------- + + -------------- ------------------- +
 |  BAR ///////////////////// header |  |  //////////////////////// header |
 + --------------------------------- + + -------------- ------------------- +
 | 这是Text |的其余部分  |  BAR |
 |  ... |  |  |
 |  ... |  | 这是Text |的其余部分
 |  ... |  |  ... |
 + --------------------------------- + + -------------- ------------------- +

我有同样的问题。 我通过向顶点高度作为填充顶部值的anchor元素添加一个类来解决此问题。

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

然后简单的CSS:

 .anchor { padding-top: 90px; } 

我使用这种方法:

 /* 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 +。

这里有更多的解决scheme: http : //nicolasgallagher.com/jump-links-and-viewport-positioning/

如果你不能或不想设置一个新的类,在CSS:

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

或jQuery:

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

官方Bootstrap采纳答案:

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

积分

合并

我发现处理这个问题的最佳方法是(用固定的元素高度replace65px):

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

如果你不喜欢使用目标select器,你也可以这样做:

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

在这种情况下,我的目标元素的绿色将覆盖他的父母红色元素在65px。 我没有find任何纯粹的CSS解决scheme来处理这个问题,但如果你没有其他的背景色,这个解决scheme是最好的。

虽然一些build议的解决scheme可以在同一页面使用片段链接(即哈希链接)(例如向下滚动的菜单链接),但是我发现当您想使用从其他链接进入的片段链接时,页面

因此,从头开始调用www.mydomain.com/page.html#foo 不会使用任何给定的CSS解决scheme或JS解决scheme在当前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延迟解决scheme可能会在Firefox,IE浏览器,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> 

将顶部填充值设置为标题的实际高度。 这会在头部的顶部引入一些额外的空白,但只有在用户跳转到锚点然后向上滚动时才会显示。 我已经为我的网站制定了解决scheme,但它只在页面顶部显示一个小的固定栏,没有太高。

我已经使用上面提到的“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/

这对我的纯粹主义感觉有些不好意思,但作为一个纯CSS的解决scheme,您可以使用:targetselect器将填充添加到活动的锚定元素:

 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> 

这个对我有用:

HTML链接到锚点:

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

HTML锚点:

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

CSS:

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

我发现我必须同时使用MutttenXdBadabam的CSS解决scheme,因为第一个在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与偏移值设置。 offset选项是jQuery.scrollTo的一部分,jQuery.localScroll是build立在这个基础上的。 演示可以在这里find: http : //demos.flesler.com/jquery/scrollTo/ (第二个窗口,在'偏移'下)

这是一个完整的jQuery解决scheme,将在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); }); 
 // 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(); } }); 

我使用这种方法是因为某些原因,其他的解决scheme都没有提供给我。 我保证我尝试过。

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

如果您愿意,可以用课程replace部分

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

  • testingFirefox 45和Chrome 52。
  • 引导版本:3.3.7

对于那些不相信我的人,我很乐意为你解决这个问题: 解决scheme

添加一个“paddingtop”的类,所以它的工作;)

 <h1><a class="paddingtop">Bar</a></h1> 

而对于CSS你有:

  .paddingtop{ padding-top: 90px; } 

CSS技巧将是一个解决方法。 一个适用于所有场景的解决scheme可以使用jQuery来实现。

请参阅https://codepen.io/pikeshmn/pen/mMxEdZ

方法:使用document.getElementById('header')。offsetHeight获得固定导航的高度,并将滚动偏移到这个值。

 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像素差异
  • 滚动效果不难,相当stream畅; 平滑滚动
 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <style> html > body { flex-direction: column; display: flex; padding: 0; margin: 0; } html > body > nav { background-color: black; white-space: pre; /* to use as much height as necessary */ flex-shrink: 1; color: white; } html > body > main { flex-flow: row nowrap; display: flex; } html > body > main > aside { flex-shrink: 1; } html > body > main > section { flex-grow: 1; } html > body > main > section > article:not(:first-child) { margin-top: 10px; } html > body > main > section > article { flex-flow: row nowrap; min-height: 150px; display: flex; } html > body > main > section > article > aside { background-color: beige; flex-shrink: 1; } html > body > main > section > article > div { background-color: lightgrey; flex-grow: 1; } </style> </head> <body> <nav> This content... ...may take as much space... ... as he want </nav> <main> <aside> this aside may... ...have a responsive width... </aside> <section> <article> <aside> ...aside... </aside> <div> Lorem Ipsum... </div> </article> <article> <aside> ...aside... </aside> <div> Lorem Ipsum... </div> </article> <article> <aside> ...aside... </aside> <div> Lorem Ipsum... </div> </article> <article> <aside> ...aside... </aside> <div> Lorem Ipsum... </div> </article> </section> </main> </body> </html>