抵消一个html锚点来调整固定的头部
我正试图清理我的船锚的工作方式。 我有一个固定在页面顶部的标题,所以当你链接到页面中其他地方的页面时,页面跳转,所以锚点位于页面的顶部,留下固定标题后面的内容(我希望这就说得通了)。 我需要一种方法来从头部的高度偏移25px的锚点。 我更喜欢HTML或CSS,但Javascript也可以接受。
你可以使用没有任何JavaScript的CSS。
给你的主持人一个class:
<a class="anchor" id="top"></a>
然后,您可以通过将其定位到比实际出现在页面上的位置更高或更低的位置,使其成为块元素并相对定位。 -250px将定位锚点250px
a.anchor { display: block; position: relative; top: -250px; visibility: hidden; }
我发现这个解决scheme:
<a name="myanchor"> <h1 style="padding-top: 40px; margin-top: -40px;">My anchor</h1> </a>
这不会在内容上产生任何差距,而且链接链接真的很好。
我也在寻找解决scheme。 在我的情况下,这很容易。
我有一个包含所有链接的列表菜单:
<ul> <li><a href="#one">one</a></li> <li><a href="#two">two</a></li> <li><a href="#three">three</a></li> <li><a href="#four">four</a></li> </ul>
在下面的标题应该去的地方。
<h3>one</h3> <p>text here</p> <h3>two</h3> <p>text here</p> <h3>three</h3> <p>text here</p> <h3>four</h3> <p>text here</p>
现在,因为我在页面顶部有一个固定的菜单,所以我不能把它放到我的标签上,因为那是菜单的后面。
相反,我把一个span标签与我的标签正确的ID。
<h3><span id="one"></span>one</h3>
现在使用2行的CSS来正确定位它们。
h3{ position:relative; } h3 span{ position:absolute; top:-200px;}
更改顶部值以匹配您的固定标题(或更多)的高度。 现在我认为这也适用于其他元素。
由于这是介绍的关注,纯粹的CSS解决scheme将是理想的。 然而,这个问题是在2012年提出的,尽pipe已经提出了相对定位/负边界解决scheme,但这些方法看起来颇为冒头,造成潜在的stream动问题,并且无法dynamic响应DOM /视口中的更改。
考虑到这一点,我相信使用JavaScript 仍然是(2017年2月)最好的方法。 下面是一个vanilla-JS解决scheme,它将响应锚点击并解决加载时的页面哈希(参见JSFiddle) 。 如果需要dynamic计算,请修改.getFixedOffset()
方法。 如果您使用的是jQuery, 这里有一个更好的事件委托和平滑滚动的解决scheme 。
(function(document, history, location) { var HISTORY_SUPPORT = !!(history && history.pushState); var anchorScrolls = { ANCHOR_REGEX: /^#[^ ]+$/, OFFSET_HEIGHT_PX: 50, /** * Establish events, and fix initial scroll position if a hash is provided. */ init: function() { this.scrollToCurrent(); window.addEventListener('hashchange', this.scrollToCurrent.bind(this)); document.body.addEventListener('click', this.delegateAnchors.bind(this)); }, /** * Return the offset amount to deduct from the normal scroll position. * Modify as appropriate to allow for dynamic calculations */ getFixedOffset: function() { return this.OFFSET_HEIGHT_PX; }, /** * If the provided href is an anchor which resolves to an element on the * page, scroll to it. * @param {String} href * @return {Boolean} - Was the href an anchor. */ scrollIfAnchor: function(href, pushToHistory) { var match, rect, anchorOffset; if(!this.ANCHOR_REGEX.test(href)) { return false; } match = document.getElementById(href.slice(1)); if(match) { rect = match.getBoundingClientRect(); anchorOffset = window.pageYOffset + rect.top - this.getFixedOffset(); window.scrollTo(window.pageXOffset, anchorOffset); // Add the state to history as-per normal anchor links if(HISTORY_SUPPORT && pushToHistory) { history.pushState({}, document.title, location.pathname + href); } } return !!match; }, /** * Attempt to scroll to the current location's hash. */ scrollToCurrent: function() { this.scrollIfAnchor(window.location.hash); }, /** * If the click event's target was an anchor, fix the scroll position. */ delegateAnchors: function(e) { var elem = e.target; if( elem.nodeName === 'A' && this.scrollIfAnchor(elem.getAttribute('href'), true) ) { e.preventDefault(); } } }; window.addEventListener( 'DOMContentLoaded', anchorScrolls.init.bind(anchorScrolls) ); })(window.document, window.history, window.location);
纯粹的CSS解决scheme启发亚历山大萨维:
a[name] { padding-top: 40px; margin-top: -40px; display: inline-block; /* required for webkit browsers */ }
或者,如果目标仍在屏幕外,可能需要添加以下内容:
vertical-align: top;
FWIW这为我工作:
*[id]:before { display: block; content: " "; margin-top: -75px; height: 75px; visibility: hidden; }
我遇到过类似的问题,不幸的是,在执行上述所有解决scheme之后,我得出以下结论。
- 我的内部元素有一个脆弱的CSS结构,实现了相对/绝对的位置,完全打破了页面devise。
- CSS不是我的强项。
我写了这个简单的滚动js,这就是由于标题引起的偏移量,并且重新定位了大约125像素以下的div。 请按照您的要求使用它。
HTML
<div id="#anchor"></div> <!-- #anchor here is the anchor tag which is on your URL -->
JavaScript
$(function() { $('a[href*=#]:not([href=#])').click(function() { if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) { var target = $(this.hash); target = target.length ? target : $('[name=' + this.hash.slice(1) +']'); if (target.length) { $('html,body').animate({ scrollTop: target.offset().top - 125 //offsets for fixed header }, 1000); return false; } } }); //Executed on page load with URL containing an anchor tag. if($(location.href.split("#")[1])) { var target = $('#'+location.href.split("#")[1]); if (target.length) { $('html,body').animate({ scrollTop: target.offset().top - 125 //offset height of header here too. }, 1000); return false; } } });
在这里看到一个实时的执行
这需要从以前的答案很多元素,并结合成一个微小的(194字节缩小)匿名jQuery函数。 调整fixedElementHeight作为菜单或阻挡元素的高度。
(function($, window) { var adjustAnchor = function() { var $anchor = $(':target'), fixedElementHeight = 100; if ($anchor.length > 0) { $('html, body') .stop() .animate({ scrollTop: $anchor.offset().top - fixedElementHeight }, 200); } }; $(window).on('hashchange load', function() { adjustAnchor(); }); })(jQuery, window);
如果您不喜欢animation,请replace
$('html, body') .stop() .animate({ scrollTop: $anchor.offset().top - fixedElementHeight }, 200);
有:
window.scrollTo(0, $anchor.offset().top - fixedElementHeight);
Uglified版本:
!function(o,n){var t=function(){var n=o(":target"),t=100;n.length>0&&o("html, body").stop().animate({scrollTop:n.offset().top-t},200)};o(n).on("hashchange load",function(){t()})}(jQuery,window);
你可以做到这一点,没有js和没有改变HTML。 这是CSS只。
a[id]:before { content:""; display:block; height:50px; margin:-30px 0 0; }
这将在每个具有id的a-tag之前附加一个伪元素。 调整值以匹配标题的高度。
对于现代浏览器,只需将CSS3:targetselect器添加到页面即可。 这将自动适用于所有锚点。
:target { display: block; position: relative; top: -100px; visibility: hidden; }
我的解决scheme结合了我们CMS的目标和select器之前。 其他技术不考虑锚中的文本。 调整高度和负边距到您需要的偏移量…
:target:before { content: ""; display: inline-block; height: 180px; margin: -180px 0 0; }
改变位置属性的解决scheme并不总是可能的(它可以破坏布局),所以我build议这样做:
HTML:
<a id="top">Anchor</a>
CSS:
#top { margin-top: -250px; padding-top: 250px; }
用这个:
<a id="top"> </a>
最大限度地减less重叠,并设置字体大小为1px。 空锚在某些浏览器中不起作用。
正如@moeffju所言,这可以通过CSS来实现 。 我遇到的问题(我很惊讶,我没有看到讨论)是重叠以前的元素与填充或透明的边界防止hover和点击行动在这些部分的底部的技巧,因为下面的一个更高Z顺序。
我发现的最好的解决方法是将节内容放在z-index: 1
的div
中z-index: 1
:
// Apply to elements that serve as anchors .offset-anchor { border-top: 75px solid transparent; margin: -75px 0 0; -webkit-background-clip: padding-box; -moz-background-clip: padding; background-clip: padding-box; } // Because offset-anchor causes sections to overlap the bottom of previous ones, // we need to put content higher so links aren't blocked by the transparent border. .container { position: relative; z-index: 1; }
对于同样的问题,我使用了一个简单的解决scheme:在每个锚上放置一个40px的填充顶部。
借用在这个链接给出的答案(没有指定作者)的一些代码,你可以包括一个很好的平滑滚动效果的锚点,而停止在锚点上方-60px,很好地固定在bootstrap导航酒吧(需要jQuery):
$(".dropdown-menu a[href^='#']").on('click', function(e) { // prevent default anchor click behavior e.preventDefault(); // animate $('html, body').animate({ scrollTop: $(this.hash).offset().top - 60 }, 300, function(){ }); });
我遇到了同样的问题,并最终手动处理点击事件,如:
$('#mynav a').click(() -> $('html, body').animate({ scrollTop: $($(this).attr('href')).offset().top - 40 }, 200 return false )
滚动animation可选,当然。
如果你的锚是一个表元素或者在一个表(行或者单元格)中,上面的方法不能很好地工作。
我必须使用javascript并绑定到窗口hashchange
事件来解决这个( 演示 ):
function moveUnderNav() { var $el, h = window.location.hash; if (h) { $el = $(h); if ($el.length && $el.closest('table').length) { $('body').scrollTop( $el.closest('table, tr').position().top - 26 ); } } } $(window) .load(function () { moveUnderNav(); }) .on('hashchange', function () { moveUnderNav(); });
*注意: hashchange事件在所有浏览器中都不可用。
这受到了Shouvik的回答 – 与他的概念相同,只有固定头部的大小不是硬编码的。 只要你的固定头在第一个头节点,这应该“只是工作”
/*jslint browser: true, plusplus: true, regexp: true */ function anchorScroll(fragment) { "use strict"; var amount, ttarget; amount = $('header').height(); ttarget = $('#' + fragment); $('html,body').animate({ scrollTop: ttarget.offset().top - amount }, 250); return false; } function outsideToHash() { "use strict"; var fragment; if (window.location.hash) { fragment = window.location.hash.substring(1); anchorScroll(fragment); } } function insideToHash(nnode) { "use strict"; var fragment; fragment = $(nnode).attr('href').substring(1); anchorScroll(fragment); } $(document).ready(function () { "use strict"; $("a[href^='#']").bind('click', function () {insideToHash(this); }); outsideToHash(); });
我正在TYPO3网站面对这个问题,所有的“内容元素”都包裹着这样的东西:
<div id="c1234" class="contentElement">...</div>
我改变了渲染,所以它呈现这样的:
<div id="c1234" class="anchor"></div> <div class="contentElement">...</div>
而这个CSS:
.anchor{ position: relative; top: -50px; }
固定的topbar是40px高,现在锚再次工作,在topbar下面开始10px。
这种技术的缺点是你不能再使用:target
。
加上Ziav的回答(感谢Alexander Savin),我需要使用旧学校<a name="...">...</a>
因为我们正在使用<div id="...">...</div>
用于我们的代码中的另一个目的。 我有一些使用display: inline-block
显示问题display: inline-block
– 每个<p>
元素的第一行display: inline-block
为稍微右移(在Webkit和Firefox浏览器上)。 我结束了尝试其他display
值和display: table-caption
完美的作品。
.anchor { padding-top: 60px; margin-top: -60px; display: table-caption; }
我在每个h1
元素之前添加了40px高度的.vspace
元素。
<div class="vspace" id="gherkin"></div> <div class="page-header"> <h1>Gherkin</h1> </div>
在CSS中:
.vspace { height: 40px;}
它工作得很好,空间不窒息。
那么带有可提供导航栏高度的可链接ID的隐藏的span标签怎么样:
#head1 { padding-top: 60px; height: 0px; visibility: hidden; } <span class="head1">somecontent</span> <h5 id="headline1">This Headline is not obscured</h5>
inheritance人小提琴: http : //jsfiddle.net/N6f2f/7
你也可以添加一个跟随attr的锚:
(text-indent:-99999px;) visibility: hidden; position:absolute; top:-80px;
并给父容器一个相对的位置。
为我完美的作品。
您可以使用a[name]:not([href])
cssselect器来实现此function。 这只是寻找与名称和没有href的链接,例如<a name="anc1"></a>
一个示例规则可能是:
a[name]:not([href]){ display: block; position: relative; top: -100px; visibility: hidden; }
从@Jan的优秀答案进一步扭曲是将其纳入#uberbar固定标题,它使用jQuery(或MooTools)。 ( http://davidwalsh.name/persistent-header-opacity )
我已经调整了代码,所以内容的顶部总是低于固定标题下方,并再次从@Jan添加锚点,以确保锚点总是位于固定标题下方。
CSS:
#uberbar { border-bottom:1px solid #0000cc; position:fixed; top:0; left:0; z-index:2000; width:100%; } a.anchor { display: block; position: relative; visibility: hidden; }
jQuery(包括调整#uberbar和锚方法:
<script type="text/javascript"> $(document).ready(function() { (function() { //settings var fadeSpeed = 200, fadeTo = 0.85, topDistance = 30; var topbarME = function() { $('#uberbar').fadeTo(fadeSpeed,1); }, topbarML = function() { $('#uberbar').fadeTo(fadeSpeed,fadeTo); }; var inside = false; //do $(window).scroll(function() { position = $(window).scrollTop(); if(position > topDistance && !inside) { //add events topbarML(); $('#uberbar').bind('mouseenter',topbarME); $('#uberbar').bind('mouseleave',topbarML); inside = true; } else if (position < topDistance){ topbarME(); $('#uberbar').unbind('mouseenter',topbarME); $('#uberbar').unbind('mouseleave',topbarML); inside = false; } }); $('#content').css({'margin-top': $('#uberbar').outerHeight(true)}); $('a.anchor').css({'top': - $('#uberbar').outerHeight(true)}); })(); }); </script>
最后是HTML:
<div id="uberbar"> <!--CONTENT OF FIXED HEADER--> </div> .... <div id="content"> <!--MAIN CONTENT--> .... <a class="anchor" id="anchor1"></a> .... <a class="anchor" id="anchor2"></a> .... </div>
也许这对喜欢#uberbar褪色dixed标题的人是有用的!
而不是有一个固定位置的导航栏,由页面的其余内容(整个页面正在滚动),而不是有固定位置的导航栏,考虑改为有一个静态的导航栏不滚动的机构,然后页面内容在一个下面是绝对定位的可滚动div。
也就是说,有这样的HTML …
<div class="static-navbar">NAVBAR</div> <div class="scrollable-content"> <p>Bla bla bla</p> <p>Yadda yadda yadda</p> <p>Mary had a little lamb</p> <h2 id="stuff-i-want-to-link-to">Stuff</h2> <p>More nonsense</p> </div>
…和CSS这样的:
.static-navbar { height: 100px; } .scrollable-content { position: absolute; top: 100px; bottom: 0; overflow-y: scroll; width: 100%; }
这以直截了当的方式实现了预期的结果。 这个和上面提到的一些聪明的CSS hack之间唯一的区别在于,滚动条(在浏览器中渲染一个)将被附加到内容div而不是页面的整个高度。 你可能会也可能不会考虑这个理想。
这是一个JSFiddle,展示了这一点。
@ AlexanderSavin的解决scheme在我的WebKit
浏览器中效果很好。
我还必须使用:目标伪类,其中应用样式到选定的锚点来调整填充FF
, Opera
& IE9
:
a:target { padding-top: 40px }
请注意,这种风格不适用于Chrome
/ Safari
因此您可能必须使用css-hacks,条件注释等。
另外我想注意的是,亚历山大的解决scheme的工作原因是,目标元素是inline
。 如果你不想链接,你可以简单地改变display
属性:
<div id="myanchor" style="display: inline"> <h1 style="padding-top: 40px; margin-top: -40px;">My anchor</h1> </div>
这是我们在网站上使用的解决scheme。 调整headerHeight
variables为任何您的标题高度。 将js-scroll
类添加到应该单击滚动的锚点上。
// SCROLL ON CLICK // -------------------------------------------------------------------------- $('.js-scroll').click(function(){ var headerHeight = 60; $('html, body').animate({ scrollTop: $( $.attr(this, 'href') ).offset().top - headerHeight }, 500); return false; });