anchor-link-with-fixed-header

2019-08-16

背景

复现

当页面中带有position:fixedheader时,通过id进行定位时,一般会有偏差。一般常见于文档页面,复现如下: 点击右侧的目录,快速定位至title2,结果被header遮住(为方便观察,header设置opacity:0.95)。 图片描述

期望实现

期望能实现准确定位。

demo代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Fixed header anchor offset</title>
</head>
<style>
* {margin: 0;padding: 0;}
html, body {
  width: 100%;
  height: 100%;
  overflow-x: hidden;
  overflow-y: auto;
}
#app {
  width: 100%;
  --header-height: 30px;
}
#app header {
  display: block;
  width: 100%;
  height: var(--header-height);
  position: fixed;
  top: 0;
  z-index: 99;
  background-color: #d1d1d1;
  text-align: center;
  font-size: 14px;
  font-weight: bolder;
  line-height: var(--header-height);
  opacity: 0.95;
}
#app #main {
  position: relative;
  top: var(--header-height);
}
#app #catalog {
  position: fixed;
  top: 60px;
  right: 30px;
  background: #f5f5ff;
  box-shadow: 0px 0px 6px #666;
  padding: 5px 10px;
}
#app #catalog > a {
  display: block;
  height: 25px;
  line-height: 25px;
  padding: 2px 4px;
  text-decoration: none;
}
#app #catalog > a:hover {
  background-color: aquamarine;
}
</style>
<body>
  <div id="app">
    <header>Header Here</header>
    <div id="main">
      <h3 id="title1">title1</h3>
      <div class="section-1" style="height: 300px;background-color:aliceblue;"></div>
      <h3 id="title2">title2</h3>
      <div class="section-2" style="height: 900px;background-color:cornflowerblue;"></div>
      <h3 id="title3">title3</h3>
      <div class="section-3" style="height: 600px;background-color:darkkhaki;"></div>
      <h3 id="title4">title4</h3>
      <div class="section-4" style="height: 800px;background-color:gold;"></div>
    </div>
    <div id="catalog">
      <a href="#title1">title1</a>
      <a href="#title2">title2</a>
      <a href="#title3">title3</a>
      <a href="#title4">title4</a>
    </div>
  </div>
</body>
</html>

解决问题

思路

给每个anchor设置偏移,纠正这个偏差。

代码

给每个锚点h3增加css属性:

#app #main h3::before {
  content: "";
  display: block;
  height: var(--header-height);
  margin-top: calc(var(--header-height) * -1);
  visibility: hidden;
}

解决后效果

纠正偏移后,能准确定位,且不影响页面布局。 图片描述

修复后的html代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Fixed header anchor offset</title>
</head>
<style>
* {margin: 0;padding: 0;}
html, body {
  width: 100%;
  height: 100%;
  overflow-x: hidden;
  overflow-y: auto;
}
#app {
  width: 100%;
  --header-height: 30px;
}
#app header {
  display: block;
  width: 100%;
  height: var(--header-height);
  position: fixed;
  top:0;
  z-index: 99;
  background-color: #d1d1d1;
  text-align: center;
  font-size: 14px;
  font-weight: bolder;
  line-height: var(--header-height);
}
#app #main {
  position: relative;
  top: var(--header-height);
}
#app #main h3::before {
  content: "";
  display: block;
  height: var(--header-height);
  margin-top: calc(var(--header-height) * -1);
  visibility: hidden;
}
#app #catalog {
  position: fixed;
  top: 60px;
  right: 30px;
  background: #f5f5ff;
  box-shadow: 0px 0px 6px #666;
  padding: 5px 10px;
}
#app #catalog > a {
  display: block;
  height: 25px;
  line-height: 25px;
  padding: 2px 4px;
  text-decoration: none;
}
#app #catalog > a:hover {
  background-color: aquamarine;
}
</style>
<body>
  <div id="app">
    <header>Header Here</header>
    <div id="main">
      <h3 id="title1">title1</h3>
      <div class="section-1" style="height: 300px;background-color:aliceblue;"></div>
      <h3 id="title2">title2</h3>
      <div class="section-2" style="height: 900px;background-color:cornflowerblue;"></div>
      <h3 id="title3">title3</h3>
      <div class="section-3" style="height: 600px;background-color:darkkhaki;"></div>
      <h3 id="title4">title4</h3>
      <div class="section-4" style="height: 800px;background-color:gold;"></div>
    </div>
    <div id="catalog">
      <a href="#title1">title1</a>
      <a href="#title2">title2</a>
      <a href="#title3">title3</a>
      <a href="#title4">title4</a>
    </div>
  </div>
</body>
</html>

原创说明

原文链接:segmentfault.com

上一篇:CSS Reset 样式重置
下一篇:真正理解nth-of-type,只知道nth-of-type和nth-child的区别?怕是不够哦!
相关教程
关注微信

扫码加入 JavaScript 社区

相关文章

首次访问,需要验证
微信扫码,关注即可
(仅需验证一次)

欢迎加入 JavaScript 社区

号内回复关键字:

回到顶部