首页 前端知识 CSS--解决目录的锚点定位被顶部导航栏盖住的问题

CSS--解决目录的锚点定位被顶部导航栏盖住的问题

2024-07-29 00:07:39 前端知识 前端哥 162 121 我要收藏

原文网址:CSS--解决目录的锚点定位被顶部导航栏盖住的问题_IT利刃出鞘的博客-CSDN博客

简介

本文介绍如何解决目录的锚点定位被顶部导航栏盖住的问题。

问题复现

可以看到,标题被最上边固定的导航栏给盖住了。

代码如下:

<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        body {
            padding: 0;
            margin: 0;
        }

        .navigation {
            background-color: rgba(0, 150, 241, 0.62);
            height: 60px;
            position: fixed;
            width: 100%;
        }

        .main_container {
            display: flex;
        }

        .main {
            padding: 60px 20px 0;
        }

        .catalogue {
            width: 300px;
            margin-top: 60px;
            flex-shrink: 0;
            background-color: #ddd;
            position: fixed;
            right: 0;
            height: 100%;
        }
    </style>
</head>

<body>
<div class="navigation">
</div>
<div class="main_container">
    <article class="main">
        <h1 class="article-title">这里是文章名称</h1>
        <div class="article-content">
            <p>
                aa<br>
                aa<br>
                aa<br>
                aa<br>
                aa<br>
            </p>
            <h3 class="heading" id="first">
                这是第1个标题
            </h3>
            <div>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
            </div>
            <h3 class="heading" id="second">
                这是第2个标题
            </h3>
            <div>
                cc<br>
                cc<br>
                cc<br>
                cc<br>
                cc<br>
                cc<br>
                cc<br>
                cc<br>
                cc<br>
            </div>
            <!--<div class="dark_anchor" id="third"></div>-->
            <h3 class="heading" id="third">这里是第3个标题</h3>
            <div>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
            </div>
            <h3 class="heading" id="forth">这里是第4个标题</h3>
            <div>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
            </div>
        </div>
    </article>

    <div class="catalogue">
        <ul>
            <li><a href="#first">标题1</a></li>
            <li><a href="#second">标题2</a></li>
            <li><a href="#third">标题3</a></li>
            <li><a href="#forth">标题4</a></li>
        </ul>
    </div>
</div>
</body>

</html>

原因分析

如果使用锚点("#")实现目录的跳转,就会遇到 fixed的导航栏遮住标题的问题。

锚点定位机制:

  1. 如果没有滚动条,锚点失效。
  2. 如果有滚动条,滚动条滚动到地址 hash (地址 # 号后面的内容)对应的锚点元素 padding-box上边缘位置。

解决方案

方案1:scroll-padding-top(推荐)

方案描述

将 scroll-padding-top 设置到滚动条所在的元素即可。示例的滚动条属于 html,所以在 html 元素上设置。(一般都是html元素)。

优点

只修改CSS即可,无需修改HTML。

方法

在CSS中添加如下内容:

html {
    scroll-padding-top: 60px;
}

测试

可以发现,已经精准对齐了。

方案2::target伪类

方案描述

:target:此CSS 伪类 代表一个唯一的页面元素(目标元素),其id 与当前URL片段匹配。

方法

在CSS中添加如下内容:

:target {
    padding-top: 60px;
    margin-top: -60px;
}

测试

跟上边一致。 

优点

只修改CSS即可,无需修改HTML。

方案3:padding+margin

方案描述

padding 影响锚点元素的定位,margin 不影响锚点元素的定位。所以使用 padding 调整锚点元素跳转后的位置,使用 margin 抵消 padding 对布局的影响。

方法

在CSS中添加如下内容:

.heading {
    padding-top: 60px;
    margin-top: -60px;
}

测试

跟上边结果一致。

优点

只修改CSS即可,无需修改HTML。

缺点

当标题的文档层级和段落的文档层级不一致时会导致遮盖其他元素。例如:标题使用了 relative 定位提升了文档层级,鼠标无法选中标题上方被布局遮挡的段落,从而导致无法复制文档。如下图所示:

代码

将标题元素加了如下CSS:

position: relative;

整个HTML如下:

<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        body {
            padding: 0;
            margin: 0;
        }

        .navigation {
            background-color: rgba(0, 150, 241, 0.62);
            height: 60px;
            position: fixed;
            width: 100%;
        }

        .main_container {
            display: flex;
        }

        .main {
            padding: 60px 20px 0;
        }

        .catalogue {
            width: 300px;
            margin-top: 60px;
            flex-shrink: 0;
            background-color: #ddd;
            position: fixed;
            right: 0;
            height: 100%;
        }

        .heading {
            padding-top: 60px;
            margin-top: -60px;
            position: relative;
        }
    </style>
</head>

<body>
<div class="navigation">
</div>
<div class="main_container">
    <article class="main">
        <h1 class="article-title">这里是文章名称</h1>
        <div class="article-content">
            <p>
                aa<br>
                aa<br>
                aa<br>
                aa<br>
                aa<br>
            </p>
            <h3 class="heading" id="first">
                这是第1个标题
            </h3>
            <div>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
            </div>
            <h3 class="heading" id="second">
                这是第2个标题
            </h3>
            <div>
                cc<br>
                cc<br>
                cc<br>
                cc<br>
                cc<br>
                cc<br>
                cc<br>
                cc<br>
                cc<br>
            </div>
            <!--<div class="dark_anchor" id="third"></div>-->
            <h3 class="heading" id="third">这里是第3个标题</h3>
            <div>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
            </div>
            <h3 class="heading" id="forth">这里是第4个标题</h3>
            <div>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
            </div>
        </div>
    </article>

    <div class="catalogue">
        <ul>
            <li><a href="#first">标题1</a></li>
            <li><a href="#second">标题2</a></li>
            <li><a href="#third">标题3</a></li>
            <li><a href="#forth">标题4</a></li>
        </ul>
    </div>
</div>
</body>

</html>

方案4:用span或a作为锚点元素

方案描述

非替换内联元素的padding不影响布局,但会影响锚点位置。

方法

修改标题写法

<h3 class="heading" id="second">
    这是第2个标题
</h3>

改为

<h3 class="heading">
    <span id="second" class="title_placeholder">
    这是第2个标题
    </span>
</h3>

在CSS中添加如下内容:

:target {
    padding-top: 60px;
    margin-top: -60px;
}

测试

跟上边一致。 

所有代码

<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        body {
            padding: 0;
            margin: 0;
        }

        .navigation {
            background-color: rgba(0, 150, 241, 0.62);
            height: 60px;
            position: fixed;
            width: 100%;
        }

        .main_container {
            display: flex;
        }

        .main {
            padding: 60px 20px 0;
        }

        .catalogue {
            width: 300px;
            margin-top: 60px;
            flex-shrink: 0;
            background-color: #ddd;
            position: fixed;
            right: 0;
            height: 100%;
        }

        .title_placeholder {
            padding-top: 60px;
        }
    </style>
</head>

<body>
<div class="navigation">
</div>
<div class="main_container">
    <article class="main">
        <h1 class="article-title">这里是文章名称</h1>
        <div class="article-content">
            <p>
                aa<br>
                aa<br>
                aa<br>
                aa<br>
                aa<br>
            </p>
            <h3 class="heading" id="first">
                这是第1个标题
            </h3>
            <div>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
                bb<br>
            </div>
            <h3 class="heading">
                <span id="second" class="title_placeholder">
                这是第2个标题
                </span>
            </h3>
            <div>
                cc<br>
                cc<br>
                cc<br>
                cc<br>
                cc<br>
                cc<br>
                cc<br>
                cc<br>
                cc<br>
            </div>
            <!--<div class="dark_anchor" id="third"></div>-->
            <h3 class="heading" id="third">这里是第3个标题</h3>
            <div>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
                dd<br>
            </div>
            <h3 class="heading" id="forth">这里是第4个标题</h3>
            <div>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
                ee<br>
            </div>
        </div>
    </article>

    <div class="catalogue">
        <ul>
            <li><a href="#first">标题1</a></li>
            <li><a href="#second">标题2</a></li>
            <li><a href="#third">标题3</a></li>
            <li><a href="#forth">标题4</a></li>
        </ul>
    </div>
</div>
</body>

</html>

缺点

  1. 需要修改HTML(每一个标题元素都要改)
  2. 当标题的文档层级和段落的文档层级不一致时会导致遮盖其他元素。例如:标题使用了 relative 定位提升了文档层级,鼠标无法选中标题上方被布局遮挡的段落,从而导致无法复制文档。

方案5:暗锚点

方案描述

在需要定位的元素上方加入不影响布局的空白锚点元素。

因为锚点跳转后的位置会落在元素的padding-box上边缘,设置 height 影响锚点位置,设置margin-top抵消暗锚对布局对影响。

方法

HTML写法

<div class="dark_anchor" id="third"></div>
<h3 class="heading">
    这是第3个标题
</h3>

CSS

.dark_anchor {
    height: 60px;
    margin-top: -60px;
}

测试

缺点

  1. 需要修改HTML。
  2. margin会影响锚点跳转后的位置,和直接设置标题为锚点元素的表现不一致。

注意事项

如果上述方案都无效,可能是其他原因导致的,比如:

  1. 目录跳转是通过js或者jquery实现的
    1. 此时可以找到相应的代码,修改偏移值
转载请注明出处或者链接地址:https://www.qianduange.cn//article/14461.html
标签
评论
发布的文章

Unity数据持久化之Json

2024-08-10 22:08:00

simdjson 高性能JSON解析C 库

2024-08-10 22:08:00

npm常用命令详解(一)

2024-08-10 22:08:34

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!