Html 固定页眉与页内锚点重叠
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4086107/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Fixed page header overlaps in-page anchors
提问by Tomalak
If I have a non-scrolling header in an HTML page, fixed to the top, having a defined height:
如果我在 HTML 页面中有一个非滚动标题,固定在顶部,具有定义的高度:
Is there a way to use the URL anchor (the #fragment
part) to have the browser scroll to a certain point in the page, but still respect the height of the fixed element without the help of JavaScript?
有没有办法使用 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 | | ... | | ... | +---------------------------------+ +---------------------------------+
采纳答案by MutttenXd
I had the same problem. I solved it by adding a class to the anchor element with the topbar height as the padding-top value.
我有同样的问题。我通过向锚元素添加一个类来解决它,顶栏高度作为 padding-top 值。
<h1><a class="anchor" name="barlink">Bar</a></h1>
And then simply the css:
然后简单的css:
.anchor { padding-top: 90px; }
回答by Adrian Garner
If you can't or don't want to set a new class, add a fixed-height ::before
pseudo-element to the :target
pseudo-class in CSS:
如果你不能或者不想设置一个新的类,在 CSS::before
的:target
伪类中添加一个固定高度的伪元素:
:target::before {
content: "";
display: block;
height: 60px; /* fixed header height*/
margin: -60px 0 0; /* negative fixed header height */
}
Or scroll the page relative to :target
with jQuery:
或者:target
使用 jQuery相对于滚动页面:
var offset = $(':target').offset();
var scrollto = offset.top - 60; // minus fixed header height
$('html, body').animate({scrollTop:scrollto}, 0);
回答by Jeremias Erbs
I use this approach:
我使用这种方法:
/* add class="jumptarget" to all targets. */
.jumptarget::before {
content:"";
display:block;
height:50px; /* fixed header height*/
margin:-50px 0 0; /* negative fixed header height */
}
It adds an invisible element before each target. It works IE8+.
它在每个目标之前添加一个不可见元素。它适用于 IE8+。
Here are more solutions: http://nicolasgallagher.com/jump-links-and-viewport-positioning/
这里有更多解决方案:http: //nicolasgallagher.com/jump-links-and-viewport-positioning/
回答by blnc
回答by Fran?ois Romain
html {
scroll-padding-top: 70px; /* height of sticky header */
}
from: https://css-tricks.com/fixed-headers-on-page-links-and-overlapping-content-oh-my/
来自:https: //css-tricks.com/fixed-headers-on-page-links-and-overlapping-content-oh-my/
回答by Roy Shoa
The best way that I found to handle this issue is (replace 65px with your fixed element height):
我发现处理这个问题的最好方法是(用你的固定元素高度替换 65px):
div:target {
padding-top: 65px;
margin-top: -65px;
}
If you do not like to use the targetselector you can also do it in this way:
如果你不喜欢使用目标选择器,你也可以这样做:
.my-target {
padding-top: 65px;
margin-top: -65px;
}
Note: this example will not work if the target element have a backgound color that differant from his parent. for example:
注意:如果目标元素的背景颜色与其父元素不同,则此示例将不起作用。例如:
<div style="background-color:red;height:100px;"></div>
<div class="my-target" style="background-color:green;height:100px;"></div>
in this case the green color of my-target element will overwrite his parent red element in 65px. I did not find any pure CSS solution to handle this issue but if you do not have another background color this solution is the best.
在这种情况下,my-target 元素的绿色将在 65px 中覆盖其父红色元素。我没有找到任何纯 CSS 解决方案来处理这个问题,但如果您没有其他背景颜色,这个解决方案是最好的。
回答by Jpsy
While some of the proposed solutions work for fragment links (= hash links) withinthe same page (like a menu link that scrolls down), I found that none of them worked in current Chrome when you want to use fragment links coming in from other pages.
虽然一些建议的解决方案适用于同一页面内的片段链接(= 哈希链接)(例如向下滚动的菜单链接),但我发现当您想使用来自其他页面的片段链接时,它们都不适用于当前的 Chrome页。
So calling www.mydomain.com/page.html#foo from scratch will NOToffset your target in current Chrome with any of the given CSS solutions or JS solutions.
因此,从头开始调用 www.mydomain.com/page.html#foo不会用任何给定的 CSS 解决方案或 JS 解决方案抵消当前 Chrome 中的目标。
There is also a jQuery bug reportdescribing some details of the problem.
还有一个jQuery 错误报告描述了问题的一些细节。
SOLUTION
解决方案
The only option I found so far that really works in Chrome is JavaScript that is not called onDomReady but with a delay.
到目前为止,我发现在 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);
}
}
SUMMARY
概括
Without a JS delay solutions will probably work in Firefox, IE, Safari, but not in Chrome.
没有 JS 延迟的解决方案可能适用于 Firefox、IE、Safari,但不适用于 Chrome。
回答by dakur
As CSS Scroll Snap speccomes into game, it is easily possible with scroll-margin-top
property. Currently runs on Chrome and Opera (April 2019). Also Safari 11+ should support this, but I was unable to run it on Safari 11. Probably we have to wait for guys to fix it overthere.
随着CSS Scroll Snap 规范进入游戏,它很容易通过scroll-margin-top
属性实现。目前在 Chrome 和 Opera 上运行(2019 年 4 月)。Safari 11+ 也应该支持这一点,但我无法在 Safari 11 上运行它。可能我们必须等待人们在那里修复它。
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>
回答by MrSwed
For Chrome/Safari/Firefox you could add a display: block
and use a negative margin to compensate the offset, like:
对于 Chrome/Safari/Firefox,您可以添加 adisplay: block
并使用负边距来补偿偏移量,例如:
a[name] {
display: block;
padding-top: 90px;
margin-top: -90px;
}
See example http://codepen.io/swed/pen/RrZBJo
回答by webvitaly
You can do this with jQuery:
你可以用 jQuery 做到这一点:
var offset = $('.target').offset();
var scrollto = offset.top - 50; // fixed_top_bar_height = 50px
$('html, body').animate({scrollTop:scrollto}, 0);