CSS 解决锚点定位被顶栏覆盖问题

date
Jun 27, 2022
slug
offset-anchor-targets
status
Published
tags
代码
summary
昨天把文章内目录(TOC)搓出来了,然而用的时候发现锚点跳转会被顶部导航栏盖住,简单查了一下,果然是可以用 CSS 解决的。
type
Post
昨天把文章内目录(TOC)搓出来了,然而用的时候发现锚点跳转会被顶部导航栏盖住,简单查了一下,果然是可以用 CSS 解决的。

现象

这里借用一个提问的老哥画的一个很生动形象的文字示意图:
WRONG (but the common behavior): CORRECT: +---------------------------------+ +---------------------------------+ | BAR///////////////////// header | | //////////////////////// header | +---------------------------------+ +---------------------------------+ | Here is the rest of the Text | | BAR | | ... | | | | ... | | Here is the rest of the Text | | ... | | ... | +---------------------------------+ +---------------------------------+

利用负 margin 偏移

一般很容易就能想到,直接给锚点标签加一个 padding 把它挤下来,这时候效果有了,但是你的排版也会被跟着挤开。 所以又可以再加一个负的 margin 把他拉回去。
h2{ padding-top: 顶栏高度; margin-top: -顶栏高度; }
notion image
示意图
margin 不会破坏文档流,用负 margin 减少自身高度,进而产生向上的偏移,且后面元素会继续紧贴着块。

伪元素

可能因为某些地方我们要用到 marginpadding,所以会冲突。这时候就可以用伪元素了。
h2:before{ content: ""; display: block; height: 顶栏高度; margin-top: -顶栏高度; }
notion image
示意图2
这里是创建了一个顶栏高度的伪元素挤开下方元素,然后使用负的 margin 让他向上偏移。

:target

顺便提一嘴,还发现了一个选择器 :target,可以选择当前聚焦的锚点。在这里应该用不上。
h2:target{ color: red; }
notion image
示意图3
或者可以这样写:h2:target:before

利用 scroll-margin/padding

算是比较新的东西,caniuse 表示 IE 全红。 用来设置浏览器自己滚动时有一个指定的偏移。
scroll-padding 是用在滚动容器上的,比如:
html{ scroll-padding-top: 顶栏高度; }
scroll-margin 是用在滚动目标上的:
h2{ scroll-margin-top: 顶栏高度; }

后记

感觉还是用负 margin 的方法会更好,毕竟新属性兼容性差。 更推荐用 JavaScript,毕竟哪一天要改顶栏高度就得重新写 CSS 了。 不知道理解有没有错误,一直查资料,这篇文章查了得有 5 小时。最后还是不能确定到底是不是对的。 感觉最近语言组织能力越来越差了,写一个句子会想很久怎么表达,用什么词更好。比如这句我就想了两分钟。感觉效率低了还给自己压力。

参考


© Cesirdy 2022

粤ICP备2022045639号又拍云